diff --git a/!readme.txt b/!readme.txt deleted file mode 100644 index 0e6276f7..00000000 --- a/!readme.txt +++ /dev/null @@ -1,8 +0,0 @@ -How to obtain list of supported algorithms by your card: -1. Upload AlgTest_v1.7.2_jc222.cap to target card (if your card doesn't support java Card 2.2.2, please use older version AlgTest_v1.7.1) -2. Run java -jar AlgTestJClient.jar -3. Select option 1 -> SUPPORTED ALGORITHMS -4. Fill identification (name) of your card -5. Wait for test to finish (2-10 min) -6. Inspect resulting CSV file -7. Consider sending the result to us at jcalgtest.org so you can contribute to community database and compare the results with others \ No newline at end of file diff --git a/AlgTest_JClient/src/algtestjclient/Utils.java b/AlgTest_JClient/src/algtestjclient/Utils.java index a9de0d3b..dfb61f78 100644 --- a/AlgTest_JClient/src/algtestjclient/Utils.java +++ b/AlgTest_JClient/src/algtestjclient/Utils.java @@ -144,9 +144,14 @@ public static String ErrorToString(int swStatus) { } case JCConsts.SW_CardRuntimeException_prefix: return "CardRuntimeException_" + Integer.toHexString(sw2); - + case (short) 0x6a00: + switch (sw2) { + case (short) 0x0081: + return "FUNC_NOT_SUPPORTED_" + Integer.toHexString(swStatus); + } default: return "UNKONWN_ERROR-card_has_return_value_" + Integer.toHexString(swStatus); } } } + diff --git a/AlgTest_JavaCard/jcbuild.xml b/AlgTest_JavaCard/jcbuild.xml index 3f4ba559..33f9b6c5 100644 --- a/AlgTest_JavaCard/jcbuild.xml +++ b/AlgTest_JavaCard/jcbuild.xml @@ -15,7 +15,7 @@ - + @@ -23,7 +23,7 @@ - + @@ -31,7 +31,7 @@ - + @@ -39,7 +39,7 @@ - + diff --git a/AlgTest_Process/process_results.py b/AlgTest_Process/process_results.py index f50601ab..b3250e26 100644 --- a/AlgTest_Process/process_results.py +++ b/AlgTest_Process/process_results.py @@ -9,6 +9,36 @@ "RSAPrivateKey", "RSAPublicKey", "RSAPrivateCRTKey", "KEY PAIR", "UTIL", "SWALGS", "KEYAGREEMENT"] +CARD_EXCEPTION_TO_STRING = { + 'f101': 'CryptoException_ILLEGAL_VALUE', + 'f102': 'CryptoException_UNINITIALIZED_KEY', + 'f103': 'CryptoException_NO_SUCH_ALGORITHM', + 'f104': 'CryptoException_INVALID_INIT', + 'f105': 'CryptoException_ILLEGAL_USE', + 'f201': 'SystemException_ILLEGAL_VALUE', + 'f202': 'SystemException_NO_TRANSIENT_SPACE', + 'f203': 'SystemException_ILLEGAL_TRANSIENT', + 'f204': 'SystemException_ILLEGAL_AID', + 'f205': 'SystemException_NO_RESOURCE', + 'f206': 'SystemException_ILLEGAL_USE', + 'f301': 'PINException_ILLEGAL_VALUE', + 'f302': 'PINException_ILLEGAL_STATE', + 'f401': 'TransactionException_IN_PROGRESS', + 'f402': 'TransactionException_NOT_IN_PROGRESS', + 'f403': 'TransactionException_BUFFER_FULL', + 'f404': 'TransactionException_INTERNAL_FAILURE', + 'f405': 'TransactionException_ILLEGAL_USE', + 'f500': 'CardRuntimeException', + 'ff01': 'Exception_GENERIC', + 'ff02': 'ArrayIndexOutOfBoundsException', + 'ff03': 'ArithmeticException', + 'ff04': 'ArrayStoreException', + 'ff05': 'NullPointerException', + 'ff06': 'NegativeArraySizeException', + 'ff': 'Exception_GENERIC', + '6a81': 'FUNC_NOT_SUPPORTED', + '6f00': 'Exception_GENERIC' +} def search_files(folder): for root, dirs, files in os.walk(folder): @@ -47,9 +77,9 @@ def extract_section(lines: list, start_string: str, perf_measurement: bool): if pos > 0: key = lines[i][0: pos].strip() if lines[i].find('method name:;') != -1: - # do not strip ending ; for line with method for variable data measurements + # do not strip ending ; for line with method for variable data measurements, strip only starting # method_name;data_length; - value = lines[i][pos:].strip() + value = lines[i][pos:].lstrip(';').strip() else: # strip ending ; value = lines[i][pos:].strip().strip(';').strip() @@ -57,7 +87,10 @@ def extract_section(lines: list, start_string: str, perf_measurement: bool): if perf_measurement and len(value) == 0: # error status like NO_SUCH_ALGORITHM section_items['status'] = key else: - section_items[key] = value + if lines[i].find('Exception') != -1: # various exceptions + section_items['status'] = key + else: + section_items[key] = value i = i + 1 just_entered = False @@ -148,8 +181,10 @@ def prepare_missing_measurements(walk_dir: str): msr = measurements['Measurements'] for category in msr: for ops in msr[category].keys(): + if 'status' not in msr[category][ops]: + print(msr[category][ops]) status = msr[category][ops]['status'] - if status == 'OK' or status == 'NO_SUCH_ALGORITHM': + if status == 'OK' or status == 'NO_SUCH_ALGORITHM' or status.find('FUNC_NOT_SUPPORTED') != -1: correctly_measured.append(ops + '\n') measured_with_errors.append(ops + '\n') else: @@ -231,7 +266,7 @@ def fix_missing_variable_data_lengths(walk_dir: str): line_corrected = line if line.find('method name:;') != -1: if line.rstrip().endswith('()'): # add data length only to the measurements where it is missing - # look ahead and extract length from measurement config + # Option 1: look ahead and extract length from measurement config config_line = lines[index + 1] if config_line.find('measurement config:') == -1: print('ERROR: missing measurement config on line ' + str(index + 1)) @@ -240,8 +275,56 @@ def fix_missing_variable_data_lengths(walk_dir: str): pos = config_line.find(';config;') + 44 # jump to payload with data length data_len_chars = config_line[pos: pos + 5].replace(' ', '') data_len = int(data_len_chars, 16) - line_corrected = '{};{};\n'.format(line.strip(), data_len) - change_found = True + data_len_verif = 0 + # do sanity check, data_len shall be 16, 32, 64, 128, 256 or 512 or not higher than 512 + if data_len not in [16, 32, 64, 128, 256, 512]: + #if data_len > 512: + print('WARNING: unexpected variable data length ' + str(data_len)) + else: + # verify against 'data length' item in 'operation info:' (if available) + info_line = lines[index + 6] + if info_line.find('operation info:') != -1: + # operation info:;data length;16;total iterations;250;total invocations;250; + # operation info:;data length;-1;total iterations;250;total invocations;250; + items = info_line.split(';') + data_len_verif = int(items[2]) + + if data_len_verif == 0 or data_len == data_len_verif: + line_corrected = '{};{};\n'.format(line.strip(), data_len) + change_found = True + else: + print('ERROR: mismatch in extracted data lengths ' + str(data_len) + ' vs. ' + str(data_len_verif)) + + lines_corrected.append(line_corrected) + index = index + 1 + + if change_found: + with open(filename, 'w') as f_write: + f_write.writelines(lines_corrected) + + +def fix_error_codes(walk_dir: str): + files = get_files_to_process(walk_dir, '.csv') + + for filename in files: + print(filename) + + change_found = False + with open(filename) as f: + lines = f.readlines() + lines_corrected = [] + index = 0 + while index < len(lines): + line = lines[index] + i = 0 + line_corrected = line + if line.find('UNKONWN_ERROR-card_has_return_value') != -1: + pos = line.find('UNKONWN_ERROR-card_has_return_value') + len('UNKONWN_ERROR-card_has_return_value') + 1 + error_code = line[pos:] + error_code = error_code.strip() + + line_corrected = CARD_EXCEPTION_TO_STRING.get(error_code, error_code) + ' (' + error_code + ')\n' + change_found = True lines_corrected.append(line_corrected) index = index + 1 @@ -294,10 +377,12 @@ def create_sorted_already_measured_list(directory: str): @click.argument("directory", required=True, type=str) @click.option("--output-dir", "output_dir", type=str, help="Base path for output.") def main(directory: str, output_dir: str): - #all_to_measure_ops = create_sorted_already_measured_list(directory) + all_to_measure_ops = create_sorted_already_measured_list(directory) + + fix_error_codes(directory) # error codes not translated into human readable string _ - #fix_missing_underscores(directory, all_to_measure_ops) # some file had incorrect naming for measured values without _ - #fix_missing_variable_data_lengths(directory) + fix_missing_underscores(directory, all_to_measure_ops) # some file had incorrect naming for measured values without _ + fix_missing_variable_data_lengths(directory) convert_to_json(directory) # from csv to json diff --git a/AlgTest_Process/run.bat b/AlgTest_Process/run.bat index 90d9df0f..bb2c9469 100644 --- a/AlgTest_Process/run.bat +++ b/AlgTest_Process/run.bat @@ -1,10 +1,10 @@ java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles HTML -java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles_20211030\performance\fixed\ SIMILARITY ..\..\algtest_results\web1\ -java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles_20211030\performance\fixed\ JCINFO ..\..\algtest_results\web1\ -java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles_20211030\performance\fixed\ SORTABLE ..\..\algtest_results\web1\ -java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles_20211030\performance\fixed\ RADAR ..\..\algtest_results\web1\ -java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles_20211030\performance\variable\ SCALABILITY ..\..\algtest_results\web1\ +java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\fixed\ SIMILARITY ..\..\algtest_results\javacard\web\ +java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\fixed\ JCINFO ..\..\algtest_results\javacard\web\ +java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\fixed\ SORTABLE ..\..\algtest_results\javacard\web\ +java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\fixed\ RADAR ..\..\algtest_results\javacard\web\ +java -jar ..\AlgTest_Process\dist\AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\variable\ SCALABILITY ..\..\algtest_results\javacard\web\ diff --git a/AlgTest_Process/similarity.txt b/AlgTest_Process/similarity.txt index 3d6c7c34..9948af9b 100644 --- a/AlgTest_Process/similarity.txt +++ b/AlgTest_Process/similarity.txt @@ -1,32 +1,37 @@ -ALG_SECURE_RANDOM RandomData_generateData();SECURE RANDOM (256B);SYM -ALG_SHA MessageDigest_doFinal();SHA-1 hash (256B);SYM -ALG_SHA_256 MessageDigest_doFinal();SHA2-256 hash (256B);SYM -TYPE_AES LENGTH_AES_128 ALG_AES_BLOCK_128_CBC_NOPAD Cipher_doFinal();AES128 encrypt (256B);SYM -TYPE_AES LENGTH_AES_256 ALG_AES_BLOCK_128_CBC_NOPAD Cipher_doFinal();AES256 encrypt (256B);SYM -TYPE_DES LENGTH_DES3_3KEY ALG_DES_CBC_NOPAD Cipher_doFinal();3DES encrypt (256B);SYM -TYPE_DES LENGTH_DES_192 setKey();3DES setKey(192b);SYM -TYPE_AES LENGTH_AES_128 setKey();AES setKey(128b);SYM -TYPE_AES LENGTH_AES_256 setKey();AES setKey(256b);SYM -SWALGS SWAlgs_AES();SWAES oneblock (16B);SYM -UTIL Util_arrayCopyNonAtomic_RAM(); arrayCopy nonAtomic RAM2RAM (256B) -UTIL Util_arrayCopyNonAtomic_EEPROM(); arrayCopy nonAtomic EEPROM2EEPROM (256B) +TYPE_RSA_PRIVATE LENGTH_RSA_1024 ALG_RSA_NOPAD Cipher_doFinal() +TYPE_RSA_PRIVATE LENGTH_RSA_2048 ALG_RSA_NOPAD Cipher_doFinal() +TYPE_RSA_PUBLIC LENGTH_RSA_1024 ALG_RSA_NOPAD Cipher_doFinal() +TYPE_RSA_PUBLIC LENGTH_RSA_2048 ALG_RSA_NOPAD Cipher_doFinal() -ALG_EC_FP LENGTH_EC_FP_256 KeyPair_genKeyPair();ECC 256b genKeyPair;ASYM -KeyPair_ALG_EC_FP KeyBuilder_LENGTH_EC_FP_256 Signature_ALG_ECDSA_SHA Signature_sign();ECDSA 256b sign;ASYM -KeyPair_ALG_EC_FP KeyBuilder_LENGTH_EC_FP_256 Signature_ALG_ECDSA_SHA Signature_verify();ECDSA 256b verify;ASYM -ALG_EC_FP LENGTH_EC_FP_256 ALG_EC_SVDP_DH KeyAgreement_generateSecret();ECDH 256b;ASYM -TYPE_RSA_CRT_PRIVATE LENGTH_RSA_1024 ALG_RSA_NOPAD Cipher_doFinal();RSA1024 CRT decrypt;ASYM -TYPE_RSA_CRT_PUBLIC LENGTH_RSA_1024 ALG_RSA_NOPAD Cipher_doFinal();RSA1024 CRT encrypt;ASYM -TYPE_RSA_CRT_PRIVATE LENGTH_RSA_2048 ALG_RSA_NOPAD Cipher_doFinal();RSA2048 CRT decrypt;ASYM -TYPE_RSA_CRT_PUBLIC LENGTH_RSA_2048 ALG_RSA_NOPAD Cipher_doFinal();RSA2048 CRT encrypt;ASYM -TYPE_RSA_PRIVATE LENGTH_RSA_1024 ALG_RSA_NOPAD Cipher_doFinal();RSA1024 decrypt;ASYM -TYPE_RSA_PUBLIC LENGTH_RSA_1024 ALG_RSA_NOPAD Cipher_doFinal();RSA1024 encrypt;ASYM -TYPE_RSA_PRIVATE LENGTH_RSA_2048 ALG_RSA_NOPAD Cipher_doFinal();RSA2048 decrypt;ASYM -TYPE_RSA_PUBLIC LENGTH_RSA_2048 ALG_RSA_NOPAD Cipher_doFinal();RSA2048 encrypt;ASYM - - - +TYPE_RSA_CRT_PRIVATE LENGTH_RSA_1024 ALG_RSA_NOPAD Cipher_doFinal() +TYPE_RSA_CRT_PRIVATE LENGTH_RSA_2048 ALG_RSA_NOPAD Cipher_doFinal() +TYPE_RSA_CRT_PUBLIC LENGTH_RSA_1024 ALG_RSA_NOPAD Cipher_doFinal() +TYPE_RSA_CRT_PUBLIC LENGTH_RSA_2048 ALG_RSA_NOPAD Cipher_doFinal() +KeyPair_ALG_EC_FP KeyBuilder_LENGTH_EC_FP_192 Signature_ALG_ECDSA_SHA Signature_sign() +KeyPair_ALG_EC_FP KeyBuilder_LENGTH_EC_FP_192 Signature_ALG_ECDSA_SHA Signature_verify() +ALG_EC_FP LENGTH_EC_FP_192 ALG_EC_SVDP_DH KeyAgreement_init() +ALG_EC_FP LENGTH_EC_FP_192 ALG_EC_SVDP_DH KeyAgreement_generateSecret() +KeyPair_ALG_EC_FP KeyBuilder_LENGTH_EC_FP_256 Signature_ALG_ECDSA_SHA Signature_sign() +KeyPair_ALG_EC_FP KeyBuilder_LENGTH_EC_FP_256 Signature_ALG_ECDSA_SHA Signature_verify() +ALG_EC_FP LENGTH_EC_FP_256 ALG_EC_SVDP_DH KeyAgreement_init() +ALG_EC_FP LENGTH_EC_FP_256 ALG_EC_SVDP_DH KeyAgreement_generateSecret() +KeyPair_ALG_EC_FP KeyBuilder_LENGTH_EC_FP_384 Signature_ALG_ECDSA_SHA Signature_sign() +KeyPair_ALG_EC_FP KeyBuilder_LENGTH_EC_FP_384 Signature_ALG_ECDSA_SHA Signature_verify() +ALG_EC_FP LENGTH_EC_FP_384 ALG_EC_SVDP_DH KeyAgreement_init() +ALG_EC_FP LENGTH_EC_FP_384 ALG_EC_SVDP_DH KeyAgreement_generateSecret() +TYPE_DES LENGTH_DES ALG_DES_ECB_NOPAD Cipher_doFinal() +TYPE_DES LENGTH_DES3_2KEY ALG_DES_ECB_NOPAD Cipher_doFinal() +ALG_SECURE_RANDOM RandomData_generateData() +TYPE_AES LENGTH_AES_128 ALG_AES_BLOCK_128_ECB_NOPAD Cipher_doFinal() +TYPE_AES LENGTH_AES_128 ALG_AES_BLOCK_256_ECB_NOPAD Cipher_doFinal() +TYPE_AES LENGTH_AES_128 setKey() +TYPE_AES LENGTH_AES_256 setKey() +ALG_SHA MessageDigest_doFinal() +ALG_SHA_256 MessageDigest_doFinal() +ALG_SHA_512 MessageDigest_doFinal() +SWALGS SWAlgs_AES() +SWALGS SWAlgs_xor() diff --git a/AlgTest_Process/source/style.css b/AlgTest_Process/source/style.css index e68d0556..f3034010 100644 --- a/AlgTest_Process/source/style.css +++ b/AlgTest_Process/source/style.css @@ -1,399 +1,439 @@ -body, html { height: 100%; } -html, body, div, span, applet, object, iframe, -/*h1, h2, h3, h4, h5, h6,*/ p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, font, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; - background: transparent; -} - -th{ -cursor: pointer; -} - - -body { line-height: 1; } - -blockquote, q { quotes: none; } -blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } -:focus { outline: 0; } -del { text-decoration: line-through; } -table {border-spacing: 0; } /* IMPORTANT, I REMOVED border-collapse: collapse; FROM THIS LINE IN ORDER TO MAKE THE OUTER BORDER RADIUS WORK */ - -/*------------------------------------------------------------------ */ - -/*This is not important*/ -body{ - font-family:Arial, Helvetica, sans-serif; -} -.table-tooltip { - cursor: pointer; -} - -.tooltip > .tooltip-inner { - font-size: 1.0em; - min-width:150%; -} -a:link { - color: #444; - font-weight: bold; - text-decoration:none; - font-size:14px; -} -a:visited { - color: #444; - font-weight:bold;font-weight:bold; - text-decoration:none; -} -a:active, -a:hover { - color: #bd5a35; - text-decoration:underline; -} - -/* -Div style ------------------------------------------------------------------- */ -div{ - font-family:Arial, Helvetica, sans-serif; - color:#003366; - font-size:20px; - max-width:2000px; -} - -.main{ - display : block; - overflow : auto; - min-height: 100px; - text-shadow: 1px 1px 0px #fff; -} - -.pageColumnQuickLinks{ - background-color : #ebebeb; - float : left; - clear : none; - min-height : 300px; - text-shadow: 1px 1px 0px #fff; - margin:20px; - margin-right:0px; - border:#ccc 1px solid; - padding-right:20px; - -moz-border-radius:3px; - -webkit-border-radius:3px; - border-radius:3px; - max-width:50%; - - -moz-box-shadow: 0 1px 2px #d1d1d1; - -webkit-box-shadow: 0 1px 2px #d1d1d1; - box-shadow: 0 1px 2px #d1d1d1; -} - -.pageColumnDetails{ - background-color : #ebebeb; - float : left; - clear : none; - min-height : 300px; - text-shadow: 1px 1px 0px #fff; - margin:20px; - margin-right:0px; - border:#ccc 1px solid; - padding-right:20px; - - -moz-border-radius:3px; - -webkit-border-radius:3px; - border-radius:3px; - - -moz-box-shadow: 0 1px 2px #d1d1d1; - -webkit-box-shadow: 0 1px 2px #d1d1d1; - box-shadow: 0 1px 2px #d1d1d1; -} - -.pageColumnCPLC{ - background-color : #ebebeb; - float : left; - clear : none; - min-height : 300px; - padding-right:20px; - padding-bottom:20px; - text-shadow: 1px 1px 0px #fff; - margin:20px; - margin-right:0px; - border:#ccc 1px solid; - - -moz-border-radius:3px; - -webkit-border-radius:3px; - border-radius:3px; - - -moz-box-shadow: 0 1px 2px #d1d1d1; - -webkit-box-shadow: 0 1px 2px #d1d1d1; - box-shadow: 0 1px 2px #d1d1d1; -} - -.description{ - border:solid #ebebeb; - border-width:.1em .1em .1em .1em; - padding: .1em .1em; - margin: 0px 50px 0px 40px; - font-size: 12px; - font-family: Monospace; - margin: 0; - line-height: 120%; - max-height: 90px; - overflow: auto; -} - -.graph{ - min-height:480px; - height:auto; - min-width:600px; - width:49%; - float:left; -} - -.end{ - margin:20px 0px 10px; - text-align:center; - float:left; - width:99%; -} - - -/* -Headers Style ------------------------------------------------------------------- */ -h1{ - font-family: Arial, Helvetica, sans-serif; - color: #003366; - font-size: 32px; - margin: 20px; - font-weight: 600; - line-height: 1.1; -} -h2{ - font-family:Arial, Helvetica, sans-serif; - color:#003366; - font-size:24px; - margin:20px; - font-weight: 600; - line-height: 1.1; -} - - -h3{ - font-family:Arial, Helvetica, sans-serif; - color:#003366; - font-size:18px; - margin:20px; - font-weight: 600; - line-height: 1.1; -} - -h4{ - font-family:Arial, Helvetica, sans-serif; - color:#003366; - font-size:16px; - margin:10px; - margin-left: 20px - font-weight: 600; - line-height: 1.1; -} - -h5{ - font-family:Arial, Helvetica, sans-serif; - color:#003366; - font-size:12px; - font-weight: 600; - line-height: 1.1; -} - -p{ - font-family:Arial, Helvetica, sans-serif; - color:#303030; - font-size:14px; - margin-left: 20px; - margin-bottom: 9px; -} - -pre{ - font-family:Monospace; - font-size:12px; - margin-left: 10px; -} - - - -/* -Table Style - This is what you want ------------------------------------------------------------------- */ -table a:link { - color: #444; - font-weight: bold; - text-decoration:none; -} -table a:visited { - color: #444; - font-weight:bold; - text-decoration:none; -} -table a:active, -table a:hover { - color: #bd5a35; - text-decoration:underline; -} -table { - font-family:Arial, Helvetica, sans-serif; - color:#444; - font-size:12px; - text-shadow: 1px 1px 0px #fff; - background:#eaebec; - margin:20px; - border:#ccc 1px solid; - - -moz-border-radius:3px; - -webkit-border-radius:3px; - border-radius:3px; - - -moz-box-shadow: 0 1px 2px #d1d1d1; - -webkit-box-shadow: 0 1px 2px #d1d1d1; - box-shadow: 0 1px 2px #d1d1d1; -} -table th { - padding:15px 15px 15px 15px; - border-top:1px solid #fafafa; - border-bottom:1px solid #e0e0e0; - - background: #ededed; - background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb)); - background: -moz-linear-gradient(top, #ededed, #ebebeb); -} - -table th.minor { - padding:5px 8px 5px 8px; - border-top:1px solid #fafafa; - border-bottom:1px solid #e0e0e0; - font-size: 10px; - background: #ededed; - background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb)); - background: -moz-linear-gradient(top, #ededed, #ebebeb); -} - -table.compare th { - padding:5px 10px 5px 10px; - border-top:1px solid #fafafa; - border-bottom:1px solid #e0e0e0; - - background: #ededed; - background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb)); - background: -moz-linear-gradient(top, #ededed, #ebebeb); -} - -table th:first-child{ - text-align: left; - padding-left:20px; -} -table tr:first-child th:first-child{ - -moz-border-radius-topleft:3px; - -webkit-border-top-left-radius:3px; - border-top-left-radius:3px; -} -table tr:first-child th:last-child{ - -moz-border-radius-topright:3px; - -webkit-border-top-right-radius:3px; - border-top-right-radius:3px; -} -table tr{ - text-align: center; - padding-left:20px; -} -table tr td:first-child{ - text-align: left; - padding-left:20px; - border-left: 0; -} -table tr td { - padding:5px; - border-top: 1px solid #ffffff; - border-bottom:1px solid #e0e0e0; - border-left: 1px solid #e0e0e0; - - background: #fafafa; - background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafafa)); - background: -moz-linear-gradient(top, #fbfbfb, #fafafa); -} - -table tr td.minor { - padding:5px; - border-top: 1px solid #ffffff; - border-bottom:1px solid #e0e0e0; - border-left: 1px solid #e0e0e0; - - background: transparent; - font-size: 10px; -} - -table tr.even td{ - background: #f6f6f6; - background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6f6)); - background: -moz-linear-gradient(top, #f8f8f8, #f6f6f6); -} - -table tr.even td.minor { - padding:5px; - border-top: 1px solid #ffffff; - border-bottom:1px solid #e0e0e0; - border-left: 1px solid #e0e0e0; - - background: transparent; - font-size: 10px; -} - -table tr.even:hover td{ - background: #f2f2f2; - background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0)); - background: -moz-linear-gradient(top, #f2f2f2, #f0f0f0); -} - -table tr:last-child td{ - border-bottom:0; -} -table tr:last-child td:first-child{ - -moz-border-radius-bottomleft:3px; - -webkit-border-bottom-left-radius:3px; - border-bottom-left-radius:3px; -} -table tr:last-child td:last-child{ - -moz-border-radius-bottomright:3px; - -webkit-border-bottom-right-radius:3px; - border-bottom-right-radius:3px; -} -table tr:hover td{ - background: #f2f2f2; - background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0)); - background: -moz-linear-gradient(top, #f2f2f2, #f0f0f0); -} - -.back-to-top { - position: fixed; - bottom: 20px; - right: 20px; - display: none; - width: 60px; - height: 60px; - background-image: url('up.png'); - opacity: 0.7; -} - -.back-to-top:hover { - background-image: url('up-hover.png'); - opacity: 0.9; -} - +body, html { height: 100%; } +html, body, div, span, applet, object, iframe, +/*h1, h2, h3, h4, h5, h6,*/ p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + background: transparent; +} + +th{ +cursor: pointer; +} + + +body { line-height: 1; } + +blockquote, q { quotes: none; } +blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } +:focus { outline: 0; } +del { text-decoration: line-through; } +table {border-spacing: 0; } /* IMPORTANT, I REMOVED border-collapse: collapse; FROM THIS LINE IN ORDER TO MAKE THE OUTER BORDER RADIUS WORK */ + +/*------------------------------------------------------------------ */ + +/*This is not important*/ +body{ + font-family:Arial, Helvetica, sans-serif; +} +.table-tooltip { + cursor: pointer; +} + +.tooltip > .tooltip-inner { + font-size: 1.0em; + min-width:150%; +} +a:link { + color: #444; + font-weight: bold; + text-decoration:none; + font-size:14px; +} +a:visited { + color: #444; + font-weight:bold;font-weight:bold; + text-decoration:none; +} +a:active, +a:hover { + color: #bd5a35; + text-decoration:underline; +} + +/* +Div style +------------------------------------------------------------------ */ +div{ + font-family:Arial, Helvetica, sans-serif; + color:#003366; + font-size:20px; + max-width:2000px; +} + +.main{ + display : block; + overflow : auto; + min-height: 100px; + text-shadow: 1px 1px 0px #fff; +} + +.pageColumnQuickLinks{ + background-color : #ebebeb; + float : left; + clear : none; + min-height : 300px; + text-shadow: 1px 1px 0px #fff; + margin:20px; + margin-right:0px; + border:#ccc 1px solid; + padding-right:20px; + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + max-width:50%; + + -moz-box-shadow: 0 1px 2px #d1d1d1; + -webkit-box-shadow: 0 1px 2px #d1d1d1; + box-shadow: 0 1px 2px #d1d1d1; +} + +.pageColumnDetails{ + background-color : #ebebeb; + float : left; + clear : none; + min-height : 300px; + text-shadow: 1px 1px 0px #fff; + margin:20px; + margin-right:0px; + border:#ccc 1px solid; + padding-right:20px; + + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + + -moz-box-shadow: 0 1px 2px #d1d1d1; + -webkit-box-shadow: 0 1px 2px #d1d1d1; + box-shadow: 0 1px 2px #d1d1d1; +} + +.pageColumnCPLC{ + background-color : #ebebeb; + float : left; + clear : none; + min-height : 300px; + padding-right:20px; + padding-bottom:20px; + text-shadow: 1px 1px 0px #fff; + margin:20px; + margin-right:0px; + border:#ccc 1px solid; + + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + + -moz-box-shadow: 0 1px 2px #d1d1d1; + -webkit-box-shadow: 0 1px 2px #d1d1d1; + box-shadow: 0 1px 2px #d1d1d1; +} + +.description{ + border:solid #ebebeb; + border-width:.1em .1em .1em .1em; + padding: .1em .1em; + margin: 0px 50px 0px 40px; + font-size: 12px; + font-family: Monospace; + margin: 0; + line-height: 120%; + max-height: 90px; + overflow: auto; +} + +.graph{ + min-height:480px; + height:auto; + min-width:600px; + width:49%; + float:left; +} + +.end{ + margin:20px 0px 10px; + text-align:center; + float:left; + width:99%; +} + + +/* +Headers Style +------------------------------------------------------------------ */ +h1{ + font-family: Arial, Helvetica, sans-serif; + color: #003366; + font-size: 32px; + margin: 20px; + font-weight: 600; + line-height: 1.1; +} +h2{ + font-family:Arial, Helvetica, sans-serif; + color:#003366; + font-size:24px; + margin:20px; + font-weight: 600; + line-height: 1.1; +} + + +h3{ + font-family:Arial, Helvetica, sans-serif; + color:#003366; + font-size:18px; + margin:20px; + font-weight: 600; + line-height: 1.1; +} + +h4{ + font-family:Arial, Helvetica, sans-serif; + color:#003366; + font-size:16px; + margin:10px; + margin-left: 20px + font-weight: 600; + line-height: 1.1; +} + +h5{ + font-family:Arial, Helvetica, sans-serif; + color:#003366; + font-size:12px; + font-weight: 600; + line-height: 1.1; +} + +p{ + font-family:Arial, Helvetica, sans-serif; + color:#303030; + font-size:14px; + margin-left: 20px; + margin-bottom: 9px; +} + +pre{ + font-family:Monospace; + font-size:12px; + margin-left: 10px; +} + + + +/* +Table Style - This is what you want +------------------------------------------------------------------ */ +table a:link { + color: #444; + font-weight: bold; + text-decoration:none; +} +table a:visited { + color: #444; + font-weight:bold; + text-decoration:none; +} +table a:active, +table a:hover { + color: #bd5a35; + text-decoration:underline; +} +table { + font-family:Arial, Helvetica, sans-serif; + color:#444; + font-size:12px; + text-shadow: 1px 1px 0px #fff; + background:#eaebec; + margin:20px; + border:#ccc 1px solid; + + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + + -moz-box-shadow: 0 1px 2px #d1d1d1; + -webkit-box-shadow: 0 1px 2px #d1d1d1; + box-shadow: 0 1px 2px #d1d1d1; +} + +table.compare { + font-size: 13px; + text-shadow: unset; + background: #f5f5f5; + margin: 0px; + border: #ccc 1px solid; + + border-radius:3px; + box-shadow: unset; +} + +table th { + padding:15px 15px 15px 15px; + border-top:1px solid #fafafa; + border-bottom:1px solid #e0e0e0; + + background: #ededed; + background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb)); + background: -moz-linear-gradient(top, #ededed, #ebebeb); +} + +table th.minor { + padding:5px 8px 5px 8px; + border-top:1px solid #fafafa; + border-bottom:1px solid #e0e0e0; + font-size: 10px; + background: #ededed; + background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb)); + background: -moz-linear-gradient(top, #ededed, #ebebeb); +} + +table.compare th.minor { + padding: 5px 8px 5px 8px; + border-top: 1px solid #ffffff; + border-bottom:3px double #e0e0e0; + border-left: 1px solid #e0e0e0; + font-size: 11px; +} + +table.compare th { + padding:5px 8px 5px 8px; + border: 2px solid white; + font-size: 80%; +} +table.compare .top { + border-collapse: separate; + border-top: 0.5em solid white; +} +table.compare .left { + border-left: 0.5em solid white; +} + +table.compare .inactive { + background-color: #f5f5f5 !important; +} + +table.compare td { + padding: 0 !important; + margin: 0 !important; + font-size: 80%; + color: white; +} + +table.compare td a { + text-decoration: none; + color: inherit !important; +} + + +table th:first-child{ + text-align: left; + padding-left:20px; +} +table tr:first-child th:first-child{ + -moz-border-radius-topleft:3px; + -webkit-border-top-left-radius:3px; + border-top-left-radius:3px; +} +table tr:first-child th:last-child{ + -moz-border-radius-topright:3px; + -webkit-border-top-right-radius:3px; + border-top-right-radius:3px; +} +table tr{ + text-align: center; + padding-left:20px; +} +table tr td:first-child{ + text-align: left; + padding-left:20px; + border-left: 0; +} +table tr td { + padding:5px; + border-top: 1px solid #ffffff; + border-bottom:1px solid #e0e0e0; + border-left: 1px solid #e0e0e0; + + background: #fafafa; + background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafafa)); + background: -moz-linear-gradient(top, #fbfbfb, #fafafa); +} + +table tr td.minor { + padding:5px; + border-top: 1px solid #ffffff; + border-bottom:1px solid #e0e0e0; + border-left: 1px solid #e0e0e0; + + background: transparent; + font-size: 10px; +} + +table tr.even td{ + background: #f6f6f6; + background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6f6)); + background: -moz-linear-gradient(top, #f8f8f8, #f6f6f6); +} + +table tr.even td.minor { + padding:5px; + border-top: 1px solid #ffffff; + border-bottom:1px solid #e0e0e0; + border-left: 1px solid #e0e0e0; + + background: transparent; + font-size: 10px; +} + +table tr.even:hover td{ + background: #f2f2f2; + background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0)); + background: -moz-linear-gradient(top, #f2f2f2, #f0f0f0); +} + +table tr:last-child td{ + border-bottom:0; +} +table tr:last-child td:first-child{ + -moz-border-radius-bottomleft:3px; + -webkit-border-bottom-left-radius:3px; + border-bottom-left-radius:3px; +} +table tr:last-child td:last-child{ + -moz-border-radius-bottomright:3px; + -webkit-border-bottom-right-radius:3px; + border-bottom-right-radius:3px; +} +table tr:hover td{ + background: #f2f2f2; + background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0)); + background: -moz-linear-gradient(top, #f2f2f2, #f0f0f0); +} + +.back-to-top { + position: fixed; + bottom: 20px; + right: 20px; + display: none; + width: 60px; + height: 60px; + background-image: url('up.png'); + opacity: 0.7; +} + +.back-to-top:hover { + background-image: url('up-hover.png'); + opacity: 0.9; +} + diff --git a/AlgTest_Process/src/algtestprocess/JCinfohtml.java b/AlgTest_Process/src/algtestprocess/JCinfohtml.java index 9d468359..f267b406 100644 --- a/AlgTest_Process/src/algtestprocess/JCinfohtml.java +++ b/AlgTest_Process/src/algtestprocess/JCinfohtml.java @@ -37,6 +37,7 @@ may be distributed under the terms of the GNU General Public License (GPL), import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Collections; @@ -275,6 +276,33 @@ public static void loadTopFunctions(List topNames_sym, List topA reader.close(); } } + + public static List> loadAlgorithmNames() { + ArrayList> result = new ArrayList(); + ArrayList current = new ArrayList(); + + String[] lineArray; + String line; + + try (BufferedReader reader = new BufferedReader(new FileReader(SIMILARITY_FILE))) { + while ((line = reader.readLine()) != null) { + if (!line.trim().isEmpty()) { + lineArray = line.split(";"); + current.add(lineArray[0]); + } else { + result.add(current); + current = new ArrayList(); + } + } + if(!current.isEmpty()) { + result.add(current); + } + } catch (IOException e) { + System.err.printf("Error: Reading from file %s failed.\n", SIMILARITY_FILE); + } + + return result; + } public static List listFilesForFolder(final File folder) { List files = new ArrayList<>(); @@ -293,203 +321,110 @@ public static List listFilesForFolder(final File folder) { public static void compareTable(String inputDir, String outputDir, FileOutputStream file) throws IOException { compareTable(inputDir, outputDir, file, false, null); } - + public static void compareTable(String inputDir, String outputDir, FileOutputStream file, boolean unknownMode, String unknownCard) throws IOException { + List> algNames = loadAlgorithmNames(); + + List files = new ArrayList<>(listFilesForFolder(new File(inputDir))); + files = sortBySimilarity(files, algNames); + List cardNames = new ArrayList<>(); + List>> similarities = new ArrayList<>(); + for(int i = 0; i < algNames.size(); ++i) { + similarities.add(computeCardSimilarities(files, cardNames.isEmpty() ? cardNames : null, algNames.get(i))); + } + + generateCompareTable(file, similarities, cardNames); + generateRadarCharts(inputDir, outputDir); + } + + public static void generateRadarCharts(String inputDir, String outputDir) throws IOException { + List files = new ArrayList<>(listFilesForFolder(new File(inputDir))); // prepare input data - topFunctions, perf results List topNames_sym = new ArrayList<>(); List topAcronyms_sym = new ArrayList<>(); List topNames_asym = new ArrayList<>(); List topAcronyms_asym = new ArrayList<>(); - loadTopFunctions(topNames_sym, topAcronyms_sym, topNames_asym, topAcronyms_asym, true); - List files = listFilesForFolder(new File(inputDir)); - Collections.sort(files); - if (unknownMode) { - files.add(0, unknownCard); - } - List namesOfCards = new ArrayList<>(); - List> rowsData = new ArrayList<>(); + loadTopFunctions(topNames_sym, topAcronyms_sym, topNames_asym, topAcronyms_asym, false); List> radarData = new ArrayList<>(); List> radarDataCopy = new ArrayList<>(); topNames_sym.addAll(topNames_asym); topAcronyms_sym.addAll(topAcronyms_asym); - - List unknownResults = new ArrayList<>(); - - //prepare rows (data added later) - //one row(ArrayList) represent one algorithm, one column (get(i) in each row) represent one card + for(String acr : topAcronyms_sym) { - rowsData.add(new ArrayList()); radarData.add(new ArrayList()); radarDataCopy.add(new ArrayList()); } - - //beginning of graph table - StringBuilder toFile = new StringBuilder(); - toFile.append("\t\n" + - "\t\t\n\t\t\t\n"); - //load data from input files (fixed-size perf data) and store name of card + List cardNames = new ArrayList<>(); for(String fileName : files) { - namesOfCards.add(addCard(topNames_sym, rowsData, fileName)); - addCard(topNames_sym, radarData, fileName); + cardNames.add(addCard(topNames_sym, radarData, fileName)); addCard(topNames_sym, radarDataCopy, fileName); } - - //head of table with cards names - for(String name : namesOfCards) - toFile.append("\t\t\t\n"); - //end of head of table - toFile.append("\t\t\n"); - - //normalize data - for(int i=0; imax) - max=value; + // Normalize data + for(int i=0; i max) + max = value; } - for(int j=0; j sortBySimilarity(List files, List> algNames) throws IOException { + List>> similarities = new ArrayList<>(); + for(int i = 0; i < algNames.size(); ++i) { + similarities.add(computeCardSimilarities(files, null, algNames.get(i))); } - for(int i=0; i\n"); - toFile.append("\t\t\t\n"); + class Pair implements Comparable { + public String name; + public double value; - for(int j=0; j notSupp = new ArrayList<>(); - List notSuppByRow = new ArrayList<>(); - List notSuppByCol = new ArrayList<>(); - float sum = 0.0F; - int num = 0; - if(i==j) { - toFile.append("\t\t\t\n"); - continue; - } - - double cosineSum = 0.0; - double cosineSumI = 0.0; - double cosineSumJ = 0.0; - for(int k=0; k"+String.format("%.0f", sum).replace(",", ".")+"\n"); - toFile.append("\t\t\t\n"); - - if (j > i) { - if (unknownMode) - generateCompareFile(outputDir, card1, card2, notSupp, notSuppByRow, notSuppByCol, "unknown-compare", topAcronyms_sym, radarData, radarDataCopy, i, j); - else - generateCompareFile(outputDir, card1, card2, notSupp, notSuppByRow, notSuppByCol, "compare", topAcronyms_sym, radarData, radarDataCopy, i, j); - } + @Override + public int compareTo(Pair other) { + return Double.compare(this.value, other.value); } - - toFile.append("\t\t\n"); } - toFile.append("\t\t
"+"Higher percentage = more similar"+""+name+"
") - .append((unknownMode && i == 0) ? "" : "") - .append(namesOfCards.get(i)) - .append((unknownMode && i == 0) ? "" : "") - .append("" + card1 + "
" + card2 + "
Difference in num. of supported algs: "+notSupp.size()+"/"+topNames_sym.size()+"
"); - - //tooltip info about unsupported algorithms - /*for(String ns:notSupp) - toFile.append(ns+"
");*/ - - float alpha = 0.0F; - String color; - if (sum > 0.5F) { - alpha = (sum*sum*sum*sum*sum*sum); - color = "140,200,120"; - } - else { - alpha = (Math.abs(sum-1)*Math.abs(sum-1)*Math.abs(sum-1)*Math.abs(sum-1)); - color = "200,120,140"; - } - - if (j < i) { - String temp = card1; - card1 = card2; - card2 = temp; - } + public Pair(String name, double value) { + this.name = name; + this.value = value; + } - toFile - .append("\" style=\"background:rgba(" + color + ","+String.format("%.2f", alpha).replace(",", ".")).append(");\">") - .append((unknownMode && (i == 0 || j == 0)) ? "" : "") - .append(String.format("%.2f", sum*100).replace(",", ".")).append((unknownMode && (i == 0 || j == 0)) ? "" : "").append("
\n"); - toFile.append("\n"); - - if (unknownMode) { - addSimilarityUnknownInfo(toFile, namesOfCards.subList(1, namesOfCards.size()), unknownResults); + List pairs = new ArrayList<>(); + for(int i = 0; i < files.size(); ++i) { + double total = 0.0d; + for(int j = 0; j < files.size(); ++j) { + for(int k = 0; k < similarities.size(); ++k) { + total += similarities.get(k).get(i).get(j); + } + } + pairs.add(new Pair(files.get(i), total)); } - file.write(toFile.toString().getBytes()); + Collections.sort(pairs, Collections.reverseOrder()); + List sorted = new ArrayList<>(); + for(Pair p : pairs) { + sorted.add(p.name); + } + + return sorted; } public static void addSimilarityUnknownInfo(StringBuilder toFile, List cardNames, List similarities) { @@ -549,8 +484,7 @@ public static void addUnknownTable(StringBuilder toFile, List cardNames, } public static void generateCompareFile(String outputDir, String card1, String card2, - List notSupp, List notSuppBy1, - List notSuppBy2, String subdirectory, + String subdirectory, List topAcronyms_sym, List> radarData, List> radarDataCopy, int i, int j) throws IOException { @@ -569,44 +503,6 @@ public static void generateCompareFile(String outputDir, String card1, String ca addCompareFileInfo(file, card1, card2); generateCompareGraph(file, filename, fileNameActual, card1, card2, topAcronyms_sym, radarData, radarDataCopy, i, j); - - StringBuilder toFile = new StringBuilder(); - - toFile.append("\t
\n"); - toFile.append("\t\t
\n"); - toFile.append("
"); - toFile.append("

Dissimilarities in algorithm support

\n"); - - if (notSupp.isEmpty()) { - toFile.append("

There are no differences in tested algorithm support between compared cards.

"); - } - else { - toFile.append("\n"); - toFile.append("\t\n"); - toFile.append("\t\t\n"); - toFile.append("\t\t\n"); - toFile.append("\t\t\n"); - toFile.append("\t\n"); - for (String alg : notSupp) { - toFile.append("\t\n"); - toFile.append("\t\t\n"); - if (notSuppBy1.contains(alg)) { - toFile.append("\t\t\n"); - } else { - toFile.append("\t\t\n"); - } - if (notSuppBy2.contains(alg)) { - toFile.append("\t\t\n"); - } else { - toFile.append("\t\t\n"); - } - toFile.append("\t\n"); - } - toFile.append("
Support").append(card1).append("").append(card2).append("
").append(alg).append("").append("No").append("").append("Yes").append("").append("No").append("").append("Yes").append("
\n"); - } - toFile.append("\t\t
\t
\n"); - - file.write(toFile.toString().getBytes()); endHTML(file, "../"); } @@ -750,6 +646,149 @@ public static void compareGraph(String inputDir, FileOutputStream file) throws I file.write(toFile.toString().getBytes()); } + public static List> computeCardSimilarities(List files, List cardNames, List algIdentifiers) throws IOException { + if (cardNames == null) { + cardNames = new ArrayList<>(); + } + + List> rowsData = new ArrayList<>(); + + for (String x : algIdentifiers) { + rowsData.add(new ArrayList<>()); + } + + for (String fileName : files) { + cardNames.add(addCard(algIdentifiers, rowsData, fileName)); + } + + //normalize data + for (int i = 0; i < rowsData.size(); i++) { + Float max = 0.0F; + for (Float value : rowsData.get(i)) { + if (value > max) { + max = value; + } + } + + for (int j = 0; j < rowsData.get(i).size(); j++) { + if (rowsData.get(i).get(j) != 0.0F) { + rowsData.get(i).set(j, rowsData.get(i).get(j) / max); + } + } + } + + List> similarity = new ArrayList<>(); + for (int i = 0; i < cardNames.size(); i++) { + int support = 0; + for (int k = 0; k < algIdentifiers.size(); ++k) { + if (rowsData.get(k).get(i) != 0.0f) { + support += 1; + } + } + + List similarity_row = new ArrayList<>(); + for (int j = 0; j < cardNames.size(); j++) { + double sum = 0.0F; + int num = 0; + + for (int k = 0; k < algIdentifiers.size(); k++) { + if (rowsData.get(k).get(i) == 0.0f && rowsData.get(k).get(j) == 0.0f) { + ; + } else if (rowsData.get(k).get(i) != 0.0f && rowsData.get(k).get(j) != 0.0f) { + sum += (rowsData.get(k).get(i) - rowsData.get(k).get(j)) * (rowsData.get(k).get(i) - rowsData.get(k).get(j)); + ++num; + } + } + if (num == 0) { + sum = 0; + } else { + sum = Math.abs(Math.sqrt(sum / num) - 1); //convert to percentage, close to 100% = very similar, close to 0% = not similar + } + sum = sum * sum; + similarity_row.add(sum); + } + similarity.add(similarity_row); + } + return similarity; + } + + public static void generateCompareTable( + FileOutputStream file, + List>> similarities, + List cardNames + ) throws IOException { + StringBuilder toFile = new StringBuilder(); + toFile.append("\t\n" + + "\t\t\n\t\t\t\n"); + for(String name : cardNames) + toFile.append("\t\t\t\n"); + toFile.append("\t\t\n"); + toFile.append("\t\t"); + + for(int i = 0; i < cardNames.size(); ++i) { + toFile.append("\t\t\n"); + toFile.append("\t\t\t\n"); + for(int j = 0; j < cardNames.size(); ++j) { + for(int k = 0; k < similarities.size() / 2; ++k) { + toFile.append(prepareCompareTableCell(i, j, k, cardNames, similarities.get(k))); + } + } + toFile.append("\t\t\n"); + + toFile.append("\t\t\n"); + for(int j = 0; j < cardNames.size(); ++j) { + for(int k = similarities.size() / 2; k < similarities.size(); ++k) { + toFile.append(prepareCompareTableCell(i, j, k, cardNames, similarities.get(k))); + } + } + toFile.append("\t\t\n"); + } + + toFile.append("\t\t
RSARSA CRTECC" + name + "
EncHashSW
").append(cardNames.get(i)).append("
\n"); + toFile.append("\n"); + file.write(toFile.toString().getBytes()); + } + + public static String prepareCompareTableCell(int row, int col, int cell, List cardNames, List> similarities) { + String rowCard = cardNames.get(row); + String colCard = cardNames.get(col); + Double rawValue = similarities.get(row).get(col); + + String classes = "table-tooltip"; + if (cell < 3) + classes += " top"; + if (cell % 3 == 0) + classes += " left"; + classes = classes.trim(); + + + String style = "width: 3em; height: 3em; "; + + if(row == col) { + return String.format("\t\t\t\n", classes, style); + } + + String value = ((int) Math.round(rawValue * 100)) == 0 ? "" : String.format("%d", (int) Math.round(rawValue * 100)); + + if(!value.isEmpty()){ + float v = Float.parseFloat(value) / 100.0f; + style += "background: rgba(" + (v > 0.5 ? "140,200,120," : "200,120,140,") + String.format("%.2f", v > 0.5 ? v : 1 - v).replace(",", ".") + ");"; + } else { + style += "background: #f5f5f5;"; + } + + String tooltip = String.format("%s
%s
", rowCard, colCard); + + return String.format("\t\t\t" + + "%s" + + "\n", classes, style, tooltip, rowCard, colCard, value); + } + public static void compareGraphForFunction(String algName, String dir, FileOutputStream file) throws IOException { List files = listFilesForFolder(new File(dir)); List rows = new ArrayList<>(); diff --git a/KNOWN_ISSUES.md b/KNOWN_ISSUES.md index f0ccb659..172356f5 100644 --- a/KNOWN_ISSUES.md +++ b/KNOWN_ISSUES.md @@ -1,5 +1,5 @@ # Known issues with testing -The collection of well known issues which may hard your card, limit its functionality or outright brick it +The collection of well known issues which may harm your card, limit its functionality or outright brick it IMPORTANT: Have you experienced any issues with cards you have? Please let us know (open issue or directly PR for this file) @@ -11,5 +11,8 @@ IMPORTANT: Have you experienced any issues with cards you have? Please let us kn * the eeprom memory is not properly freed after upload of certain (FIXME) cap file, potentially rendering card almost useless (very low amount of available EEPROM) * NXP JCOP3 J3H145G * setting and using incorrect private exponent for RSA may brick the whole card (FIXME example from JCMathLib) + * Feitian A20, A40 and similar cards + * failing repeated performance tests in KeyBuilder part with SystemException.NO_TRANSIENT_SPACE + * The issue is likely garbage collector not freeing unused objects properly even after JCSystem.requestObjectDeletion() is called diff --git a/README.md b/README.md index 7abf51f9..46f0c373 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ An automated testing tool for cryptographic algorithms supported by a particular *Contribution with results for YOUR card is wanted! (and highly appreciated :))* -The processed data are available at http://jcalgtest.org +The processed data are available at [https://www.fi.muni.cz/~xsvenda/jcalgtest/](https://www.fi.muni.cz/~xsvenda/jcalgtest/) ## Usage @@ -16,10 +16,10 @@ Upload proper cap file (based on the supported JavaCard version) file to your smart card using uploader like [GlobalPlatformPro](https://github.com/martinpaljak/GlobalPlatformPro). ``` -java -jar gp.jar --install AlgTest_v1.7.10_jc305.cap +java -jar gp.jar --install AlgTest_v1.8.0_jc305.cap ``` -If unsure about the supported version for your card, simply try to upload from the highest version down to the lower one (e.g., start with AlgTest_v1.7.10_jc305.cap, then AlgTest_v1.7.10_jc304.cap, then AlgTest_v1.7.10_jc222.cap). Stop when the card upload succeed. +If unsure about the supported version for your card, simply try to upload from the highest version down to the lower one (e.g., start with AlgTest_v1.8.0_jc305.cap, then AlgTest_v1.8.0_jc304.cap, then AlgTest_v1.8.0_jc222.cap). Stop when the card upload succeed. Check that the applet was correctly uploaded and installed: ``` @@ -44,6 +44,7 @@ PKG: 4A43416C6754657374 (LOADED) ### 2. Run data collection application (AlgTestJClient) +Run as interactive application and select from the offered options: ``` java -jar AlgTestJClient.jar ``` @@ -59,117 +60,189 @@ Choose the target reader for the card with the uploaded AlgTest applet, select t Please consider to send us (petr@svenda.com) your results in case your card (*.csv and *.log file). The open database benefit both from the cards not yet in an open public database at https://www.fi.muni.cz/~xsvenda/jcalgtest/, but also from the new measurements for the already included ones (set of supported algorithms can expand in later revisions of the same card). +### 4. Automatization of data collection + +The AlgTestJClient can be run in non-interactive mode for usage in scripts, see available options using `--help` option +``` +java -jar AlgTestJClient.jar --help +``` + +#### Non-interactive measurement - supported algorithms +Run non-interactively (scripts) the algorithms support (-op ALG_SUPPORT_EXTENDED), with specified card name (-cardname your_card_name) and complete measurement (-fresh): +``` +java -jar AlgTestJClient.jar -op ALG_SUPPORT_EXTENDED -cardname your_card_name -fresh +``` + +#### Non-interactive measurement - performance benchmark on fixed data length (typically 256 bytes) +Run non-interactively (scripts) the performance benchmark with 256 bytes of data (-op ALG_PERFORMANCE_STATIC), with specified card name (-cardname your_card_name) and complete measurement (-fresh): +``` +java -jar AlgTestJClient.jar -op ALG_PERFORMANCE_STATIC -cardname your_card_name -fresh +``` +Note: if '-fresh' option is omitted, you will be asked to continue previous measurement for same card, if found + +#### Non-interactive measurement - performance benchmark on variable data length (16, 32, 64, 128, 256 and 512 bytes) +Run non-interactively (script usage) the performance benchmark with variable data (-op ALG_PERFORMANCE_VARIABLE), with specified card name (-cardname your_card_name) and complete measurement (-fresh): +``` +java -jar AlgTestJClient.jar -op ALG_PERFORMANCE_VARIABLE -cardname your_card_name -fresh +``` + + +## Results data presentation and visualization + +### jcalgtest.org web page + +We do periodically update the web page with visualization and sortable tables at http://jcalgtest.org. The raw source files with measurements are available in separate repository https://github.com/crocs-muni/jcalgtest_results/. +Visit the page to see all results you also (possibly) contributed to! + +### Generate web page yourself + +The webpage content can be generated with AlgTestProcess sub-project. If you want to generate webpage yourself, then: + +1. Clone [jcalgtest_results](https://github.com/crocs-muni/jcalgtest_results/) repository +``` +git clone https://github.com/crocs-muni/jcalgtest_results.git +``` + +2. Run AlgTestProcess.jar application to generate algorithms support table +``` +java -jar AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles HTML +``` + +3. Run AlgTestProcess.jar application to generate various performance measurements +``` +java -jar AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\fixed\ SIMILARITY ..\..\algtest_results\javacard\web\ +java -jar AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\fixed\ JCINFO ..\..\algtest_results\javacard\web\ +java -jar AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\fixed\ SORTABLE ..\..\algtest_results\javacard\web\ +java -jar AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\fixed\ RADAR ..\..\algtest_results\javacard\web\ +java -jar AlgTestProcess.jar ..\..\algtest_results\javacard\Profiles\performance\variable\ SCALABILITY ..\..\algtest_results\javacard\web\ +``` + +4. Inspect results in \algtest_results\javacard\web\ folder + +## Future development + +Important: We are now working on refactoring results data presentation and visualization from Java-based [AlgTestProcess](https://github.com/crocs-muni/JCAlgTest/tree/master/AlgTest_Process) application to Python-based scripts and Jupyter notebooks and AlgTestProcess project will be depricated. + +The data collection application [AlgTestJClient](https://github.com/crocs-muni/JCAlgTest/tree/master/AlgTest_JClient) and on-card javacard applet [AlgTestJavaCard](https://github.com/crocs-muni/JCAlgTest/tree/master/AlgTest_JavaCard) will continue to be maintained as Java applications. + +## Contributed cards Results for (at least) the following smartcards are currently in the database -(https://www.fi.muni.cz/~xsvenda/jcalgtest/): - -``` - c0 ACS ACOSJ (Combi) , ATR=3b 69 00 02 41 43 4f 53 4a 76 31 30 31 (provided by Alexandre Bouvier), - c1 ACS ACOSJ 40K , ATR=3b 69 00 02 41 43 4f 53 4a 76 31 30 31 (provided by PetrS), - c2 Athena IDprotect , ATR=3B D5 18 FF 80 91 FE 1F C3 80 73 C8 21 13 08 (provided by Cosmo), - c3 Athena IDProtect ICFabDate 2015 , ATR=3b d5 18 ff 81 91 fe 1f c3 80 73 c8 21 13 09 (provided by PetrS), - c4 Axalto Cyberflex32 , ATR=3B 75 94 00 00 62 02 02 02 01 (provided by PetrS), - c5 Axalto Cyberflex PalmeraV5 , ATR=3B E6 00 00 81 21 45 32 4B 01 01 01 01 7A (provided by PetrS), - c6 Credentsys Lite , ATR=3b df 95 ff 80 91 fe 1f c3 80 25 a0 00 00 00 68 53 19 00 01 73 c8 21 13 29 (provided by Kate Gray), - c7 Feitian-FTJCOS ICFabDate 2018 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 00 87 06 00 00 00 00 ea (provided by Toporin), - c8 Feitian A40 ICFabDate 2018 , ATR=3b 9f 95 81 31 fe 9f 00 66 46 53 05 10 00 ff 71 df 00 00 00 00 00 ec (provided by Radboud University), - c9 Feitian A40CR ICFabDate 2018 , ATR=3b 9c 95 80 81 1f 03 90 67 46 4a 01 00 41 06 f2 72 7e 00 57, - c10 Feitian C21C Samsung S3FS91J , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 00 05 24 c0 72 7e 00 86 (provided by Thotheolh Tay), - c11 Feitian eJava Token , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 64 2f 70 c1 72 fe e0 fd (provided by Razvan Dragomirescu), - c12 Feitian Fingerprint card , ATR=3b 61 00 00 80, - c13 Feitian Java Card D11CR , ATR=3b 6a 00 00 09 44 31 31 43 52 02 00 25 c3 (provided by PetrS), - c14 Feitian JavaCOS A22 ICFabDate 2015 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 00 68 08 04 00 00 00 00 0e (provided by Ivo Kubjas and PetrS), - c15 Feitian JavaCOS A22CR-ECC-SHA-2 ICFabDate 2015 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 00 10 04 f2 72 fe 00 01 (provided by Kenneth Benson), - c16 Feitian JavaCOS A22CR ICFabDate 2016 084 , ATR=3b 8c 80 01 90 67 46 4a 01 00 25 04 00 00 00 00 d6 (provided by Josh Harvey), - c17 Feitian JavaCOS A22CR ICFabDate 2016 257 , ATR=3b 9c 95 80 81 1f 03 90 67 46 4a 01 00 35 04 f2 72 fe 00 a1 (provided by PetrS), - c18 Feitian JavaCOS A40 ICFabDate 2016 201 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 00 20 05 00 00 00 00 4e (provided by PetrS and Keneth Benson), - c19 Feitian K9 NXPJ3E081 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by Thotheolh Tay), - c20 FeiTian Ltd JavaCard Token V1.0 0 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 01 68 06 00 00 00 00 04 (provided by Thoth Tay), - c21 G+D Smart Cafe Expert 4.x V2 ICFabDate 2007 079 , ATR=3b f8 18 00 00 80 31 fe 45 00 73 c8 40 13 00 90 00 92 (provided by PetrS), Performance, Graphs - c22 G+D Smartcafe 6.0 80K ICFabDate 2015 024 , ATR=3b fe 18 00 00 80 31 fe 45 53 43 45 36 30 2d 43 44 30 38 31 2d 6e 46 a9 (provided by PetrS), - c23 G+D SmartCafe 7.0 215K USB Token S , ATR=3b f9 96 00 00 81 31 fe 45 53 43 45 37 20 0e 00 20 20 28 (provided by PetrS), - c24 G+D Smartcafe 7.0 , ATR=3b f9 96 00 00 80 31 fe 45 53 43 45 37 20 00 00 20 20 27 (provided by Radboud University), - c25 G+D SmartCafe Expert 144k Dual , ATR=3b fd 18 00 00 80 31 fe 45 73 66 74 65 20 63 64 31 34 34 2d 6e 66 d8 (provided by Diego NdK), - c26 G+D Smartcafe Expert 3.2 72K ICFabDate 2003 126 , ATR=3b f7 18 00 00 80 31 fe 45 73 66 74 65 2d 6e 66 c4 (provided by Cosmo and PetrS), - c27 G+D StarSign Crypto USB token S , ATR=3b f0 96 00 00 81 31 fe 45 6d (provided by Luka Logar), - c28 Gemalto IDCore 10 , ATR=3b 7d 96 00 00 80 31 80 65 b0 83 11 d0 a9 83 00 90 00 (provided by Martin Paljak), - c29 Gemalto IDCore 3010 CC , ATR=3b 7d 96 00 00 80 31 80 65 b0 85 02 00 cf 83 01 90 00 (provided by Martin Paljak), - c30 Gemalto TOP IM GXP4 , ATR=3b 7d 94 00 00 80 31 80 65 b0 83 11 d0 a9 83 00 90 00 (provided by PetrS), - c31 Gemalto TwinGCX4 72k ICFabDate 2006 005 , ATR=3b 7d 94 00 00 80 31 80 65 b0 83 11 11 ac 83 00 90 00 (provided by PetrS), - c32 Gemplus GXP R4 72K ICFabDate 2007 291 , ATR=3b 7d 94 00 00 80 31 80 65 b0 83 11 c0 a9 83 00 90 00 (provided by PetrS), Performance, Graphs - c33 Gemplus GXPE64PK TOP IM GX3 , ATR=3B 7E 94 00 00 80 25 A0 00 00 00 28 56 80 10 21 00 01 08 (provided by PetrS), - c34 Gemplus GXPLiteGeneric , ATR=3B 7D 94 00 00 80 31 80 65 B0 83 01 02 90 83 00 90 00 (provided by PetrS), - c35 Gemplus GXPR3 , ATR=3B 7B 94 00 00 80 65 B0 83 01 01 74 83 00 90 00 (provided by PetrS), - c36 Gemplus GXPR3r32 TOP IS GX3 , ATR=3B 7D 94 00 00 80 31 80 65 B0 83 01 02 90 83 00 90 00 (provided by PetrS), - c37 Idemia COSMO FLY v5.8 ICFabDate 2016 253 , ATR=3b 8b 80 01 00 31 c0 64 08 44 03 04 00 90 00 44 (provided by Kevin Osborn), - c38 Infineon CJTOP 80K INF SLJ 52GLA080AL M8.4 ICFabDate 2012 001 , ATR=3b fe 18 00 00 80 31 fe 45 80 31 80 66 40 90 a5 10 2e 10 83 01 90 00 f2 (provided by PetrS), Performance, Graphs - c39 Infineon jTOP ID SLJ 52GCA150CL ICFabDate 2015 , ATR=3b fe 18 00 00 80 31 fe 45 80 31 80 66 40 90 a5 10 2e 10 83 07 90 00 f4 (provided by Luka Logar), - c40 Infineon JTOPV2 16K , ATR=3B 6D 00 00 80 31 80 65 40 90 86 01 51 83 07 90 00 (provided by PetrS), - c41 Infineon SLE78 Universal JCard , ATR=3b fd 96 00 00 81 31 fe 45 53 4c 4a 35 32 47 44 4c 31 32 38 43 52 57 (provided by Till Maas RedTeamPentesting and PetrS), - c42 Infineon SLJ52GCA150 ICFabDate 2015 , ATR=3b fe 18 00 00 80 31 fe 45 80 31 80 66 40 90 a5 10 2e 10 83 01 90 00 f2 (provided by Toporin), - c43 JavaCardOS Infineon JC30M48CR , ATR=3b 80 80 01 01 (provided by JavaCardOS and Thotheolh Tay), - c44 JavaCardOS JC10M24R , ATR=3b 80 80 01 01 (provided by JavaCardOS), - c45 jCardSim-2.2.1-all , ATR=3B FA 18 00 00 81 31 FE 45 4A 43 4F 50 33 31 56 32 33 32 98 (provided by PetrS), - c46 jCardSim-2.2.2-all , ATR=3B FA 18 00 00 81 31 FE 45 4A 43 4F 50 33 31 56 32 33 32 98 (provided by PetrS), - c47 jCardSim-3.0.4-SNAPSHOT , ATR=3B FA 18 00 00 81 31 FE 45 4A 43 4F 50 33 31 56 32 33 32 98 (provided by PetrS), - c48 jCardSim-3.0.5-SNAPSHOT , ATR=3B FA 18 00 00 81 31 FE 45 4A 43 4F 50 33 31 56 32 33 32 98 (provided by PetrS), - c49 Nokia 6131 , ATR=3B 88 80 01 00 73 C8 40 13 00 90 00 71 (provided by Hakan Karahan), - c50 NXP JCOP J2A080 80K ICFabDate 2011 070 , ATR=3b f8 18 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 bc (provided by PetrS), - c51 NXP J2E081 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by PetrS), - c52 NXP J2E145G ICFabDate 2013 025 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by PetrS and Lukas Malina), - c53 NXP J3A080 ICFabDate 2011 035 , ATR=3b f8 13 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 b7 (provided by PetrS), - c54 NXP J3R150 EMV 4K RSA no OKBG no ECC , ATR=3b 6a 00 ff 00 31 c1 73 c8 40 00 00 90 00 (provided by dilucide), - c55 NXP J3R180 SECID 4K RSA OBKG ECC , ATR=3b d5 18 ff 81 91 fe 1f c3 80 73 c8 21 10 0a (provided by dilucide), - c56 NXP JCOP10 (DES only version) , ATR=3b e9 00 00 81 31 fe 45 4a 43 4f 50 31 30 56 32 32 a3 (provided by Henrik), - c57 NXP JCOP3 J3E145 , ATR=3b f9 18 00 00 81 31 fe 45 50 56 5f 4a 33 45 30 38 32 b5 (provided by Anonymous), - c58 NXP JCOP3 J3H081 EMV ICFabDate 2016 355 , ATR=3b f8 18 00 00 81 31 fe 45 00 73 c8 40 00 00 90 00 80 (provided by Adam Zhang and Richard Mitev), - c59 NXP JCOP3 J3H081 EMV ICFabDate 2018 , ATR=3b fa 18 00 00 81 31 fe 45 50 56 4a 43 4f 50 33 45 4d 56 94 (provided by Rowland Watkins and PetrS), - c60 NXP JCOP3 J3H145 (JCOP 3 SECID P60) , ATR=3b 9e 95 81 01 41 4a 43 4f 53 01 45 48 54 01 52 01 56 00 83 (provided by Kenneth Benson), - c61 NXP JCOP3 J3H145 SECID P60 , ATR=3b 11 95 80 (provided by Luka Logar and Rowland Watkins and PetrS), - c62 NXP JCOP41 v2.3.1 ICFabDate 2008 , ATR=3b fa 18 00 ff 81 31 fe 45 4a 43 4f 50 34 31 56 32 33 31 63 (provided by Radboud University), - c63 NXP JCOP41 v221 , ATR=3b fa 18 00 00 81 31 fe 45 4a 43 4f 50 34 31 56 32 32 31 9d (provided by PetrS), Performance, Graphs - c64 NXP JCOP4 J3R110 , ATR=3b fe 95 00 00 81 31 fe 45 ff 43 52 59 50 54 4e 4f 58 20 43 41 52 44 be (provided by Francesco Gugliuzza and PetrS), - c65 NXP JCOP4 J3R180 P71 , ATR=3b fa 18 00 ff 10 00 4a 54 61 78 43 6f 72 65 56 31 (provided by PetrS), - c66 NXP JCOP4 J3R180 SecID Feitian , ATR=3b d5 18 ff 81 91 fe 1f c3 80 73 c8 21 10 0a (provided by PetrS), - c67 NXP JCOP4 P71 NoECC , ATR=3b ea 00 00 81 31 fe 45 00 31 c1 73 c8 40 00 00 90 00 7a, - c68 NXP JCOP4 P71D321 , ATR=3b 8a 80 01 50 56 4a 43 4f 50 34 53 49 44 71 (provided by Riley Gall), - c69 NXP JCOP 10.18 v2.3.1 ICFabDate 2008 163 , ATR=3b fa 13 00 00 81 31 fe 45 4a 43 4f 50 31 30 56 32 33 31 93 (provided by PetrS), - c70 NXP JCOP 21 v2.4.2R3 ICFabDate 2013 025 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by PetrS), Performance, Graphs - c71 NXP JCOP 21 V2.2 36K ICFabDate 2008 015 , ATR=3b f9 18 00 00 81 31 fe 45 4a 43 4f 50 32 31 56 32 32 a9 (provided by PetrS), Performance, Graphs - c72 NXP JCOP 31 V2.2 36K ICFabDate 2006 306 , ATR=3b eb 00 00 81 31 20 45 4a 43 4f 50 33 31 33 36 47 44 54 78 (provided by PetrS), Performance, Graphs - c73 NXP JCOP 31 V2.3.2 ICFabDate 2011 016 , ATR=3b 8a 80 01 4a 43 4f 50 33 31 56 32 33 32 7a (provided by Martin Omacka), - c74 NXP JCOP 31 V2.4.1 72K ICFabDate 2012 240 , ATR=3b f8 13 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 b7 (provided by PetrS), Performance, Graphs - c75 NXP JCOP CJ2A081 JC222 ICFabDate 2012 240 , ATR=3b f8 13 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 b7 (provided by PetrS), Performance, Graphs - c76 NXP JCOP CJ3A080v241 , ATR=3B F8 13 00 00 81 31 FE 45 4A 43 4F 50 76 32 34 31 B7 (provided by Lazuardi Nasution), Performance, Graphs - c77 NXP JCOP CJ3A081 JC222 , ATR=3b f8 13 00 00 81 31 fe 45 4a 33 41 30 38 31 56 32 34 31 89 (provided by PetrS), Performance, Graphs - c78 NXP JCOP J2A080 , ATR=3b f6 18 00 ff 81 31 fe 45 4a 32 41 30 38 30 1b (provided by Pierre-d), Performance, Graphs - c79 NXP JCOP J2A080 80K ICFabDate 2011 070 , ATR=3b f8 18 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 bc (provided by PetrS), - c80 NXP JCOP J2A080 ICFabDate 2018 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 b7 01 (provided by Toporin), - c81 NXP JCOP J2D081 80K ICFabDate 2014 126 , ATR=3b f9 18 00 00 81 31 fe 45 4a 32 44 30 38 31 5f 50 56 b6 (provided by PetrS and Paul Crocker), Performance, Graphs - c82 NXP JCOP J2D081 ICFabDate 2017 , ATR=3b f9 18 00 00 81 31 fe 45 4a 32 44 30 38 31 5f 50 56 b6 (provided by Toporin), - c83 NXP JCOP J3A040 ICFabDate 2010 071 , ATR=3b 88 80 01 4a 43 4f 50 76 32 34 31 5e (provided by Lukas Malina), - c84 NXP JCOP J3A081 ICFabDate 2013 , ATR=3b f9 18 00 ff 81 31 fe 45 50 56 5f 4a 33 41 30 38 31 4d (provided by Toporin), - c85 NXP JCOP J3D081 v242r2 ICFabDate 2012 334 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 32 a3 (provided by Martin Paljak and Arnis UT), - c86 NXP JCOP J3H145G C4 , ATR=3b 94 95 81 01 46 54 56 01 c4 (provided by Jhony Melendez), - c87 NXP JCOP J3H145G C5 , ATR=3b 94 95 81 01 46 54 56 00 c5 (provided by Jhony Melendez), - c88 NXP JCOP NXP250A v242r3 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by Amir Digar Nemikhandad), - c89 Oberthur Cosmo V7 64K Dual 128K , ATR=3B DB 18 00 80 B1 FE 45 1F 83 00 31 C0 64 C7 FC 10 00 01 90 00 FA (provided by Cosmo), - c90 Oberthur Cosmo v7 , ATR=3b db 96 00 80 b1 fe 45 1f 83 00 31 c0 64 c3 08 01 00 01 90 00 95 (provided by PetrS), - c91 Oberthur CosmoDual72K , ATR=3B 7B 18 00 00 00 31 C0 64 77 E3 03 00 82 90 00 (provided by PetrS), - c92 Oberthur ID-ONE Cosmo 64 RSA v5.4 ICFabDate 2007 031 , ATR=3b 7b 18 00 00 00 31 c0 64 77 e9 10 00 01 90 00 (provided by PetrS), Performance, Graphs - c93 PIVKey C910 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 00 64 16 06 f2 72 7e 00 e0 (provided by Anonymous), - c94 Softlock SLCOS InfineonSLE78 , ATR=3b 8a 80 01 53 4c 43 4f 53 20 54 3d 43 4c 0d (provided by Ahmed Mamdouh), - c95 sysmocom sysmoUSIM-SJS1-3FF , ATR=3b 9f 96 80 1f c7 80 31 a0 73 be 21 13 67 43 20 07 18 00 00 01 a5 (provided by promovicz), - c96 Taisys SIMoME VAULT ICFabDate 2016 , ATR=3b 9f 95 80 3f c7 a0 80 31 e0 73 fa 21 10 63 00 00 00 83 f0 90 00 bb (provided by PetrS), - c97 Tongxin Microelectronics THD89 T101 , ATR=3b 1b 96 50 6f 6c 61 72 69 73 20 19 01 21 (provided by Thoth Tay), - c98 Unknown , ATR=3b 68 00 00 00 73 c8 40 12 00 90 00 (provided by Amir Digar Nemikhandad), - c99 Yubikey Neo (Warning not open JavaCard) , ATR=3b fa 13 00 00 81 31 fe 15 59 75 62 69 6b 65 79 4e 45 4f a6 (provided by Pierre-d and Cosmo), - c100 [undisclosed1] , ATR=3b xx xx xx xx xx xx xx xx xx xx xx xx xx xx (provided by Cosmo), - c101 [undisclosed2] , ATR=3b xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx (provided by Cosmo), - c102 [undisclosed3] , ATR=3b xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx (provided by Cosmo), - c103 [undisclosed4] , ATR=3b xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx (provided by Cosmo), - c104 [undisclosed5] , ATR=3b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (provided by Metro), - c105 [undisclosed6] , ATR=3b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (provided by Metro), -``` - -See more details at http://jcalgtest.org +([https://www.fi.muni.cz/~xsvenda/jcalgtest/](https://www.fi.muni.cz/~xsvenda/jcalgtest/)): + +``` +c0 ACS ACOSJ (Combi) , ATR=3b 69 00 02 41 43 4f 53 4a 76 31 30 31 (provided by Alexandre Bouvier), +c1 ACS ACOSJ 40K , ATR=3b 69 00 02 41 43 4f 53 4a 76 31 30 31 (provided by PetrS), +c2 Athena IDprotect , ATR=3B D5 18 FF 80 91 FE 1F C3 80 73 C8 21 13 08 (provided by Cosmo), +c3 Athena IDProtect ICFabDate 2015 , ATR=3b d5 18 ff 81 91 fe 1f c3 80 73 c8 21 13 09 (provided by PetrS), +c4 Axalto Cyberflex32 , ATR=3B 75 94 00 00 62 02 02 02 01 (provided by PetrS), +c5 Axalto Cyberflex PalmeraV5 , ATR=3B E6 00 00 81 21 45 32 4B 01 01 01 01 7A (provided by PetrS), +c6 Credentsys Lite , ATR=3b df 95 ff 80 91 fe 1f c3 80 25 a0 00 00 00 68 53 19 00 01 73 c8 21 13 29 (provided by Kate Gray), +c7 Feitian-FTJCOS ICFabDate 2018 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 00 87 06 00 00 00 00 ea (provided by Toporin), +c8 Feitian A40 ICFabDate 2018 , ATR=3b 9f 95 81 31 fe 9f 00 66 46 53 05 10 00 ff 71 df 00 00 00 00 00 ec (provided by Radboud University), +c9 Feitian A40CR ICFabDate 2018 , ATR=3b 9c 95 80 81 1f 03 90 67 46 4a 01 00 41 06 f2 72 7e 00 57, +c10 Feitian C21C Samsung S3FS91J , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 00 05 24 c0 72 7e 00 86 (provided by Thotheolh Tay), +c11 Feitian eJava Token , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 64 2f 70 c1 72 fe e0 fd (provided by Razvan Dragomirescu), +c12 Feitian Fingerprint card , ATR=3b 61 00 00 80 (provided by PetrS), +c13 Feitian Java Card D11CR , ATR=3b 6a 00 00 09 44 31 31 43 52 02 00 25 c3 (provided by PetrS), +c14 Feitian JavaCOS A22 ICFabDate 2015 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 00 68 08 04 00 00 00 00 0e (provided by Ivo Kubjas and PetrS), +c15 Feitian JavaCOS A22CR-ECC-SHA-2 ICFabDate 2015 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 00 10 04 f2 72 fe 00 01 (provided by Kenneth Benson), +c16 Feitian JavaCOS A22CR ICFabDate 2016 084 , ATR=3b 8c 80 01 90 67 46 4a 01 00 25 04 00 00 00 00 d6 (provided by Josh Harvey), +c17 Feitian JavaCOS A22CR ICFabDate 2016 257 , ATR=3b 9c 95 80 81 1f 03 90 67 46 4a 01 00 35 04 f2 72 fe 00 a1 (provided by PetrS), +c18 Feitian JavaCOS A40 ICFabDate 2016 201 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 00 20 05 00 00 00 00 4e (provided by PetrS and Keneth Benson), +c19 Feitian JavaSD , ATR=3b 9f 95 81 31 fe 9f 00 66 46 53 05 10 00 ff 71 df 00 00 00 00 00 ec (provided by Thoth), +c20 Feitian K9 NXPJ3E081 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by Thotheolh Tay), +c21 FeiTian Ltd JavaCard Token V1.0 0 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 01 01 68 06 00 00 00 00 04 (provided by Thoth Tay), +c22 G+D Smart Cafe Expert 4.x V2 ICFabDate 2007 079 , ATR=3b f8 18 00 00 80 31 fe 45 00 73 c8 40 13 00 90 00 92 (provided by PetrS), Performance, Graphs +c23 G+D Smartcafe 6.0 80K ICFabDate 2015 024 , ATR=3b fe 18 00 00 80 31 fe 45 53 43 45 36 30 2d 43 44 30 38 31 2d 6e 46 a9 (provided by PetrS), +c24 G+D SmartCafe 7.0 215K USB Token S , ATR=3b f9 96 00 00 81 31 fe 45 53 43 45 37 20 0e 00 20 20 28 (provided by PetrS), +c25 G+D Smartcafe 7.0 , ATR=3b f9 96 00 00 80 31 fe 45 53 43 45 37 20 00 00 20 20 27 (provided by Radboud University), +c26 G+D SmartCafe Expert 144k Dual , ATR=3b fd 18 00 00 80 31 fe 45 73 66 74 65 20 63 64 31 34 34 2d 6e 66 d8 (provided by Diego NdK), +c27 G+D Smartcafe Expert 3.2 72K ICFabDate 2003 126 , ATR=3b f7 18 00 00 80 31 fe 45 73 66 74 65 2d 6e 66 c4 (provided by Cosmo and PetrS), +c28 G+D StarSign Crypto USB token S , ATR=3b f0 96 00 00 81 31 fe 45 6d (provided by Luka Logar), +c29 Gemalto IDCore 10 , ATR=3b 7d 96 00 00 80 31 80 65 b0 83 11 d0 a9 83 00 90 00 (provided by Martin Paljak), +c30 Gemalto IDCore 3010 CC , ATR=3b 7d 96 00 00 80 31 80 65 b0 85 02 00 cf 83 01 90 00 (provided by Martin Paljak), +c31 Gemalto TOP IM GXP4 , ATR=3b 7d 94 00 00 80 31 80 65 b0 83 11 d0 a9 83 00 90 00 (provided by PetrS), +c32 Gemalto TwinGCX4 72k ICFabDate 2006 005 , ATR=3b 7d 94 00 00 80 31 80 65 b0 83 11 11 ac 83 00 90 00 (provided by PetrS), +c33 Gemplus GXP R4 72K ICFabDate 2007 291 , ATR=3b 7d 94 00 00 80 31 80 65 b0 83 11 c0 a9 83 00 90 00 (provided by PetrS), Performance, Graphs +c34 Gemplus GXPE64PK TOP IM GX3 , ATR=3B 7E 94 00 00 80 25 A0 00 00 00 28 56 80 10 21 00 01 08 (provided by PetrS), +c35 Gemplus GXPLiteGeneric , ATR=3B 7D 94 00 00 80 31 80 65 B0 83 01 02 90 83 00 90 00 (provided by PetrS), +c36 Gemplus GXPR3 , ATR=3B 7B 94 00 00 80 65 B0 83 01 01 74 83 00 90 00 (provided by PetrS), +c37 Gemplus GXPR3r32 TOP IS GX3 , ATR=3B 7D 94 00 00 80 31 80 65 B0 83 01 02 90 83 00 90 00 (provided by PetrS), +c38 Idemia COSMO FLY v5.8 ICFabDate 2016 253 , ATR=3b 8b 80 01 00 31 c0 64 08 44 03 04 00 90 00 44 (provided by Kevin Osborn), +c39 Infineon CJTOP 80K INF SLJ 52GLA080AL M8.4 ICFabDate 2012 001 , ATR=3b fe 18 00 00 80 31 fe 45 80 31 80 66 40 90 a5 10 2e 10 83 01 90 00 f2 (provided by PetrS), Performance, Graphs +c40 Infineon jTOP ID SLJ 52GCA150CL ICFabDate 2015 , ATR=3b fe 18 00 00 80 31 fe 45 80 31 80 66 40 90 a5 10 2e 10 83 07 90 00 f4 (provided by Luka Logar), +c41 Infineon JTOPV2 16K , ATR=3B 6D 00 00 80 31 80 65 40 90 86 01 51 83 07 90 00 (provided by PetrS), +c42 Infineon SECORA ID S (SCP02 with RSA2k JC305 GP230 NOT FOR SALE - PROTOTYPE ONLY) , ATR=3b b8 97 00 c0 08 31 fe 45 ff ff 13 57 30 50 23 00 6a (provided by Thoth), +c43 Infineon SECORA ID X , ATR=3b b8 97 00 c0 08 31 fe 45 ff ff 13 58 30 50 23 00 65 (provided by Thoth), +c44 Infineon SECORA ID X Batch 16072021 SALES , ATR=3b 88 80 01 00 00 00 11 77 81 c3 00 2d (provided by Thoth), +c45 Infineon SLE78 Universal JCard , ATR=3b fd 96 00 00 81 31 fe 45 53 4c 4a 35 32 47 44 4c 31 32 38 43 52 57 (provided by Till Maas RedTeamPentesting and PetrS), +c46 Infineon SLJ52GCA150 ICFabDate 2015 , ATR=3b fe 18 00 00 80 31 fe 45 80 31 80 66 40 90 a5 10 2e 10 83 01 90 00 f2 (provided by Toporin), +c47 Infineon SPA1-1 ThothTrust Edition , ATR=3b 89 80 01 66 52 57 45 32 50 52 4f 4d 1c (provided by Thoth), +c48 JavaCardOS Infineon JC30M48CR , ATR=3b 80 80 01 01 (provided by JavaCardOS and Thotheolh Tay), +c49 JavaCardOS JC10M24R , ATR=3b 80 80 01 01 (provided by JavaCardOS), +c50 jCardSim-2.2.1-all , ATR=3B FA 18 00 00 81 31 FE 45 4A 43 4F 50 33 31 56 32 33 32 98 (provided by PetrS), +c51 jCardSim-2.2.2-all , ATR=3B FA 18 00 00 81 31 FE 45 4A 43 4F 50 33 31 56 32 33 32 98 (provided by PetrS), +c52 jCardSim-3.0.4-SNAPSHOT , ATR=3B FA 18 00 00 81 31 FE 45 4A 43 4F 50 33 31 56 32 33 32 98 (provided by PetrS), +c53 jCardSim-3.0.5-SNAPSHOT , ATR=3B FA 18 00 00 81 31 FE 45 4A 43 4F 50 33 31 56 32 33 32 98 (provided by PetrS), +c54 Nokia 6131 , ATR=3B 88 80 01 00 73 C8 40 13 00 90 00 71 (provided by Hakan Karahan), +c55 NXP JCOP J2A080 80K ICFabDate 2011 070 , ATR=3b f8 18 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 bc (provided by PetrS), +c56 NXP J2E081 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by PetrS), +c57 NXP J2E145G ICFabDate 2013 025 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by PetrS and Lukas Malina), +c58 NXP J3A080 ICFabDate 2011 035 , ATR=3b f8 13 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 b7 (provided by PetrS), +c59 NXP JCOP10 (DES only version) , ATR=3b e9 00 00 81 31 fe 45 4a 43 4f 50 31 30 56 32 32 a3 (provided by Henrik), +c60 NXP JCOP3 J3E145 , ATR=3b f9 18 00 00 81 31 fe 45 50 56 5f 4a 33 45 30 38 32 b5 (provided by Anonymous), +c61 NXP JCOP3 J3H081 EMV ICFabDate 2016 355 , ATR=3b f8 18 00 00 81 31 fe 45 00 73 c8 40 00 00 90 00 80 (provided by Adam Zhang and Richard Mitev), +c62 NXP JCOP3 J3H081 EMV ICFabDate 2018 , ATR=3b fa 18 00 00 81 31 fe 45 50 56 4a 43 4f 50 33 45 4d 56 94 (provided by Rowland Watkins and PetrS), +c63 NXP JCOP3 J3H145 (JCOP 3 SECID P60) , ATR=3b 9e 95 81 01 41 4a 43 4f 53 01 45 48 54 01 52 01 56 00 83 (provided by Kenneth Benson), +c64 NXP JCOP3 J3H145 SCP03 RSA4K , ATR=3b dc 18 ff 81 91 fe 1f c3 80 73 c8 21 13 66 05 03 63 51 00 02 50 (provided by Peter Steiert), +c65 NXP JCOP3 J3H145 SECID P60 , ATR=3b 11 95 80 (provided by Luka Logar and Rowland Watkins and PetrS), +c66 NXP JCOP41 v2.3.1 ICFabDate 2008 , ATR=3b fa 18 00 ff 81 31 fe 45 4a 43 4f 50 34 31 56 32 33 31 63 (provided by Radboud University), +c67 NXP JCOP41 v221 , ATR=3b fa 18 00 00 81 31 fe 45 4a 43 4f 50 34 31 56 32 32 31 9d (provided by PetrS), Performance, Graphs +c68 NXP JCOP4 J3R110 , ATR=3b fe 95 00 00 81 31 fe 45 ff 43 52 59 50 54 4e 4f 58 20 43 41 52 44 be (provided by Francesco Gugliuzza and PetrS), +c69 NXP JCOP4 J3R150 EMV 4K RSA no OKBG no ECC , ATR=3b 6a 00 ff 00 31 c1 73 c8 40 00 00 90 00 (provided by dilucide), +c70 NXP JCOP4 J3R180 P71 , ATR=3b fa 18 00 ff 10 00 4a 54 61 78 43 6f 72 65 56 31 (provided by PetrS), +c71 NXP JCOP4 J3R180 SECID 4K RSA OBKG ECC , ATR=3b d5 18 ff 81 91 fe 1f c3 80 73 c8 21 10 0a (provided by dilucide), +c72 NXP JCOP4 J3R180 SecID Feitian , ATR=3b d5 18 ff 81 91 fe 1f c3 80 73 c8 21 10 0a (provided by PetrS), +c73 NXP JCOP4 P71 NoECC , ATR=3b ea 00 00 81 31 fe 45 00 31 c1 73 c8 40 00 00 90 00 7a, +c74 NXP JCOP4 P71D321 , ATR=3b 8a 80 01 50 56 4a 43 4f 50 34 53 49 44 71 (provided by Riley Gall), +c75 NXP JCOP 10.18 v2.3.1 ICFabDate 2008 163 , ATR=3b fa 13 00 00 81 31 fe 45 4a 43 4f 50 31 30 56 32 33 31 93 (provided by PetrS), +c76 NXP JCOP 21 v2.4.2R3 ICFabDate 2013 025 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by PetrS), Performance, Graphs +c77 NXP JCOP 21 V2.2 36K ICFabDate 2008 015 , ATR=3b f9 18 00 00 81 31 fe 45 4a 43 4f 50 32 31 56 32 32 a9 (provided by PetrS), Performance, Graphs +c78 NXP JCOP 31 V2.2 36K ICFabDate 2006 306 , ATR=3b eb 00 00 81 31 20 45 4a 43 4f 50 33 31 33 36 47 44 54 78 (provided by PetrS), Performance, Graphs +c79 NXP JCOP 31 V2.3.2 ICFabDate 2011 016 , ATR=3b 8a 80 01 4a 43 4f 50 33 31 56 32 33 32 7a (provided by Martin Omacka), +c80 NXP JCOP 31 V2.4.1 72K ICFabDate 2012 240 , ATR=3b f8 13 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 b7 (provided by PetrS), Performance, Graphs +c81 NXP JCOP CJ2A081 JC222 ICFabDate 2012 240 , ATR=3b f8 13 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 b7 (provided by PetrS), Performance, Graphs +c82 NXP JCOP CJ3A080v241 , ATR=3B F8 13 00 00 81 31 FE 45 4A 43 4F 50 76 32 34 31 B7 (provided by Lazuardi Nasution), Performance, Graphs +c83 NXP JCOP CJ3A081 JC222 , ATR=3b f8 13 00 00 81 31 fe 45 4a 33 41 30 38 31 56 32 34 31 89 (provided by PetrS), Performance, Graphs +c84 NXP JCOP J2A080 , ATR=3b f6 18 00 ff 81 31 fe 45 4a 32 41 30 38 30 1b (provided by Pierre-d), Performance, Graphs +c85 NXP JCOP J2A080 80K ICFabDate 2011 070 , ATR=3b f8 18 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 bc (provided by PetrS), +c86 NXP JCOP J2A080 ICFabDate 2018 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 76 32 34 31 b7 01 (provided by Toporin), +c87 NXP JCOP J2D081 80K ICFabDate 2014 126 , ATR=3b f9 18 00 00 81 31 fe 45 4a 32 44 30 38 31 5f 50 56 b6 (provided by PetrS and Paul Crocker), Performance, Graphs +c88 NXP JCOP J2D081 ICFabDate 2017 , ATR=3b f9 18 00 00 81 31 fe 45 4a 32 44 30 38 31 5f 50 56 b6 (provided by Toporin), +c89 NXP JCOP J3A040 ICFabDate 2010 071 , ATR=3b 88 80 01 4a 43 4f 50 76 32 34 31 5e (provided by Lukas Malina), +c90 NXP JCOP J3A081 ICFabDate 2013 , ATR=3b f9 18 00 ff 81 31 fe 45 50 56 5f 4a 33 41 30 38 31 4d (provided by Toporin), +c91 NXP JCOP J3D081 v242r2 ICFabDate 2012 334 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 32 a3 (provided by Martin Paljak and Arnis UT), +c92 NXP JCOP J3H145G C4 , ATR=3b 94 95 81 01 46 54 56 01 c4 (provided by Jhony Melendez), +c93 NXP JCOP J3H145G C5 , ATR=3b 94 95 81 01 46 54 56 00 c5 (provided by Jhony Melendez), +c94 NXP JCOP NXP250A v242r3 , ATR=3b f9 13 00 00 81 31 fe 45 4a 43 4f 50 32 34 32 52 33 a2 (provided by Amir Digar Nemikhandad), +c95 Oberthur Cosmo V7 64K Dual 128K , ATR=3B DB 18 00 80 B1 FE 45 1F 83 00 31 C0 64 C7 FC 10 00 01 90 00 FA (provided by Cosmo), +c96 Oberthur Cosmo v7 , ATR=3b db 96 00 80 b1 fe 45 1f 83 00 31 c0 64 c3 08 01 00 01 90 00 95 (provided by PetrS), +c97 Oberthur CosmoDual72K , ATR=3B 7B 18 00 00 00 31 C0 64 77 E3 03 00 82 90 00 (provided by PetrS), +c98 Oberthur ID-ONE Cosmo 64 RSA v5.4 ICFabDate 2007 031 , ATR=3b 7b 18 00 00 00 31 c0 64 77 e9 10 00 01 90 00 (provided by PetrS), Performance, Graphs +c99 PIVKey C910 , ATR=3b fc 18 00 00 81 31 80 45 90 67 46 4a 00 64 16 06 f2 72 7e 00 e0 (provided by Anonymous), +c100 PIVKey C980 , ATR=3b 89 80 01 53 50 49 56 4b 45 59 37 30 44 (provide by Arthur Moore), +c101 Softlock SLCOS InfineonSLE78 , ATR=3b 8a 80 01 53 4c 43 4f 53 20 54 3d 43 4c 0d (provided by Ahmed Mamdouh), +c102 sysmocom sysmoUSIM-SJS1-3FF , ATR=3b 9f 96 80 1f c7 80 31 a0 73 be 21 13 67 43 20 07 18 00 00 01 a5 (provided by promovicz), +c103 Taisys SIMoME VAULT ICFabDate 2016 , ATR=3b 9f 95 80 3f c7 a0 80 31 e0 73 fa 21 10 63 00 00 00 83 f0 90 00 bb (provided by PetrS), +c104 Tongxin Microelectronics THD89 T101 , ATR=3b 1b 96 50 6f 6c 61 72 69 73 20 19 01 21 (provided by Thoth Tay), +c105 Unknown , ATR=3b 68 00 00 00 73 c8 40 12 00 90 00 (provided by Amir Digar Nemikhandad), +c106 Yubikey Neo (Warning not open JavaCard) , ATR=3b fa 13 00 00 81 31 fe 15 59 75 62 69 6b 65 79 4e 45 4f a6 (provided by Pierre-d and Cosmo), +c107 [undisclosed1] , ATR=3b xx xx xx xx xx xx xx xx xx xx xx xx xx xx (provided by Cosmo), +c108 [undisclosed2] , ATR=3b xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx (provided by Cosmo), +c109 [undisclosed3] , ATR=3b xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx (provided by Cosmo), +c110 [undisclosed4] , ATR=3b xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx (provided by Cosmo), +c111 [undisclosed5] , ATR=3b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (provided by Metro), +c112 [undisclosed6] , ATR=3b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (provided by Metro), +``` +