11import base64
2+ import binascii
3+
4+ try :
5+ from cryptography .hazmat .primitives .asymmetric .utils import (
6+ decode_rfc6979_signature , encode_rfc6979_signature
7+ )
8+ except ImportError :
9+ pass
210
311
412def base64url_decode (input ):
@@ -25,3 +33,35 @@ def merge_dict(original, updates):
2533 raise TypeError ('original and updates must be a dictionary: %s' % e )
2634
2735 return merged_options
36+
37+
38+ def number_to_bytes (num , num_bytes ):
39+ padded_hex = '%0*x' % (2 * num_bytes , num )
40+ big_endian = binascii .a2b_hex (padded_hex .encode ('ascii' ))
41+ return big_endian
42+
43+
44+ def bytes_to_number (string ):
45+ return int (binascii .b2a_hex (string ), 16 )
46+
47+
48+ def der_to_raw_signature (der_sig , curve ):
49+ num_bits = curve .key_size
50+ num_bytes = (num_bits + 7 ) / 8
51+
52+ r , s = decode_rfc6979_signature (der_sig )
53+
54+ return number_to_bytes (r , num_bytes ) + number_to_bytes (s , num_bytes )
55+
56+
57+ def raw_to_der_signature (raw_sig , curve ):
58+ num_bits = curve .key_size
59+ num_bytes = (num_bits + 7 ) / 8
60+
61+ if len (raw_sig ) != 2 * num_bytes :
62+ raise ValueError ('Invalid signature' )
63+
64+ r = bytes_to_number (raw_sig [:num_bytes ])
65+ s = bytes_to_number (raw_sig [num_bytes :])
66+
67+ return encode_rfc6979_signature (r , s )
0 commit comments