1 # common crypto functions (mostly specific to XEP-0116, but useful elsewhere)
3 ## src/common/crypto.py
5 ## Copyright (C) 2007 Brendan Taylor <whateley AT gmail.com>
7 ## This file is part of Gajim.
9 ## Gajim is free software; you can redistribute it and/or modify
10 ## it under the terms of the GNU General Public License as published
11 ## by the Free Software Foundation; version 3 only.
13 ## Gajim is distributed in the hope that it will be useful,
14 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ## GNU General Public License for more details.
18 ## You should have received a copy of the GNU General Public License
19 ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
25 from hashlib
import sha256
as SHA256
27 # convert a large integer to a big-endian bitstring
30 return encode_mpi(n
/ 256) + chr(n
% 256)
34 # convert a large integer to a big-endian bitstring, padded with \x00s to
35 # a multiple of 16 bytes
36 def encode_mpi_with_padding(n
):
37 return pad_to_multiple(encode_mpi(n
), 16, '\x00', True)
39 # pad 'string' to a multiple of 'multiple_of' with 'char'.
40 # pad on the left if 'left', otherwise pad on the right.
41 def pad_to_multiple(string
, multiple_of
, char
, left
):
42 mod
= len(string
) % multiple_of
46 padding
= (multiple_of
- mod
) * char
49 return padding
+ string
51 return string
+ padding
53 # convert a big-endian bitstring to an integer
58 return 256 * decode_mpi(s
[:-1]) + ord(s
[-1])
65 base28_chr
= "acdefghikmopqruvwxy123456789"
67 def sas_28x5(m_a
, form_b
):
68 sha
= sha256(m_a
+ form_b
+ 'Short Authentication String')
69 lsb24
= decode_mpi(sha
[-3:])
74 return base28(n
/ 28) + base28_chr
[n
% 28]
78 def random_bytes(bytes_
):
79 return os
.urandom(bytes_
)
82 return random_bytes(8)
84 # generate a random number between 'bottom' and 'top'
85 def srand(bottom
, top
):
86 # minimum number of bytes needed to represent that range
87 bytes
= int(math
.ceil(math
.log(top
- bottom
, 256)))
89 # in retrospect, this is horribly inadequate.
90 return (decode_mpi(random_bytes(bytes
)) % (top
- bottom
)) + bottom
92 # a faster version of (base ** exp) % mod
93 # taken from <http://lists.danga.com/pipermail/yadis/2005-September/001445.html>
94 def powmod(base
, exp
, mod
):
99 if exp
& 1: # exponent is odd
100 result
= (result
* square
) % mod
102 square
= (square
* square
) % mod