1from __future__ import absolute_import, print_function 2 3import hashlib 4import os 5from binascii import hexlify 6from collections import defaultdict 7 8from ecdsa import SECP256k1, SigningKey 9from ecdsa.util import sigdecode_der, sigencode_der 10 11from cryptography_vectors import open_vector_file 12 13from tests.utils import ( 14 load_fips_ecdsa_signing_vectors, load_vectors_from_file 15) 16 17HASHLIB_HASH_TYPES = { 18 "SHA-1": hashlib.sha1, 19 "SHA-224": hashlib.sha224, 20 "SHA-256": hashlib.sha256, 21 "SHA-384": hashlib.sha384, 22 "SHA-512": hashlib.sha512, 23} 24 25 26class TruncatedHash(object): 27 def __init__(self, hasher): 28 self.hasher = hasher 29 30 def __call__(self, data): 31 self.hasher.update(data) 32 return self 33 34 def digest(self): 35 return self.hasher.digest()[:256 // 8] 36 37 38def build_vectors(fips_vectors): 39 vectors = defaultdict(list) 40 for vector in fips_vectors: 41 vectors[vector['digest_algorithm']].append(vector['message']) 42 43 for digest_algorithm, messages in vectors.items(): 44 if digest_algorithm not in HASHLIB_HASH_TYPES: 45 continue 46 47 yield "" 48 yield "[K-256,{0}]".format(digest_algorithm) 49 yield "" 50 51 for message in messages: 52 # Make a hash context 53 hash_func = TruncatedHash(HASHLIB_HASH_TYPES[digest_algorithm]()) 54 55 # Sign the message using warner/ecdsa 56 secret_key = SigningKey.generate(curve=SECP256k1) 57 public_key = secret_key.get_verifying_key() 58 signature = secret_key.sign(message, hashfunc=hash_func, 59 sigencode=sigencode_der) 60 61 r, s = sigdecode_der(signature, None) 62 63 yield "Msg = {0}".format(hexlify(message)) 64 yield "d = {0:x}".format(secret_key.privkey.secret_multiplier) 65 yield "Qx = {0:x}".format(public_key.pubkey.point.x()) 66 yield "Qy = {0:x}".format(public_key.pubkey.point.y()) 67 yield "R = {0:x}".format(r) 68 yield "S = {0:x}".format(s) 69 yield "" 70 71 72def write_file(lines, dest): 73 for line in lines: 74 print(line) 75 print(line, file=dest) 76 77 78source_path = os.path.join("asymmetric", "ECDSA", "FIPS_186-3", "SigGen.txt") 79dest_path = os.path.join("asymmetric", "ECDSA", "SECP256K1", "SigGen.txt") 80 81fips_vectors = load_vectors_from_file( 82 source_path, 83 load_fips_ecdsa_signing_vectors 84) 85 86with open_vector_file(dest_path, "w") as dest_file: 87 write_file( 88 build_vectors(fips_vectors), 89 dest_file 90 ) 91