Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  genNISTTestVector.py

  Sprache: Python
 

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

import json
import os
import subprocess
import hashlib

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
import binascii

script_dir = os.path.dirname(os.path.abspath(__file__))

# Imports a JSON testvector file.
def import_testvector(file):
    """Import a JSON testvector file and return an array of the contained objects."""
    with open(file) as f:
        vectors = json.loads(f.read())
    return vectors

# Convert a test data string to a hex array.
def string_to_hex(string):
    """Convert a string of hex chars to a string representing a C-format array of hex bytes."""
    b = bytearray.fromhex(string)
    result = ', '.join("{:#04x}".format(x) for x in b)
    return result

def digest(string):
    b = bytearray.fromhex(string)
    h = hashlib.sha3_256()
    h.update(b)
    return h.hexdigest()

#now split them into readable lines
def string_line_split(string, group_len, count, spaces):
    result=''
    lstring = string;
    while (len(lstring) > count*group_len):
        result += lstring[:count*group_len].rjust(spaces);
        result += '\n'
        lstring=lstring[count*group_len:];
    result += lstring.rjust(spaces)
    return result

# put it together
def string_to_hex_array(string):
    result="{\n"
    result += string_line_split(' '+string_to_hex(string), 6124)
    result += '}'
    return result


mldsa_spki={
    "ML-DSA-44""30820532300b06096086480165030403110382052100",
    "ML-DSA-65""308207b2300b0609608648016503040312038207a100",
    "ML-DSA-87""30820a32300b060960864801650304031303820a2100",
}

mldsa_p11param={
    "ML-DSA-44""CKP_ML_DSA_44",
    "ML-DSA-65""CKP_ML_DSA_65",
    "ML-DSA-87""CKP_ML_DSA_87",
}

class MLDSA_VERIFY():
    key_name=''
    has_name=False
    def init_global(self, group, group_result, out_defs):
        paramSet= group['parameterSet']
        self.paramSet=paramSet
        if not paramSet in mldsa_spki:
            return False
        if 'pk' in group:
            rawkey= group['pk']
            paramSet= group['parameterSet']
            key_name = "kPubKey"+str(group['tgId'])
            key=mldsa_spki[paramSet]+rawkey
            out_defs.append('// Key Type'+paramSet+'\n')
            out_defs.append('static const std::vector<uint8_t> ' + key_name + string_to_hex_array(key) + ';\n\n')
            self.key_name=key_name
            self.has_name=True
            return True
        self.has_name=False
        # only fetch the test types that we support: external
        # pure, and externalMu == false.
        # we can adjust these when we and externalMu support and
        # MLDSA Hash support (if we ever do)
        if 'signatureInterface' in group:
            if group['signatureInterface'] != "external":
                return False
        if 'preHash' in group:
            if group['preHash'] != "pure":
                return False
        if 'externalMu' in group:
            if group['externalMu']:
                return False
        return True
    def format_testcase(self, testcase, testcase_result, out_defs):
        key=mldsa_spki[self.paramSet]+testcase['pk']
        result = '\n// {}\n'.format(self.paramSet)
        result = '// tcID: {}\n'.format(testcase['tcId'])
        result += '{{{},\n'.format(testcase['tcId'])
        result += '// signature\n{},\n'.format(string_to_hex_array(testcase['signature']))
        if self.has_name:
            result += '{},\n'.format(self.key_name)
        else:
            result += '// pubkey\n{},\n'.format(string_to_hex_array(key))
        if 'context' in testcase:
            result += '// context\n{},\n'.format(string_to_hex_array(testcase['context']))
        else:
            result += '// context\n{{}},\n'
        result += '// message\n{},\n'.format(string_to_hex_array(testcase['message']))
        result += '{}}},\n'.format(str(testcase_result['testPassed']).lower())
        display = 'tcID {}: {} '.format(testcase['tcId'],self.paramSet)
        display += 'key({}) message({}) '.format(len(key)/2,len(testcase['message'])/2)
        display += 'signature({}) ctx({}) '.format(len(testcase['signature'])/2,len(testcase['context'])/2,)
        display += '{}'.format(testcase_result['testPassed'])
        print(display)
        return result

class MLDSA_KEYGEN():
    def init_global(self, group, group_result, out_defs):
        paramSet= group['parameterSet']
        self.paramSet = paramSet
        return paramSet in mldsa_p11param
    def format_testcase(self, testcase, testcase_result, out_defs):
        seed=testcase['seed']
        pubk=testcase_result['pk']
        privk=testcase_result['sk']
        result = '\n// {}\n'.format(self.paramSet)
        result = '// tcID: {}\n'.format(testcase['tcId'])
        result += '{{{},\n'.format(testcase['tcId'])
        result += '{},\n'.format(mldsa_p11param[self.paramSet])
        result += '//seed\n{},\n'.format(string_to_hex_array(seed))
        result += '//raw pubkey\n{},\n'.format(string_to_hex_array(pubk))
        result += '//raw privkey\n{}}},\n'.format(string_to_hex_array(privk))
        display = 'tcID {}: {} '.format(testcase['tcId'],self.paramSet)
        display += 'seed({}) pubk({}) '.format(len(seed)/2,len(pubk)/2)
        display += 'privk({})'.format(len(privk)/2)
        print(display)
        return result

mlkem_freebl_param={
    "ML-KEM-768""params_ml_kem768",
    "ML-KEM-1024""params_ml_kem1024",
}

mlkem_freebl_test_param={
    "ML-KEM-768""params_ml_kem768_test_mode",
    "ML-KEM-1024""params_ml_kem1024_test_mode",
}

mlkem_prefix={
    "ML-KEM-768""MlKem768",
    "ML-KEM-1024""MlKem1024",
}

class MLKEM_KEYGEN():
    def init_global(self, group, group_result, out_defs):
        paramSet= group['parameterSet']
        self.paramSet = paramSet
        return paramSet in mlkem_freebl_param
    def format_testcase(self, testcase, testcase_result, out_defs):
        seed=testcase['d']+testcase['z']
        pubk=testcase_result['ek']
        privk=testcase_result['dk']
        pubkDigest=digest(pubk)
        privkDigest=digest(privk)
        result = '\n// {}\n'.format(self.paramSet)
        result = '// tcID: {}\n'.format(testcase['tcId'])
        result += '{{{},\n'.format(testcase['tcId'])
        result += '{},\n'.format(mlkem_freebl_param[self.paramSet])
        result += '//seed\n{},\n'.format(string_to_hex_array(seed))
        result += '//publicKeyDigest\n{},\n'.format(string_to_hex_array(pubkDigest))
        result += '//privateKeyDigest\n{}}},\n'.format(string_to_hex_array(privkDigest))
        display = 'tcID {}: {} '.format(testcase['tcId'],self.paramSet)
        display += 'seed({}) pubk({}) '.format(len(seed)/2,len(pubk)/2)
        display += 'privk({})'.format(len(privk)/2)
        print(display)
        return result

class MLKEM_ENCAP():
    key_name=''
    has_name=False
    def init_global(self, group, group_result, out_defs):
        paramSet= group['parameterSet']
        self.paramSet=paramSet
        if not paramSet in mlkem_freebl_test_param:
            return False
        if  group['function'] != 'encapsulation':
            return False
        return True
    def format_testcase(self, testcase, testcase_result, out_defs):
        key=testcase['ek']
        result = '\n// {}\n'.format(self.paramSet)
        result = '// tcID: {}\n'.format(testcase['tcId'])
        result += '{{{},\n'.format(testcase['tcId'])
        result += '{},\n'.format(mlkem_freebl_test_param[self.paramSet])
        result += '// entropy\n{},\n'.format(string_to_hex_array(testcase['m']))
        result += '// publicKey\n{},\n'.format(string_to_hex_array(testcase['ek']))
        cipherTextDigest=digest(testcase_result['c'])
        result += '// cipherTextDigest\n{},\n'.format(string_to_hex_array(cipherTextDigest))
        result += '// secret\n{},\ntrue}},\n'.format(string_to_hex_array(testcase_result['k']))
        display = 'tcID {}: {} '.format(testcase['tcId'],self.paramSet)
        display += 'key({}) encapsulate'.format(len(key)/2)
        print(display)
        return result

class MLKEM_DECAP():
    key_name=''
    has_name=False
    def init_global(self, group, group_result, out_defs):
        paramSet= group['parameterSet']
        self.paramSet=paramSet
        if not paramSet in mlkem_freebl_test_param:
            return False
        if  group['function'] != 'decapsulation':
            return False
        return True
    def format_testcase(self, testcase, testcase_result, out_defs):
        result = '\n// {}\n'.format(self.paramSet)
        result = '// tcID: {}\n'.format(testcase['tcId'])
        result += '{{{},\n'.format(testcase['tcId'])
        result += '{},\n'.format(mlkem_freebl_test_param[self.paramSet])
        result += '// privateKey\n{},\n'.format(string_to_hex_array(testcase['dk']))
        result += '// ciphertext\n{},\n'.format(string_to_hex_array(testcase['c']))
        result += '// secret\n{},\ntrue}},\n'.format(string_to_hex_array(testcase_result['k']))
        display = 'tcID {}: {} decapsulate'.format(testcase['tcId'],self.paramSet)
        print(display)
        return result

def matchID(_id, source, target):
    for i in target:
        if i[_id] == source[_id]:
            return i
    return {}

def generate_vectors_file(params):
    """
    Generate and store a .h-file with test vectors for one test.

    params -- Dictionary with parameters for test vector generation for the desired test.
    """

    cases = import_testvector(os.path.join(script_dir, params['source_dir'] + params['prompt_file']))
    result = import_testvector(os.path.join(script_dir, params['source_dir'] + params['result_file']))

    base_vectors = ""
    if 'base' in params:
        with open(os.path.join(script_dir, params['base'])) as base:
            base_vectors = base.read()
        base_vectors += "\n\n"

    header = standard_params['license']
    header += "\n"
    header += standard_params['top_comment']
    header += "\n"
    header += "#ifndef " + params['section'] + "\n"
    header += "#define " + params['section'] + "\n"
    header += "\n"

    for include in standard_params['includes']:
        header += "#include " + include + "\n"

    header += "\n"

    if 'includes' in params:
        for include in params['includes']:
            header += "#include " + include + "\n"
        header += "\n"

    shared_defs = []
    vectors_file = base_vectors + params['array_init']

    for group in cases['testGroups']:
        group_result = matchID('tgId', group, result['testGroups']);
        if (not params['formatter'].init_global(group, group_result, shared_defs)):
            continue;
        for test in group['tests']:
            test_result = matchID('tcId', test, group_result['tests']);
            vectors_file += params['formatter'].format_testcase(test, test_result, shared_defs)

    vectors_file = vectors_file[:params['crop_size_end']] + '\n};\n\n'
    vectors_file += "#endif // " + params['section'] + '\n'

    with open(os.path.join(script_dir, params['target']), 'w'as target:
        target.write(header)
        for definition in shared_defs:
            target.write(definition)
        target.write(vectors_file)


standard_params = {
    'includes': ['"testvectors_base/test-structs.h"'],
    'license':
"""/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
 """,

    'top_comment':
"""/* This file is generated from sources in nss/gtests/common/wycheproof
 * automatically and should not be touched manually.
 * Generation is trigged by calling python3 genTestVectors.py */
 """
}

# Parameters that describe the generation of a testvector file for each supoorted test.
# source -- relative path to the wycheproof JSON source file with testvectors.
# base -- relative path to non-wycheproof vectors.
# target -- relative path to where the finished .h-file is written.
# array_init -- string to initialize the c-header style array of testvectors.
# formatter -- the test case formatter class to be used for this test.
# crop_size_end -- number of characters removed from the end of the last generated test vector to close the array definition.
# section -- name of the section
# comment -- additional comments to add to the file just before definition of the test vector array.

ml_dsa_verify_params = {
    'source_dir''source_vectors/',
    'test_name''ML-DSA-sigVer-FIPS204',
    'tag''v1.1.0.40',
    'prompt_file''ml_dsa_verify_prompt.json',
    'result_file''ml_dsa_verify_result.json',
    'target''../testvectors/ml-dsa-verify-vectors.h',
    'array_init''const MlDsaVerifyTestVector kMLDsaNISTVerifyVectors[] = {\n',
    'formatter' : MLDSA_VERIFY(),
    'crop_size_end': -2,
    'section''mldsa_verify_vectors_h__',
    'comment' : ''
}

ml_dsa_keygen_params = {
    'source_dir''source_vectors/',
    'test_name''ML-DSA-keyGen-FIPS204',
    'tag''v1.1.0.40',
    'prompt_file''ml_dsa_keygen_prompt.json',
    'result_file''ml_dsa_keygen_result.json',
    'target''../testvectors/ml-dsa-keygen-vectors.h',
    'array_init''const MlDsaKeyGenTestVector kMLDsaNISTKeyGenVectors[] = {\n',
    'formatter' : MLDSA_KEYGEN(),
    'crop_size_end': -2,
    'section''mldsa_keygen_vectors_h__',
    'comment' : ''
}

ml_kem_decap_params = {
    'source_dir''source_vectors/',
    'test_name''ML-KEM-encapDecap-FIPS203',
    'tag''v1.1.0.40',
    'prompt_file''ml_kem_encap_decap_prompt.json',
    'result_file''ml_kem_encap_decap_result.json',
    'target''../testvectors/ml-kem-decap-vectors.h',
    'array_init''const std::vector<MlKemDecapTestVector> MlKemDecapTests = {\n',
    'formatter' : MLKEM_DECAP(),
    'crop_size_end': -2,
    'section''mlkem_decap_vectors_h__',
    'comment' : ''
}

ml_kem_encap_params = {
    'source_dir''source_vectors/',
    'test_name''ML-KEM-encapDecap-FIPS203',
    'tag''v1.1.0.40',
    'prompt_file''ml_kem_encap_decap_prompt.json',
    'result_file''ml_kem_encap_decap_result.json',
    'target''../testvectors/ml-kem-encap-vectors.h',
    'array_init''const std::vector<MlKemEncapTestVector> MlKemEncapTests = {\n',
    'formatter' : MLKEM_ENCAP(),
    'crop_size_end': -2,
    'section''mlkem_encap_vectors_h__',
    'comment' : ''
}

ml_kem_keygen_params = {
    'source_dir''source_vectors/',
    'test_name''ML-KEM-keyGen-FIPS203',
    'tag''v1.1.0.40',
    'prompt_file''ml_kem_keygen_prompt.json',
    'result_file''ml_kem_keygen_result.json',
    'target''../testvectors/ml-kem-keygen-vectors.h',
    'array_init''const std::vector<MlKemKeyGenTestVector> MlKemKeyGenTests = {\n',
    'formatter' : MLKEM_KEYGEN(),
    'crop_size_end': -2,
    'section''mlkem_keygen_vectors_h__',
    'comment' : ''
}


def update_tests(tests):

    remote_base = "https://raw.githubusercontent.com/usnistgov/ACVP-Server/refs/tags/"
    for test in tests:
        remote = remote_base+test['tag']+"/gen-val/json-files/"+test['test_name']+"/"
        subprocess.check_call(['wget', remote+"/prompt.json"'-O',
                               script_dir+'/'+test['source_dir']+test['prompt_file']])
        subprocess.check_call(['wget', remote+"/expectedResults.json"'-O',
                               script_dir+'/'+test['source_dir']+test['result_file']])

def generate_test_vectors():
    """Generate C-header files for all supported tests."""
    all_tests = [ ml_kem_keygen_params, ml_kem_encap_params, ml_kem_decap_params ]
#all_tests = [ml_kem_keygen_params, ml_kem_encap_params, ml_kem_decap_params ]
    update_tests(all_tests)
    for test in all_tests:
        generate_vectors_file(test)

def main():
    generate_test_vectors()

if __name__ == '__main__':
    main()

Messung V0.5 in Prozent
C=81 H=99 G=90

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002