Package common :: Module crypto
[hide private]
[frames] | no frames]

Source Code for Module common.crypto

  1  # common crypto functions (mostly specific to XEP-0116, but useful elsewhere) 
  2  # -*- coding:utf-8 -*- 
  3  ## src/common/crypto.py 
  4  ## 
  5  ## Copyright (C) 2007 Brendan Taylor <whateley AT gmail.com> 
  6  ## 
  7  ## This file is part of Gajim. 
  8  ## 
  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. 
 12  ## 
 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. 
 17  ## 
 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/>. 
 20  ## 
 21   
 22  import os 
 23  import math 
 24   
 25  from hashlib import sha256 as SHA256 
 26   
 27  # convert a large integer to a big-endian bitstring 
28 -def encode_mpi(n):
29 if n >= 256: 30 return encode_mpi(n / 256) + chr(n % 256) 31 else: 32 return chr(n)
33 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)
38 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 43 if mod == 0: 44 return string 45 else: 46 padding = (multiple_of - mod) * char 47 48 if left: 49 return padding + string 50 else: 51 return string + padding
52 53 # convert a big-endian bitstring to an integer
54 -def decode_mpi(s):
55 if len(s) == 0: 56 return 0 57 else: 58 return 256 * decode_mpi(s[:-1]) + ord(s[-1])
59
60 -def sha256(string):
61 sh = SHA256() 62 sh.update(string) 63 return sh.digest()
64 65 base28_chr = "acdefghikmopqruvwxy123456789" 66
67 -def sas_28x5(m_a, form_b):
68 sha = sha256(m_a + form_b + 'Short Authentication String') 69 lsb24 = decode_mpi(sha[-3:]) 70 return base28(lsb24)
71
72 -def base28(n):
73 if n >= 28: 74 return base28(n / 28) + base28_chr[n % 28] 75 else: 76 return base28_chr[n]
77
78 -def random_bytes(bytes_):
79 return os.urandom(bytes_)
80
81 -def generate_nonce():
82 return random_bytes(8)
83 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))) 88 89 # in retrospect, this is horribly inadequate. 90 return (decode_mpi(random_bytes(bytes)) % (top - bottom)) + bottom
91 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):
95 square = base % mod 96 result = 1 97 98 while exp > 0: 99 if exp & 1: # exponent is odd 100 result = (result * square) % mod 101 102 square = (square * square) % mod 103 exp /= 2 104 105 return result
106