tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

genTestVectors.py (21704B)


      1 #!/usr/bin/env python3
      2 # -*- coding: utf-8 -*-
      3 
      4 # This Source Code Form is subject to the terms of the Mozilla Public
      5 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
      6 # You can obtain one at http://mozilla.org/MPL/2.0/.
      7 
      8 import json
      9 import os
     10 import subprocess
     11 
     12 from cryptography.hazmat.backends import default_backend
     13 from cryptography.hazmat.primitives.asymmetric import ec
     14 from cryptography.hazmat.primitives import serialization
     15 import binascii
     16 
     17 script_dir = os.path.dirname(os.path.abspath(__file__))
     18 
     19 # Imports a JSON testvector file.
     20 def import_testvector(file):
     21    """Import a JSON testvector file and return an array of the contained objects."""
     22    with open(file) as f:
     23        vectors = json.loads(f.read())
     24    return vectors
     25 
     26 # Convert a test data string to a hex array.
     27 def string_to_hex_array(string):
     28    """Convert a string of hex chars to a string representing a C-format array of hex bytes."""
     29    b = bytearray.fromhex(string)
     30    result = '{' + ', '.join("{:#04x}".format(x) for x in b) + '}'
     31    return result
     32 
     33 # Writes one AES-GCM testvector into C-header format. (Not clang-format conform)
     34 class AESGCM():
     35    """Class that provides the generator function for a single AES-GCM test case."""
     36 
     37    def format_testcase(self, vector):
     38        """Format an AES-GCM testcase object. Return a string in C-header format."""
     39        result = '{{ {},\n'.format(vector['tcId'])
     40        for key in ['key', 'msg', 'aad', 'iv']:
     41            result += ' \"{}\",\n'.format(vector[key])
     42        result += ' \"\",\n'
     43        result += ' \"{}\",\n'.format(vector['tag'])
     44        result += ' \"{}\",\n'.format(vector['ct'] + vector['tag'])
     45        result += ' {},\n'.format(str(vector['result'] == 'invalid').lower())
     46        result += ' {}}},\n\n'.format(str('ZeroLengthIv' in vector['flags']).lower())
     47 
     48        return result
     49 
     50 # Writes one AES-CMAC testvector into C-header format. (Not clang-format conform)
     51 class AESCMAC():
     52    """Class that provides the generator function for a single AES-CMAC test case."""
     53 
     54    def format_testcase(self, vector):
     55        """Format an AES-CMAC testcase object. Return a string in C-header format."""
     56        result = '{{ {},\n'.format(vector['tcId'])
     57        for key in ['comment', 'key', 'msg', 'tag']:
     58            result += ' \"{}\",\n'.format(vector[key])
     59        result += ' {}}},\n\n'.format(str(vector['result'] == 'invalid').lower())
     60 
     61        return result
     62 
     63 # Writes one AES-CBC testvector into C-header format. (Not clang-format conform)
     64 class AESCBC():
     65    """Class that provides the generator function for a single AES-CBC test case."""
     66 
     67    def format_testcase(self, vector):
     68        """Format an AES-CBC testcase object. Return a string in C-header format."""
     69        result = '{{ {},\n'.format(vector['tcId'])
     70        for key in ['key', 'msg', 'iv']:
     71            result += ' \"{}\",\n'.format(vector[key])
     72        result += ' \"{}\",\n'.format(vector['ct'])
     73        result += ' {}}},\n\n'.format(str(vector['result'] == 'valid' and len(vector['flags']) == 0).lower())
     74 
     75        return result
     76 
     77 # Writes one ChaChaPoly testvector into C-header format. (Not clang-format conform)
     78 class ChaChaPoly():
     79    """Class that provides the generator function for a single ChaCha test case."""
     80 
     81    def format_testcase(self, testcase):
     82        """Format an ChaCha testcase object. Return a string in C-header format."""
     83        result = '\n// Comment: {}'.format(testcase['comment'])
     84        result += '\n{{{},\n'.format(testcase['tcId']-1)
     85        for key in ['msg', 'aad', 'key', 'iv']:
     86            result += '{},\n'.format(string_to_hex_array(testcase[key]))
     87        ct = testcase['ct'] + testcase['tag']
     88        result += '{},\n'.format(string_to_hex_array(ct))
     89        result += '{},\n'.format(str(testcase['result'] == 'invalid').lower())
     90        result += '{}}},\n'.format(str(testcase['comment'] == 'invalid nonce size').lower())
     91 
     92        return result
     93 
     94 class DSA():
     95    pub_keys = {}
     96    def format_testcase(self, testcase, key, hash_oid, keySize, out_defs):
     97        key_name = "kPubKey"
     98        if key in self.pub_keys:
     99            key_name = self.pub_keys[key]
    100        else:
    101            key_name += str(len(self.pub_keys))
    102            self.pub_keys[key] = key_name
    103            out_defs.append('static const std::vector<uint8_t> ' + key_name + string_to_hex_array(key) + ';\n\n')
    104        result = '\n// Comment: {}'.format(testcase['comment'])
    105        result += '\n// tcID: {}\n'.format(testcase['tcId'])
    106        result += '{{{}, {},\n'.format(hash_oid, testcase['tcId'])
    107        result += '{},\n'.format(string_to_hex_array(testcase['sig']))
    108        result += '{},\n'.format(key_name)
    109        result += '{},\n'.format(string_to_hex_array(testcase['msg']))
    110        valid = testcase['result'] == 'valid' or (testcase['result'] == 'acceptable' and 'NoLeadingZero' in testcase['flags'])
    111        result += '{}}},\n'.format(str(valid).lower())
    112 
    113        return result
    114 
    115 class HKDF():
    116    """Class that provides the generator function for a single HKDF test case."""
    117 
    118    def format_testcase(self, vector):
    119        """Format an HKDF testcase object. Return a string in C-header format."""
    120        result = '{{ {},\n'.format(vector['tcId'])
    121        for key in ['ikm', 'salt', 'info', "okm"]:
    122            result += ' \"{}\",\n'.format(vector[key])
    123        result += ' {},\n'.format(vector['size'])
    124        result += ' {}}},\n\n'.format(str(vector['result'] == 'valid').lower())
    125 
    126        return result
    127 
    128 class RSA_OAEP():
    129    priv_keys = {}
    130 
    131    def format_testcase(self, testcase, key, hash_oid, mgf_hash, out_defs):
    132        key_name = "priv_key_"
    133        if key in self.priv_keys:
    134            key_name = self.priv_keys[key]
    135        else:
    136            key_name += str(len(self.priv_keys))
    137            self.priv_keys[key] = key_name
    138            out_defs.append('static const std::vector<uint8_t> ' + key_name + string_to_hex_array(key) + ';\n\n')
    139 
    140        result = '\n// Comment: {}'.format(testcase['comment'])
    141        result += '\n// tcID: {}\n'.format(testcase['tcId'])
    142        result += '{{{}, {}, {},\n'.format(hash_oid, mgf_hash, testcase['tcId'])
    143        result += '{},\n'.format(string_to_hex_array(testcase['msg']))
    144        result += '{},\n'.format(string_to_hex_array(testcase['ct']))
    145        result += '{},\n'.format(string_to_hex_array(testcase['label']))
    146        result += '{},\n'.format(key_name)
    147 
    148        valid = testcase['result'] == 'valid'
    149        result += '{}}},\n'.format(str(valid).lower())
    150 
    151        return result
    152 
    153 class HMAC():
    154    """Class that provides the generator function for a single HMAC test case."""
    155 
    156    def format_testcase(self, vector):
    157        """Format a HMAC testcase object. Return a string in C-header format."""
    158        result = '{{ {},\n'.format(vector['tcId'])
    159        for key in ['comment', 'key', 'msg', "tag"]:
    160            result += ' \"{}\",\n'.format(vector[key])
    161        result += ' {}}},\n\n'.format(str(vector['result'] == 'invalid').lower())
    162 
    163        return result
    164 
    165 
    166 def getSha(sha):
    167    s = sha.split("-")
    168    return "SEC_OID_SHA" + s[1]
    169 
    170 def getMgfSha(sha):
    171    s = sha.split("-")
    172    return "CKG_MGF1_SHA" + s[1]
    173 
    174 def generate_vectors_file(params):
    175    """
    176    Generate and store a .h-file with test vectors for one test.
    177 
    178    params -- Dictionary with parameters for test vector generation for the desired test.
    179    """
    180 
    181    cases = import_testvector(os.path.join(script_dir, params['source_dir'] + params['source_file']))
    182 
    183    base_vectors = ""
    184    if 'base' in params:
    185        with open(os.path.join(script_dir, params['base'])) as base:
    186            base_vectors = base.read()
    187        base_vectors += "\n\n"
    188 
    189    header = standard_params['license']
    190    header += "\n"
    191    header += standard_params['top_comment']
    192    header += "\n"
    193    header += "#ifndef " + params['section'] + "\n"
    194    header += "#define " + params['section'] + "\n"
    195    header += "\n"
    196 
    197    for include in standard_params['includes']:
    198        header += "#include " + include + "\n"
    199 
    200    header += "\n"
    201 
    202    if 'includes' in params:
    203        for include in params['includes']:
    204            header += "#include " + include + "\n"
    205        header += "\n"
    206 
    207    shared_defs = []
    208    vectors_file = base_vectors + params['array_init']
    209 
    210    for group in cases['testGroups']:
    211        for test in group['tests']:
    212            if 'key' in group:
    213                if 'curve' in group['key'] and group['key']['curve'] not in ['secp256r1', 'secp384r1', 'secp521r1']:
    214                    continue
    215                vectors_file += params['formatter'].format_testcase(test, group['keyDer'], getSha(group['sha']), group['key']['keySize'], shared_defs)
    216            elif 'type' in group and group['type'] == 'RsaesOaepDecrypt':
    217                vectors_file += params['formatter'].format_testcase(test, group['privateKeyPkcs8'], getSha(group['sha']), getMgfSha(group['mgfSha']), shared_defs)
    218            elif 'keyDer' in group:
    219                vectors_file += params['formatter'].format_testcase(test, group['keyDer'], group['keysize'], getSha(group['sha']), shared_defs)
    220            elif 'privateKeyPkcs8' in group:
    221                vectors_file += params['formatter'].format_testcase(test, group['privateKeyPkcs8'], group['keysize'], shared_defs)
    222            elif 'curve' in group:
    223                if group['curve'] == 'secp256r1':
    224                    curve = ec.SECP256R1()
    225                elif group['curve'] == 'secp384r1':
    226                    curve = ec.SECP384R1()
    227                elif group['curve'] == 'secp521r1':
    228                    curve = ec.SECP521R1()
    229                else:
    230                    continue
    231                vectors_file += params['formatter'].format_testcase(test, curve)
    232            else:
    233                vectors_file += params['formatter'].format_testcase(test)
    234 
    235    vectors_file = vectors_file[:params['crop_size_end']] + '\n};\n\n'
    236    vectors_file += "#endif // " + params['section'] + '\n'
    237 
    238    with open(os.path.join(script_dir, params['target']), 'w') as target:
    239        target.write(header)
    240        for definition in shared_defs:
    241            target.write(definition)
    242        target.write(vectors_file)
    243 
    244 
    245 standard_params = {
    246    'includes': ['"testvectors_base/test-structs.h"'],
    247    'license':
    248 """/* vim: set ts=2 et sw=2 tw=80: */
    249 /* This Source Code Form is subject to the terms of the Mozilla Public
    250 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
    251 * You can obtain one at http://mozilla.org/MPL/2.0/. */
    252 """,
    253 
    254    'top_comment':
    255 """/* This file is generated from sources in nss/gtests/common/wycheproof
    256 * automatically and should not be touched manually.
    257 * Generation is trigged by calling python3 genTestVectors.py */
    258 """
    259 }
    260 
    261 # Parameters that describe the generation of a testvector file for each supoorted test.
    262 # source -- relative path to the wycheproof JSON source file with testvectors.
    263 # base -- relative path to non-wycheproof vectors.
    264 # target -- relative path to where the finished .h-file is written.
    265 # array_init -- string to initialize the c-header style array of testvectors.
    266 # formatter -- the test case formatter class to be used for this test.
    267 # crop_size_end -- number of characters removed from the end of the last generated test vector to close the array definition.
    268 # section -- name of the section
    269 # comment -- additional comments to add to the file just before definition of the test vector array.
    270 
    271 aes_gcm_params = {
    272    'source_dir': 'source_vectors/',
    273    'source_file': 'aes_gcm_test.json',
    274    'base': '../testvectors_base/gcm-vectors_base.h',
    275    'target': '../testvectors/gcm-vectors.h',
    276    'array_init': 'const AesGcmKatValue kGcmWycheproofVectors[] = {\n',
    277    'formatter' : AESGCM(),
    278    'crop_size_end': -3,
    279    'section': 'gcm_vectors_h__',
    280    'comment' : ''
    281 }
    282 
    283 aes_cmac_params = {
    284    'source_dir': 'source_vectors/',
    285    'source_file': 'aes_cmac_test.json',
    286    'target': '../testvectors/cmac-vectors.h',
    287    'array_init': 'const AesCmacTestVector kCmacWycheproofVectors[] = {\n',
    288    'formatter' : AESCMAC(),
    289    'crop_size_end': -3,
    290    'section': 'cmac_vectors_h__',
    291    'comment' : ''
    292 }
    293 
    294 aes_cbc_params = {
    295    'source_dir': 'source_vectors/',
    296    'source_file': 'aes_cbc_pkcs5_test.json',
    297    'target': '../testvectors/cbc-vectors.h',
    298    'array_init': 'const AesCbcTestVector kCbcWycheproofVectors[] = {\n',
    299    'formatter' : AESCBC(),
    300    'crop_size_end': -3,
    301    'section': 'cbc_vectors_h__',
    302    'comment' : ''
    303 }
    304 
    305 chacha_poly_params = {
    306    'source_dir': 'source_vectors/',
    307    'source_file': 'chacha20_poly1305_test.json',
    308    'base': '../testvectors_base/chachapoly-vectors_base.h',
    309    'target': '../testvectors/chachapoly-vectors.h',
    310    'array_init': 'const ChaChaTestVector kChaCha20WycheproofVectors[] = {\n',
    311    'formatter' : ChaChaPoly(),
    312    'crop_size_end': -2,
    313    'section': 'chachapoly_vectors_h__',
    314    'comment' : ''
    315 }
    316 
    317 dsa_params = {
    318    'source_dir': 'source_vectors/',
    319    'source_file': 'dsa_test.json',
    320    'target': '../testvectors/dsa-vectors.h',
    321    'array_init': 'const DsaTestVector kDsaWycheproofVectors[] = {\n',
    322    'formatter' : DSA(),
    323    'crop_size_end': -2,
    324    'section': 'dsa_vectors_h__',
    325    'comment' : ''
    326 }
    327 
    328 hkdf_sha1_params = {
    329    'source_dir': 'source_vectors/',
    330    'source_file': 'hkdf_sha1_test.json',
    331    'target': '../testvectors/hkdf-sha1-vectors.h',
    332    'array_init': 'const HkdfTestVector kHkdfSha1WycheproofVectors[] = {\n',
    333    'formatter' : HKDF(),
    334    'crop_size_end': -3,
    335    'section': 'hkdf_sha1_vectors_h__',
    336    'comment' : ''
    337 }
    338 
    339 hkdf_sha256_params = {
    340    'source_dir': 'source_vectors/',
    341    'source_file': 'hkdf_sha256_test.json',
    342    'target': '../testvectors/hkdf-sha256-vectors.h',
    343    'array_init': 'const HkdfTestVector kHkdfSha256WycheproofVectors[] = {\n',
    344    'formatter' : HKDF(),
    345    'crop_size_end': -3,
    346    'section': 'hkdf_sha256_vectors_h__',
    347    'comment' : ''
    348 }
    349 
    350 hkdf_sha384_params = {
    351    'source_dir': 'source_vectors/',
    352    'source_file': 'hkdf_sha384_test.json',
    353    'target': '../testvectors/hkdf-sha384-vectors.h',
    354    'array_init': 'const HkdfTestVector kHkdfSha384WycheproofVectors[] = {\n',
    355    'formatter' : HKDF(),
    356    'crop_size_end': -3,
    357    'section': 'hkdf_sha384_vectors_h__',
    358    'comment' : ''
    359 }
    360 
    361 hkdf_sha512_params = {
    362    'source_dir': 'source_vectors/',
    363    'source_file': 'hkdf_sha512_test.json',
    364    'target': '../testvectors/hkdf-sha512-vectors.h',
    365    'array_init': 'const HkdfTestVector kHkdfSha512WycheproofVectors[] = {\n',
    366    'formatter' : HKDF(),
    367    'crop_size_end': -3,
    368    'section': 'hkdf_sha512_vectors_h__',
    369    'comment' : ''
    370 }
    371 
    372 rsa_oaep_2048_sha1_mgf1sha1_params = {
    373    'source_dir': 'source_vectors/',
    374    'source_file': 'rsa_oaep_2048_sha1_mgf1sha1_test.json',
    375    'target': '../testvectors/rsa_oaep_2048_sha1_mgf1sha1-vectors.h',
    376    'array_init': 'const RsaOaepTestVector kRsaOaep2048Sha1WycheproofVectors[] = {\n',
    377    'formatter' : RSA_OAEP(),
    378    'crop_size_end': -2,
    379    'section': 'rsa_oaep_2048_sha1_mgf1sha1_vectors_h__',
    380    'comment' : ''
    381 }
    382 
    383 rsa_oaep_2048_sha256_mgf1sha1_params = {
    384    'source_dir': 'source_vectors/',
    385    'source_file': 'rsa_oaep_2048_sha256_mgf1sha1_test.json',
    386    'target': '../testvectors/rsa_oaep_2048_sha256_mgf1sha1-vectors.h',
    387    'array_init': 'const RsaOaepTestVector kRsaOaep2048Sha256Mgf1Sha1WycheproofVectors[] = {\n',
    388    'formatter' : RSA_OAEP(),
    389    'crop_size_end': -2,
    390    'section': 'rsa_oaep_2048_sha256_mgf1sha1_vectors_h__',
    391    'comment' : ''
    392 }
    393 
    394 rsa_oaep_2048_sha256_mgf1sha256_params = {
    395    'source_dir': 'source_vectors/',
    396    'source_file': 'rsa_oaep_2048_sha256_mgf1sha256_test.json',
    397    'target': '../testvectors/rsa_oaep_2048_sha256_mgf1sha256-vectors.h',
    398    'array_init': 'const RsaOaepTestVector kRsaOaep2048Sha256Mgf1Sha256WycheproofVectors[] = {\n',
    399    'formatter' : RSA_OAEP(),
    400    'crop_size_end': -2,
    401    'section': 'rsa_oaep_2048_sha256_mgf1sha256_vectors_h__',
    402    'comment' : ''
    403 }
    404 
    405 rsa_oaep_2048_sha384_mgf1sha1_params = {
    406    'source_dir': 'source_vectors/',
    407    'source_file': 'rsa_oaep_2048_sha384_mgf1sha1_test.json',
    408    'target': '../testvectors/rsa_oaep_2048_sha384_mgf1sha1-vectors.h',
    409    'array_init': 'const RsaOaepTestVector kRsaOaep2048Sha384Mgf1Sha1WycheproofVectors[] = {\n',
    410    'formatter' : RSA_OAEP(),
    411    'crop_size_end': -2,
    412    'section': 'rsa_oaep_2048_sha384_mgf1sha1_vectors_h__',
    413    'comment' : ''
    414 }
    415 
    416 rsa_oaep_2048_sha384_mgf1sha384_params = {
    417    'source_dir': 'source_vectors/',
    418    'source_file': 'rsa_oaep_2048_sha384_mgf1sha384_test.json',
    419    'target': '../testvectors/rsa_oaep_2048_sha384_mgf1sha384-vectors.h',
    420    'array_init': 'const RsaOaepTestVector kRsaOaep2048Sha384Mgf1Sha384WycheproofVectors[] = {\n',
    421    'formatter' : RSA_OAEP(),
    422    'crop_size_end': -2,
    423    'section': 'rsa_oaep_2048_sha384_mgf1sha384_vectors_h__',
    424    'comment' : ''
    425 }
    426 
    427 rsa_oaep_2048_sha512_mgf1sha1_params = {
    428    'source_dir': 'source_vectors/',
    429    'source_file': 'rsa_oaep_2048_sha512_mgf1sha1_test.json',
    430    'target': '../testvectors/rsa_oaep_2048_sha512_mgf1sha1-vectors.h',
    431    'array_init': 'const RsaOaepTestVector kRsaOaep2048Sha512Mgf1Sha1WycheproofVectors[] = {\n',
    432    'formatter' : RSA_OAEP(),
    433    'crop_size_end': -2,
    434    'section': 'rsa_oaep_2048_sha512_mgf1sha1_vectors_h__',
    435    'comment' : ''
    436 }
    437 
    438 rsa_oaep_2048_sha512_mgf1sha512_params = {
    439    'source_dir': 'source_vectors/',
    440    'source_file': 'rsa_oaep_2048_sha512_mgf1sha512_test.json',
    441    'target': '../testvectors/rsa_oaep_2048_sha512_mgf1sha512-vectors.h',
    442    'array_init': 'const RsaOaepTestVector kRsaOaep2048Sha512Mgf1Sha512WycheproofVectors[] = {\n',
    443    'formatter' : RSA_OAEP(),
    444    'crop_size_end': -2,
    445    'section': 'rsa_oaep_2048_sha512_mgf1sha512_vectors_h__',
    446    'comment' : ''
    447 }
    448 
    449 hmac_sha256_params = {
    450    'source_dir': 'source_vectors/',
    451    'source_file': 'hmac_sha256_test.json',
    452    'target': '../testvectors/hmac-sha256-vectors.h',
    453    'array_init': 'const HmacTestVector kHmacSha256WycheproofVectors[] = {\n',
    454    'formatter' : HMAC(),
    455    'crop_size_end': -3,
    456    'section': 'hmac_sha256_vectors_h__',
    457    'comment' : ''
    458 }
    459 
    460 hmac_sha384_params = {
    461    'source_dir': 'source_vectors/',
    462    'source_file': 'hmac_sha384_test.json',
    463    'target': '../testvectors/hmac-sha384-vectors.h',
    464    'array_init': 'const HmacTestVector kHmacSha384WycheproofVectors[] = {\n',
    465    'formatter' : HMAC(),
    466    'crop_size_end': -3,
    467    'section': 'hmac_sha384_vectors_h__',
    468    'comment' : ''
    469 }
    470 
    471 hmac_sha512_params = {
    472    'source_dir': 'source_vectors/',
    473    'source_file': 'hmac_sha512_test.json',
    474    'target': '../testvectors/hmac-sha512-vectors.h',
    475    'array_init': 'const HmacTestVector kHmacSha512WycheproofVectors[] = {\n',
    476    'formatter' : HMAC(),
    477    'crop_size_end': -3,
    478    'section': 'hmac_sha512_vectors_h__',
    479    'comment' : ''
    480 }
    481 
    482 hmac_sha3_224_params = {
    483    'source_dir': 'source_vectors/',
    484    'source_file': 'hmac_sha3_224_test.json',
    485    'target': '../testvectors/hmac-sha3-224-vectors.h',
    486    'array_init': 'const HmacTestVector kHmacSha3224WycheproofVectors[] = {\n',
    487    'formatter' : HMAC(),
    488    'crop_size_end': -3,
    489    'section': 'hmac_sha3_224_vectors_h__',
    490    'comment' : ''
    491 }
    492 
    493 hmac_sha3_256_params = {
    494    'source_dir': 'source_vectors/',
    495    'source_file': 'hmac_sha3_256_test.json',
    496    'target': '../testvectors/hmac-sha3-256-vectors.h',
    497    'array_init': 'const HmacTestVector kHmacSha3256WycheproofVectors[] = {\n',
    498    'formatter' : HMAC(),
    499    'crop_size_end': -3,
    500    'section': 'hmac_sha3_256_vectors_h__',
    501    'comment' : ''
    502 }
    503 
    504 hmac_sha3_384_params = {
    505    'source_dir': 'source_vectors/',
    506    'source_file': 'hmac_sha3_384_test.json',
    507    'target': '../testvectors/hmac-sha3-384-vectors.h',
    508    'array_init': 'const HmacTestVector kHmacSha3384WycheproofVectors[] = {\n',
    509    'formatter' : HMAC(),
    510    'crop_size_end': -3,
    511    'section': 'hmac_sha3_384_vectors_h__',
    512    'comment' : ''
    513 }
    514 
    515 hmac_sha3_512_params = {
    516    'source_dir': 'source_vectors/',
    517    'source_file': 'hmac_sha3_512_test.json',
    518    'target': '../testvectors/hmac-sha3-512-vectors.h',
    519    'array_init': 'const HmacTestVector kHmacSha3512WycheproofVectors[] = {\n',
    520    'formatter' : HMAC(),
    521    'crop_size_end': -3,
    522    'section': 'hmac_sha3_512_vectors_h__',
    523    'comment' : ''
    524 }
    525 
    526 def update_tests(tests):
    527 
    528    remote = "https://raw.githubusercontent.com/google/wycheproof/master/testvectors/"
    529    for test in tests:
    530        subprocess.check_call(['wget', remote+test['source_file'], '-O',
    531                               'gtests/common/wycheproof/source_vectors/' +test['source_file']])
    532 
    533 def generate_test_vectors():
    534    """Generate C-header files for all supported tests."""
    535    all_tests = [aes_cbc_params,
    536                 aes_cmac_params,
    537                 aes_gcm_params,
    538                 chacha_poly_params,
    539                 dsa_params,
    540                 hkdf_sha1_params,
    541                 hkdf_sha256_params,
    542                 hkdf_sha384_params,
    543                 hkdf_sha512_params,
    544                 rsa_oaep_2048_sha1_mgf1sha1_params,
    545                 rsa_oaep_2048_sha256_mgf1sha1_params,
    546                 rsa_oaep_2048_sha256_mgf1sha256_params,
    547                 rsa_oaep_2048_sha384_mgf1sha1_params,
    548                 rsa_oaep_2048_sha384_mgf1sha384_params,
    549                 rsa_oaep_2048_sha512_mgf1sha1_params,
    550                 rsa_oaep_2048_sha512_mgf1sha512_params,
    551                 hmac_sha256_params,
    552                 hmac_sha384_params,
    553                 hmac_sha512_params,
    554                 hmac_sha3_224_params,
    555                 hmac_sha3_256_params,
    556                 hmac_sha3_384_params,
    557                 hmac_sha3_512_params]
    558    update_tests(all_tests)
    559    for test in all_tests:
    560        generate_vectors_file(test)
    561 
    562 def main():
    563    generate_test_vectors()
    564 
    565 if __name__ == '__main__':
    566    main()