/usr/share/pyshared/Crypto/PublicKey/DSA.py is in python-crypto 2.4.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191  | # -*- coding: utf-8 -*-
#
#  PublicKey/DSA.py : DSA signature primitive
#
# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net>
#
# ===================================================================
# The contents of this file are dedicated to the public domain.  To
# the extent that dedication to the public domain is not available,
# everyone is granted a worldwide, perpetual, royalty-free,
# non-exclusive license to exercise all rights associated with the
# contents of this file for any purpose whatsoever.
# No rights are reserved.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# ===================================================================
"""DSA public-key signature algorithm."""
__revision__ = "$Id$"
__all__ = ['generate', 'construct', 'error']
import sys
if sys.version_info[0] == 2 and sys.version_info[1] == 1:
    from Crypto.Util.py21compat import *
from Crypto.PublicKey import _DSA, _slowmath, pubkey
from Crypto import Random
try:
    from Crypto.PublicKey import _fastmath
except ImportError:
    _fastmath = None
class _DSAobj(pubkey.pubkey):
    keydata = ['y', 'g', 'p', 'q', 'x']
    def __init__(self, implementation, key):
        self.implementation = implementation
        self.key = key
    def __getattr__(self, attrname):
        if attrname in self.keydata:
            # For backward compatibility, allow the user to get (not set) the
            # DSA key parameters directly from this object.
            return getattr(self.key, attrname)
        else:
            raise AttributeError("%s object has no %r attribute" % (self.__class__.__name__, attrname,))
    def _encrypt(self, c, K):
        raise TypeError("DSA cannot encrypt")
    def _decrypt(self, c):
        raise TypeError("DSA cannot decrypt")
    def _blind(self, m, r):
        raise TypeError("DSA cannot blind")
    def _unblind(self, m, r):
        raise TypeError("DSA cannot unblind")
    def _sign(self, m, k):
        return self.key._sign(m, k)
    def _verify(self, m, sig):
        (r, s) = sig
        return self.key._verify(m, r, s)
    def has_private(self):
        return self.key.has_private()
    def size(self):
        return self.key.size()
    def can_blind(self):
        return False
    def can_encrypt(self):
        return False
    def can_sign(self):
        return True
    def publickey(self):
        return self.implementation.construct((self.key.y, self.key.g, self.key.p, self.key.q))
    def __getstate__(self):
        d = {}
        for k in self.keydata:
            try:
                d[k] = getattr(self.key, k)
            except AttributeError:
                pass
        return d
    def __setstate__(self, d):
        if not hasattr(self, 'implementation'):
            self.implementation = DSAImplementation()
        t = []
        for k in self.keydata:
            if not d.has_key(k):
                break
            t.append(d[k])
        self.key = self.implementation._math.dsa_construct(*tuple(t))
    def __repr__(self):
        attrs = []
        for k in self.keydata:
            if k == 'p':
                attrs.append("p(%d)" % (self.size()+1,))
            elif hasattr(self.key, k):
                attrs.append(k)
        if self.has_private():
            attrs.append("private")
        # PY3K: This is meant to be text, do not change to bytes (data)
        return "<%s @0x%x %s>" % (self.__class__.__name__, id(self), ",".join(attrs))
class DSAImplementation(object):
    def __init__(self, **kwargs):
        # 'use_fast_math' parameter:
        #   None (default) - Use fast math if available; Use slow math if not.
        #   True - Use fast math, and raise RuntimeError if it's not available.
        #   False - Use slow math.
        use_fast_math = kwargs.get('use_fast_math', None)
        if use_fast_math is None:   # Automatic
            if _fastmath is not None:
                self._math = _fastmath
            else:
                self._math = _slowmath
        elif use_fast_math:     # Explicitly select fast math
            if _fastmath is not None:
                self._math = _fastmath
            else:
                raise RuntimeError("fast math module not available")
        else:   # Explicitly select slow math
            self._math = _slowmath
        self.error = self._math.error
        # 'default_randfunc' parameter:
        #   None (default) - use Random.new().read
        #   not None       - use the specified function
        self._default_randfunc = kwargs.get('default_randfunc', None)
        self._current_randfunc = None
    def _get_randfunc(self, randfunc):
        if randfunc is not None:
            return randfunc
        elif self._current_randfunc is None:
            self._current_randfunc = Random.new().read
        return self._current_randfunc
    def generate(self, bits, randfunc=None, progress_func=None):
        # Check against FIPS 186-2, which says that the size of the prime p
        # must be a multiple of 64 bits between 512 and 1024
        for i in (0, 1, 2, 3, 4, 5, 6, 7, 8):
            if bits == 512 + 64*i:
                return self._generate(bits, randfunc, progress_func)
        # The March 2006 draft of FIPS 186-3 also allows 2048 and 3072-bit
        # primes, but only with longer q values.  Since the current DSA
        # implementation only supports a 160-bit q, we don't support larger
        # values.
        raise ValueError("Number of bits in p must be a multiple of 64 between 512 and 1024, not %d bits" % (bits,))
    def _generate(self, bits, randfunc=None, progress_func=None):
        rf = self._get_randfunc(randfunc)
        obj = _DSA.generate_py(bits, rf, progress_func)    # TODO: Don't use legacy _DSA module
        key = self._math.dsa_construct(obj.y, obj.g, obj.p, obj.q, obj.x)
        return _DSAobj(self, key)
    def construct(self, tup):
        key = self._math.dsa_construct(*tup)
        return _DSAobj(self, key)
_impl = DSAImplementation()
generate = _impl.generate
construct = _impl.construct
error = _impl.error
# vim:set ts=4 sw=4 sts=4 expandtab:
 |