diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2011-07-10 01:35:46 +0200 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2011-07-10 01:35:46 +0200 |
commit | 65f254fcf1928740c4828c9287aada3197525d56 (patch) | |
tree | e2e1ea230eb30723d6b23b2bc203899a31f7001c | |
parent | 2cc58a8604facfb130579958466c2b71a5146cbd (diff) | |
download | rsa-git-65f254fcf1928740c4828c9287aada3197525d56.tar.gz |
Reinstated some of the backed out changeset 812d745b6bef:
- added support for block size
- improved some exceptions
-rwxr-xr-x | rsa/core.py | 7 | ||||
-rwxr-xr-x | rsa/transform.py | 41 |
2 files changed, 45 insertions, 3 deletions
diff --git a/rsa/core.py b/rsa/core.py index 8f989df..2df4be5 100755 --- a/rsa/core.py +++ b/rsa/core.py @@ -17,8 +17,11 @@ def encrypt_int(message, ekey, n): if not type(message) is types.LongType: raise TypeError("You must pass a long or int") - if message < 0 or message > n: - raise OverflowError("The message is too long") + if message < 0: + raise ValueError('Only non-negative numbers are supported') + + if message > n: + raise OverflowError("The message %i is too long for n=%i" % (message, n)) #Note: Bit exponents start at zero (bit counts start at 1) this is correct safebit = rsa.common.bit_size(n) - 2 # compute safe bit (MSB - 1) diff --git a/rsa/transform.py b/rsa/transform.py index 35b7461..076c385 100755 --- a/rsa/transform.py +++ b/rsa/transform.py @@ -9,8 +9,22 @@ import types def bit_size(number): """Returns the number of bits required to hold a specific long number""" + if number < 0: + raise ValueError('Only nonnegative numbers possible: %s' % number) + + if number == 0: + return 1 + return int(math.ceil(math.log(number, 2))) +def byte_size(number): + """Returns the number of bytes required to hold a specific long number. + + The number of bytes is rounded up. + """ + + return int(math.ceil(bit_size(number) / 8.0)) + def bytes2int(bytes): """Converts a list of bytes or an 8-bit string to an integer. @@ -72,7 +86,7 @@ def int2bytes(number, block_size=None): # Do some bounds checking if block_size is not None: - needed_bytes = int(math.ceil(bit_size(number) / 8.0)) + needed_bytes = byte_size(number) if needed_bytes > block_size: raise OverflowError('Needed %i bytes for number, but block size ' 'is %i' % (needed_bytes, block_size)) @@ -92,6 +106,31 @@ def int2bytes(number, block_size=None): return padding + ''.join(bytes) +def block_op(block_provider, block_size, operation): + r'''Generator, applies the operation on each block and yields the result + + Each block is converted to a number, the given operation is applied and then + the resulting number is converted back to a block of data. The resulting + block is yielded. + + @param block_provider: an iterable that iterates over the data blocks. + @param block_size: the used block size + @param operation: a function that accepts an integer and returns an integer + + >>> blocks = ['\x00\x01\x02', '\x03\x04\x05'] + >>> list(block_op(blocks, 3, lambda x: (x + 6))) + ['\x00\x01\x08', '\x03\x04\x0b'] + + ''' + + for block in block_provider: + number = bytes2int(block) + print 'In : %i (%i bytes)' % (number, byte_size(number)) + after_op = operation(number) + print 'Out: %i (%i bytes)' % (after_op, byte_size(after_op)) + yield int2bytes(after_op, block_size) + + def to64(number): """Converts a number in the range of 0 to 63 into base 64 digit character in the range of '0'-'9', 'A'-'Z', 'a'-'z','-','_'. |