/ adafruit_rsa / core.py
core.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 """Core mathematical operations. 18 19 This is the actual core RSA implementation, which is only defined 20 mathematically on integers. 21 """ 22 23 # pylint: disable=invalid-name 24 from adafruit_rsa._compat import is_integer 25 26 __version__ = "0.0.0-auto.0" 27 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_RSA.git" 28 29 30 def fast_pow(x, e, m): 31 """Performs fast modular exponentiation, saves RAM on small CPUs/micros. 32 :param int x: Base 33 :param int y: Exponent 34 :param int e: Second exponent 35 """ 36 X = x 37 E = e 38 Y = 1 39 while E > 0: 40 if E % 2 == 0: 41 X = (X * X) % m 42 E = E // 2 43 else: 44 Y = (X * Y) % m 45 E = E - 1 46 return Y 47 48 49 def assert_int(var, name): 50 """Asserts provided variable is an integer.""" 51 if is_integer(var): 52 return 53 54 raise TypeError("%s should be an integer, not %s" % (name, var.__class__)) 55 56 57 def encrypt_int(message, ekey, n): 58 """Encrypts a message using encryption key 'ekey', working modulo n""" 59 60 assert_int(message, "message") 61 assert_int(ekey, "ekey") 62 assert_int(n, "n") 63 64 if message < 0: 65 raise ValueError("Only non-negative numbers are supported") 66 67 if message > n: 68 raise OverflowError("The message %i is too long for n=%i" % (message, n)) 69 70 # return pow(message, ekey, n) 71 # print('fast_pow({},{},{})'.format(message,ekey,n)) 72 return fast_pow(message, ekey, n) 73 74 75 def decrypt_int(cyphertext, dkey, n): 76 """Decrypts a cypher text using the decryption key 'dkey', working modulo n""" 77 78 assert_int(cyphertext, "cyphertext") 79 assert_int(dkey, "dkey") 80 assert_int(n, "n") 81 82 message = fast_pow(cyphertext, dkey, n) 83 return message