/ adafruit_rsa / _compat.py
_compat.py
1 # -*- coding: utf-8 -*- 2 # 3 # Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # https://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 """Python compatibility wrappers.""" 18 19 import sys 20 from struct import pack 21 22 __version__ = "0.0.0-auto.0" 23 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_RSA.git" 24 25 MAX_INT = sys.maxsize 26 MAX_INT64 = (1 << 63) - 1 27 MAX_INT32 = (1 << 31) - 1 28 MAX_INT16 = (1 << 15) - 1 29 30 # Determine the word size of the processor. 31 if MAX_INT == MAX_INT64: 32 # 64-bit processor. 33 MACHINE_WORD_SIZE = 64 34 elif MAX_INT == MAX_INT32: 35 # 32-bit processor. 36 MACHINE_WORD_SIZE = 32 37 else: 38 # Else we just assume 64-bit processor keeping up with modern times. 39 MACHINE_WORD_SIZE = 64 40 41 42 INTEGER_TYPES = (int,) 43 44 45 def write_to_stdout(data): 46 """Writes bytes to stdout 47 48 :type data: bytes 49 """ 50 # On Py3 we must use the buffer interface to write bytes. 51 sys.stdout.buffer.write(data) 52 53 54 def is_bytes(obj): 55 """ 56 Determines whether the given value is a byte string. 57 58 :param obj: 59 The value to test. 60 :returns: 61 ``True`` if ``value`` is a byte string; ``False`` otherwise. 62 """ 63 return isinstance(obj, bytes) 64 65 66 def is_integer(obj): 67 """ 68 Determines whether the given value is an integer. 69 70 :param obj: 71 The value to test. 72 :returns: 73 ``True`` if ``value`` is an integer; ``False`` otherwise. 74 """ 75 return isinstance(obj, INTEGER_TYPES) 76 77 78 def byte(num): 79 """ 80 Converts a number between 0 and 255 (both inclusive) to a base-256 (byte) 81 representation. 82 83 Use it as a replacement for ``chr`` where you are expecting a byte 84 because this will work on all current versions of Python:: 85 86 :param num: 87 An unsigned integer between 0 and 255 (both inclusive). 88 :returns: 89 A single byte. 90 """ 91 return pack("B", num) 92 93 94 def xor_bytes(bytes_1, bytes_2): 95 """ 96 Returns the bitwise XOR result between two bytes objects, bytes_1 ^ bytes_2. 97 98 Bitwise XOR operation is commutative, so order of parameters doesn't 99 generate different results. If parameters have different length, extra 100 length of the largest one is ignored. 101 102 :param bytes_1: 103 First bytes object. 104 :param bytes_2: 105 Second bytes object. 106 :returns: 107 Bytes object, result of XOR operation. 108 """ 109 return bytes(x ^ y for x, y in zip(bytes_1, bytes_2)) 110 111 112 def get_word_alignment(num, force_arch=64, _machine_word_size=MACHINE_WORD_SIZE): 113 """ 114 Returns alignment details for the given number based on the platform 115 Python is running on. 116 117 :param num: 118 Unsigned integral number. 119 :param force_arch: 120 If you don't want to use 64-bit unsigned chunks, set this to 121 anything other than 64. 32-bit chunks will be preferred then. 122 Default 64 will be used when on a 64-bit machine. 123 :param _machine_word_size: 124 (Internal) The machine word size used for alignment. 125 :returns: 126 4-tuple:: 127 128 (word_bits, word_bytes, 129 max_uint, packing_format_type) 130 """ 131 max_uint64 = 0xFFFFFFFFFFFFFFFF 132 max_uint32 = 0xFFFFFFFF 133 max_uint16 = 0xFFFF 134 max_uint8 = 0xFF 135 136 if force_arch == 64 and _machine_word_size >= 64 and num > max_uint32: 137 # 64-bit unsigned integer. 138 return 64, 8, max_uint64, "Q" 139 if num > max_uint16: 140 # 32-bit unsigned integer 141 return 32, 4, max_uint32, "L" 142 if num > max_uint8: 143 # 16-bit unsigned integer. 144 return 16, 2, max_uint16, "H" 145 # 8-bit unsigned integer. 146 return 8, 1, max_uint8, "B"