<commit_before># vim: set syntax=pyrex
<%!

key_parts = 'e d N p q qP dP dQ'.split()

%>

from tomcrypt._core cimport *
from tomcrypt import Error
from tomcrypt.prng cimport conform_prng
from tomcrypt.hash cimport conform_hash, Descriptor as HashDescriptor
from tomcrypt.prng cimport PRNG

import re
import base64
from math import ceil


TYPE_PRIVATE = 'private'
TYPE_PUBLIC  = 'public'

cdef object type_map = {
    TYPE_PRIVATE: c_RSA_TYPE_PRIVATE,
    TYPE_PUBLIC : c_RSA_TYPE_PUBLIC,
}


cdef c_RSA_PAD_NONE = 0
PAD_NONE = 'none'
PAD_V1_5 = 'v1.5'
PAD_OAEP = 'oaep'
PAD_PSS  = 'pss'

cdef object padding_map = {
    PAD_NONE: c_RSA_PAD_NONE,
    PAD_V1_5: c_RSA_PAD_V1_5,
    PAD_OAEP: c_RSA_PAD_OAEP,
    PAD_PSS : c_RSA_PAD_PSS,
}


FORMAT_PEM = 'pem'
FORMAT_DER = 'der'


DEFAULT_ENC_HASH = 'sha1'
DEFAULT_SIG_HASH = 'sha512'

DEFAULT_SIZE = 2048
DEFAULT_E = 65537



cdef int conform_padding(padding) except -1:
    """Turn a user supplied padding constant into the C variant."""
    if isinstance(padding, basestring):
        padding = padding.lower()
    if padding not in padding_map:
        raise Error('unknown RSA padding %r' % padding)
    return padding_map[padding]


cdef unsigned long conform_saltlen(key, saltlen, HashDescriptor hash, padding) except? 0:
    """Turn a user supplied saltlen into an appropriate object.

    Defaults to as long a salt as possible if not supplied.

    """
    if saltlen is None:
        return max_payload(key.size, padding, hash)
    return saltlen


def max_payload(int key_size, padding=PAD_OAEP, hash=None):
    """Find the maximum length of the payload that is safe to encrypt/sign.

    Params:
        padding -- The padding that will be used.
        hash -- The hash that will be used.

    """
    padding = conform_padding(padding)
    hash = conform_hash(hash, DEFAULT_ENC_HASH)
    if padding == c_RSA_PAD_NONE:
        return key_size / 8
    elif padding == c_RSA_PAD_OAEP:
        return key_size / 8 - 2 * hash.digest_size - 2
    elif padding == c_RSA_PAD_PSS:
        return key_size / 8 - hash.digest_size - 2
    else:
        # PAD_V1_5 - I'm not too sure about this one.
        return key_size / 8 - 2


def key_size_for_payload(int length, padding=PAD_OAEP, hash=None):
    """Determine the min keysize for a payload of a given length."""
    padding = conform_padding(padding)
    hash = conform_hash(hash, DEFAULT_ENC_HASH)
    if padding == c_RSA_PAD_NONE:
        return 8 * length
    elif padding == c_RSA_PAD_OAEP:
        return 8 * (length + 2 * hash.digest_size + 2)
    elif padding == c_RSA_PAD_PSS:
        return 8 * (length + hash.digest_size + 2)
    else:
        # PAD_V1_5 - I'm not too sure about this one.
        return 8 * (length + 2)


# This object must be passed to the Key constructor in order for an
# instance to be created. This is to assert that keys can only be created by
# the C code. This is a BAD idea.
cdef object blank_key_sentinel = object()

cdef class Key

cdef Key blank_key(cls):
    """Create a new uninitialized key object.

    This must be used as we do not allow one to create a key with the normal
    constructor (to make sure we don't have any keys in an undefined state).

    """
    return cls(blank_key_sentinel)


# Regular expression for determining and extracting PEM data.
cdef object pem_re = re.compile(r'^\s*-----BEGIN ((?:RSA )?(?:PRIVATE|PUBLIC)) KEY-----(.+)-----END \1 KEY-----', re.DOTALL)


cdef class Key(object):

    cdef rsa_key key
    cdef Key _public

    # The sentinel checking code is in the cinit because I believe it is the
    # only place that it cannot be overidden.
    def __cinit__(self, input=None, **kwargs):

        cdef unsigned long size, e
        cdef PRNG prng

        if isinstance(input, basestring):
            format = kwargs.pop('format', None)
            if kwargs:
                raise Error('too many kwargs')
            self._from_string(input, format)

        elif 'size' in kwargs or isinstance(input, int):
            size = kwargs.pop('size', input)
            e = kwargs.pop('e', DEFAULT_E)
            prng = kwargs.pop('prng', None)
            self._generate(size, e, prng)<commit_msg>rsa.Key accepts longs as key sizes.<commit_after># vim: set syntax=pyrex
<%!

key_parts = 'e d N p q qP dP dQ'.split()

%>

from tomcrypt._core cimport *
from tomcrypt import Error
from tomcrypt.prng cimport conform_prng
from tomcrypt.hash cimport conform_hash, Descriptor as HashDescriptor
from tomcrypt.prng cimport PRNG

import re
import base64
from math import ceil


TYPE_PRIVATE = 'private'
TYPE_PUBLIC  = 'public'

cdef object type_map = {
    TYPE_PRIVATE: c_RSA_TYPE_PRIVATE,
    TYPE_PUBLIC : c_RSA_TYPE_PUBLIC,
}


cdef c_RSA_PAD_NONE = 0
PAD_NONE = 'none'
PAD_V1_5 = 'v1.5'
PAD_OAEP = 'oaep'
PAD_PSS  = 'pss'

cdef object padding_map = {
    PAD_NONE: c_RSA_PAD_NONE,
    PAD_V1_5: c_RSA_PAD_V1_5,
    PAD_OAEP: c_RSA_PAD_OAEP,
    PAD_PSS : c_RSA_PAD_PSS,
}


FORMAT_PEM = 'pem'
FORMAT_DER = 'der'


DEFAULT_ENC_HASH = 'sha1'
DEFAULT_SIG_HASH = 'sha512'

DEFAULT_SIZE = 2048
DEFAULT_E = 65537



cdef int conform_padding(padding) except -1:
    """Turn a user supplied padding constant into the C variant."""
    if isinstance(padding, basestring):
        padding = padding.lower()
    if padding not in padding_map:
        raise Error('unknown RSA padding %r' % padding)
    return padding_map[padding]


cdef unsigned long conform_saltlen(key, saltlen, HashDescriptor hash, padding) except? 0:
    """Turn a user supplied saltlen into an appropriate object.

    Defaults to as long a salt as possible if not supplied.

    """
    if saltlen is None:
        return max_payload(key.size, padding, hash)
    return saltlen


def max_payload(int key_size, padding=PAD_OAEP, hash=None):
    """Find the maximum length of the payload that is safe to encrypt/sign.

    Params:
        padding -- The padding that will be used.
        hash -- The hash that will be used.

    """
    padding = conform_padding(padding)
    hash = conform_hash(hash, DEFAULT_ENC_HASH)
    if padding == c_RSA_PAD_NONE:
        return key_size / 8
    elif padding == c_RSA_PAD_OAEP:
        return key_size / 8 - 2 * hash.digest_size - 2
    elif padding == c_RSA_PAD_PSS:
        return key_size / 8 - hash.digest_size - 2
    else:
        # PAD_V1_5 - I'm not too sure about this one.
        return key_size / 8 - 2


def key_size_for_payload(int length, padding=PAD_OAEP, hash=None):
    """Determine the min keysize for a payload of a given length."""
    padding = conform_padding(padding)
    hash = conform_hash(hash, DEFAULT_ENC_HASH)
    if padding == c_RSA_PAD_NONE:
        return 8 * length
    elif padding == c_RSA_PAD_OAEP:
        return 8 * (length + 2 * hash.digest_size + 2)
    elif padding == c_RSA_PAD_PSS:
        return 8 * (length + hash.digest_size + 2)
    else:
        # PAD_V1_5 - I'm not too sure about this one.
        return 8 * (length + 2)


# This object must be passed to the Key constructor in order for an
# instance to be created. This is to assert that keys can only be created by
# the C code. This is a BAD idea.
cdef object blank_key_sentinel = object()

cdef class Key

cdef Key blank_key(cls):
    """Create a new uninitialized key object.

    This must be used as we do not allow one to create a key with the normal
    constructor (to make sure we don't have any keys in an undefined state).

    """
    return cls(blank_key_sentinel)


# Regular expression for determining and extracting PEM data.
cdef object pem_re = re.compile(r'^\s*-----BEGIN ((?:RSA )?(?:PRIVATE|PUBLIC)) KEY-----(.+)-----END \1 KEY-----', re.DOTALL)


cdef class Key(object):

    cdef rsa_key key
    cdef Key _public

    # The sentinel checking code is in the cinit because I believe it is the
    # only place that it cannot be overidden.
    def __cinit__(self, input=None, **kwargs):

        cdef unsigned long size, e
        cdef PRNG prng

        if isinstance(input, basestring):
            format = kwargs.pop('format', None)
            if kwargs:
                raise Error('too many kwargs')
            self._from_string(input, format)

        elif 'size' in kwargs or isinstance(input, (int, long)):
            size = kwargs.pop('size', input)
            e = kwargs.pop('e', DEFAULT_E)
            prng = kwargs.pop('prng', None)
            self._generate(size, e, prng)
{'fraction_non_alphanumeric': 0.0896001903855307, 'fraction_numerical': 0.011185149928605425, 'mean_word_length': 2.8679245283018866, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3566271', 'n_tokens_mistral': 2949, 'n_tokens_neox': 2719, 'n_words': 943}