Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/rsa/core.py: 75%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

44 statements  

1# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# https://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Core mathematical operations. 

16 

17This is the actual core RSA implementation, which is only defined 

18mathematically on integers. 

19""" 

20import itertools 

21import typing 

22 

23 

24def assert_int(var: int, name: str) -> None: 

25 if isinstance(var, int): 

26 return 

27 

28 raise TypeError("{} should be an integer, not {}".format(name, var.__class__)) 

29 

30 

31def encrypt_int(message: int, ekey: int, n: int) -> int: 

32 """Encrypts a message using encryption key 'ekey', working modulo n""" 

33 

34 assert_int(message, "message") 

35 assert_int(ekey, "ekey") 

36 assert_int(n, "n") 

37 

38 if message < 0: 

39 raise ValueError("Only non-negative numbers are supported") 

40 

41 if message >= n: 

42 raise OverflowError("The message %i is too long for n=%i" % (message, n)) 

43 

44 return pow(message, ekey, n) 

45 

46 

47def decrypt_int(cyphertext: int, dkey: int, n: int) -> int: 

48 """Decrypts a cypher text using the decryption key 'dkey', working modulo n""" 

49 

50 assert_int(cyphertext, "cyphertext") 

51 assert_int(dkey, "dkey") 

52 assert_int(n, "n") 

53 

54 message = pow(cyphertext, dkey, n) 

55 return message 

56 

57 

58def decrypt_int_fast( 

59 cyphertext: int, 

60 rs: typing.List[int], 

61 ds: typing.List[int], 

62 ts: typing.List[int], 

63) -> int: 

64 """Decrypts a cypher text more quickly using the Chinese Remainder Theorem.""" 

65 

66 assert_int(cyphertext, "cyphertext") 

67 for r in rs: 

68 assert_int(r, "r") 

69 for d in ds: 

70 assert_int(d, "d") 

71 for t in ts: 

72 assert_int(t, "t") 

73 

74 p, q, rs = rs[0], rs[1], rs[2:] 

75 exp1, exp2, ds = ds[0], ds[1], ds[2:] 

76 coef, ts = ts[0], ts[1:] 

77 

78 M1 = pow(cyphertext, exp1, p) 

79 M2 = pow(cyphertext, exp2, q) 

80 h = ((M1 - M2) * coef) % p 

81 m = M2 + q * h 

82 

83 Ms = [pow(cyphertext, d, r) for d, r in zip(ds, rs)] 

84 Rs = list(itertools.accumulate([p, q] + rs, lambda x, y: x*y)) 

85 for R, r, M, t in zip(Rs[1:], rs, Ms, ts): 

86 h = ((M - m) * t) % r 

87 m += R * h 

88 

89 return m