Are there any codecs that can take parameters at initialization time? If not, how about supporting them? Here's a motivating example: import codecs f = codecs.open('output', 'wb', encoding='DES', # arguments to open() key = '...', mode = DES.ECB) f.write('This will be encrypted\n') f.close() For this to work, you'd need a few changes to codecs.py. Off the top of my head, I think StreamReader, StreamWriter, and StreamReaderWriter all need to grow **kwargs arguments for any additional arguments, as do codecs.open() and codecs.lookup(). Then someone could write a DES StreamReader/Streamwriter that took a key and feedback mode at creation time. (codecs.Codec instances are supposed to be stateless, right?) --amk
Andrew wrote:
Are there any codecs that can take parameters at initialization time? If not, how about supporting them? Here's a motivating example:
import codecs f = codecs.open('output', 'wb', encoding='DES', # arguments to open() key = '...', mode = DES.ECB) f.write('This will be encrypted\n') f.close()
RC4, maybe. But I think you're asking for trouble in trying to pretend a block-mode cipher is a stream. - Gordon
Andrew Kuchling wrote:
Are there any codecs that can take parameters at initialization time? If not, how about supporting them?
Even though this is not documented in the Unicode PEP, the extensibility of the constructor using extra (keyword) arguments is intended.
Here's a motivating example:
import codecs f = codecs.open('output', 'wb', encoding='DES', # arguments to open() key = '...', mode = DES.ECB) f.write('This will be encrypted\n') f.close()
For this to work, you'd need a few changes to codecs.py. Off the top of my head, I think StreamReader, StreamWriter, and StreamReaderWriter all need to grow **kwargs arguments for any additional arguments, as do codecs.open() and codecs.lookup().
The codec design allows extending the constructors using keyword arguments, however I'd rather not add a generic **kws argument to the base classes since this would hide errors (unknown or unsupported keywords, mispellings, etc.). The codec.open() API is different though: it could grow a **kws argument which is then apply()ed to the codec constructor. The constructor will then raise any exceptions related to malformed keyword parameters. There's no need to add **kws to codec.lookup().
Then someone could write a DES StreamReader/Streamwriter that took a key and feedback mode at creation time. (codecs.Codec instances are supposed to be stateless, right?)
The encoder and decoder functions must work stateless. StreamReader/Writer instances should be used for everything that has to do with state since these are instantiatied per use whereas encoder and decoder functions fetched using codec.lookup() can be used multiple times. -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/
On Tue, Sep 18, 2001 at 04:31:31PM -0400, Gordon McMillan wrote:
RC4, maybe. But I think you're asking for trouble in trying to pretend a block-mode cipher is a stream.
Dunno, but we'll hash that out on the python-crypto list. For now I just wanted to know if parametrized codecs would be an inherently bad idea. (Two ways of handling this would be requiring all write() calls to use a multiple of the block size, or reporting an error on the close() if you haven't written out an even number of blocks. I have no idea which is preferable; not sure I like either of them...) --amk
The codec design allows extending the constructors using keyword arguments, however I'd rather not add a generic **kws argument to the base classes since this would hide errors (unknown or unsupported keywords, mispellings, etc.).
Isn't such an argument required at least for StreamReaderWriter, because it actually instantiates two objects? class StreamReaderWriter: def __init__(self, stream, Reader, Writer, errors='strict'): """ ... Reader, Writer must be factory functions or classes providing the StreamReader, StreamWriter interface resp. """ self.stream = stream self.reader = Reader(stream, errors) self.writer = Writer(stream, errors) Hmm... you'd better not need to have two different set of keyword arguments for Reader and Writer. Is that limitation acceptable? If it is, then the list of changes becomes 1) add **kw to codecs.open, and 2) add **kw to StreamReaderWriter's constructor, and apply it to the Reader() and Writer() calls.
The encoder and decoder functions must work stateless.
OK, then they're not suitable for encryption (in general, though they'd work fine for ECB mode). --amk
Andrew Kuchling wrote:
The codec design allows extending the constructors using keyword arguments, however I'd rather not add a generic **kws argument to the base classes since this would hide errors (unknown or unsupported keywords, mispellings, etc.).
Isn't such an argument required at least for StreamReaderWriter, because it actually instantiates two objects?
class StreamReaderWriter: def __init__(self, stream, Reader, Writer, errors='strict'):
""" ... Reader, Writer must be factory functions or classes providing the StreamReader, StreamWriter interface resp. """ self.stream = stream self.reader = Reader(stream, errors) self.writer = Writer(stream, errors)
Hmm... you'd better not need to have two different set of keyword arguments for Reader and Writer. Is that limitation acceptable?
Should be OK since both work on the same stream backend and thus will normally use the same encoding parameters.
If it is, then the list of changes becomes 1) add **kw to codecs.open, and 2) add **kw to StreamReaderWriter's constructor, and apply it to the Reader() and Writer() calls.
Right.
The encoder and decoder functions must work stateless.
OK, then they're not suitable for encryption (in general, though they'd work fine for ECB mode).
Right; would it be feasable to use ECB ciphers for the stateless part and also allow other modes for the StreamReader/Writer ? -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/
Andrew Kuchling wrote:
On Tue, Sep 18, 2001 at 04:31:31PM -0400, Gordon McMillan wrote:
RC4, maybe. But I think you're asking for trouble in trying to pretend a block-mode cipher is a stream.
Dunno, but we'll hash that out on the python-crypto list. For now I just wanted to know if parametrized codecs would be an inherently bad idea.
(Two ways of handling this would be requiring all write() calls to use a multiple of the block size, or reporting an error on the close() if you haven't written out an even number of blocks. I have no idea which is preferable; not sure I like either of them...)
I guess you'll need some kind of buffering in the reader/writer to handle this situation. The cipher.py tools in mxCrypto does this already, so it may serve as template for the needed code. (This is getting off-topic though for this list...) -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Consulting & Company: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/
MAL wrote:
Andrew Kuchling wrote:
On Tue, Sep 18, 2001 at 04:31:31PM -0400, Gordon McMillan wrote:
RC4, maybe. But I think you're asking for trouble in trying to pretend a block-mode cipher is a stream.
Dunno, but we'll hash that out on the python-crypto list. For now I just wanted to know if parametrized codecs would be an inherently bad idea.
(Two ways of handling this would be requiring all write() calls to use a multiple of the block size, or reporting an error on the close() if you haven't written out an even number of blocks. I have no idea which is preferable; not sure I like either of them...)
I guess you'll need some kind of buffering in the reader/writer to handle this situation. The cipher.py tools in mxCrypto does this already, so it may serve as template for the needed code.
Sigh. If it's a stream, you can hook a writer through IPC to a reader. Let's say the first 15 bytes are enough to tell the reading process whether it's interested in the rest. So unsupecting programmer sends 15 bytes to the writer, then waits for the reading process to tell him whether to continue. And waits. And waits... It's not a stream.
(This is getting off-topic though for this list...)
It is on-topic to the extent that python dev-vers should be encouraged not to violate certan well-established notions. - Gordon
participants (3)
-
Andrew Kuchling
-
Gordon McMillan
-
M.-A. Lemburg