Cryptographic library for Boost

Hi, All! I've decided to participate in Google SoC(http://code.google.com/soc/) and try to make basic cryptographic library good enough to be ready for review in August. I think that any cryptographic function (encryption/decryption, hashes) can be represented as operation on data stream and sticked to following interface: class crypt_something { void init ( <algorithm-specific initialization parameters here, like encryption key> ); ~crypt_something(); //performs secure cleanup //process given data //return value: iterator pointing to first unaffected element //in output buffer. template<class iIt, class oIt> oIt process(iIt begin, iIt end, oIt out); //estimates amount of data to be written when calling process() //with given arguments. //return value: maximum number of *iIt elements that can be written by //next call to process template<class iIt> std::size_t process_outsize(iIt begin, iIt end) const; //flushes internal buffer //next call to process() will start new calculation //return value: iterator pointing to first unaffected element //in output buffer. template<class oIt> oIt flush(oIt out); //estimates amount of data to be written when calling flush() //with given arguments. //return value: maximum number of *oIt elements that can be written by //next call to flush template<class oIt> std::size_t flush_outsize() const; }; Later any algorithm with this interface can be used as template parameter for adapter (for example, to Boost.Iostreams - it can be used assuming we use 'secure' allocator) What do you think, what functionality should Boost.Crypto include? What interfaces are fast and useful(except for iterators in code above)? Criticism is welcomed :) Sergey

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Sergey Sent: Thursday, March 22, 2007 11:10 PM To: boost@lists.boost.org Subject: [boost] Cryptographic library for Boost
template<class iIt, class oIt> oIt process(iIt begin, iIt end, oIt out);
Criticism is welcomed :)
No criticism, just a thought/suggestion: As it stands, 'process' is linear. OTOH, there are 'restartable' or incremental (I don't know the right terminology) hash functions, see http://www.azillionmonkeys.com/qed/hash.html, esp. Update(5). From a 10.000 meters perspective it takes just one portion of the whole input at once, computes a hash for that portion and holds or, preferably, returns a state, that needs to be used for the next iteration. Supporting such use cases might possibly be more general than the proposed linear approach. The linear approach could possibly be just a layer above an iterative interface, which might be much more appropriate for asynchronously received data (be it files or via sockets). If an iterative interface is implemented, it might be nice to be able to run different iterations in different threads. cheers, aa -- Andreas Ames | Programmer | Comergo GmbH | ames AT avaya DOT com Sitz der Gesellschaft: Stuttgart Registergericht: Amtsgericht Stuttgart - HRB 22107 Geschäftsführer: Andreas von Meyer zu Knonow, Udo Bühler, Thomas Kreikemeier

Thanks for suggestion. My crypt_something class meant to be streamed but i failed to describe it. crypt_something is buffered 'processor' and user can call process() several time example: crypt_something cs; cs.init(encryption_key); ... while (!input_stream.eof()) { in_buffer = input_stream.read(); //reading to buffer from input stream size_t outsize = cs.process_outsize(in_buffer.begin(), in_buffer.end()); //determining //amount of memory we will need to write output if (out_buffer.size() < outsize) out_buffer.resize(outsize); stream_buffer::iterator it = cs.process(in_buffer.begin(), in_buffer.end(), out_buffer.begin()); out_stream.write(out_buffer.begin(), it); } //flushing buffer size_t outsize = cs.flush_outsize<stream_buffer::item_type>(); if (out_buffer.size() < outsize) out_buffer.resize(outsize); stream_buffer::iterator it = cs.flush(out_buffer.begin()); out_stream.write(out_buffer.begin(), it); It is written in some kind of pseudo-code but i hope it is clear enough now :) Sergey. On 3/23/07, Ames Andreas <Andreas.Ames@comergo.com> wrote:
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Sergey Sent: Thursday, March 22, 2007 11:10 PM To: boost@lists.boost.org Subject: [boost] Cryptographic library for Boost
template<class iIt, class oIt> oIt process(iIt begin, iIt end, oIt out);
Criticism is welcomed :)
No criticism, just a thought/suggestion:
As it stands, 'process' is linear.

Sergey escreveu:
Thanks for suggestion. My crypt_something class meant to be streamed but i failed to describe it. crypt_something is buffered 'processor' and user can call process() several time example: crypt_something cs; cs.init(encryption_key); ... while (!input_stream.eof()) { in_buffer = input_stream.read(); //reading to buffer from input stream size_t outsize = cs.process_outsize(in_buffer.begin(), in_buffer.end()); //determining //amount of memory we will need to write output if (out_buffer.size() < outsize) out_buffer.resize(outsize); stream_buffer::iterator it = cs.process(in_buffer.begin(), in_buffer.end(), out_buffer.begin()); out_stream.write(out_buffer.begin(), it); } //flushing buffer size_t outsize = cs.flush_outsize<stream_buffer::item_type>(); if (out_buffer.size() < outsize) out_buffer.resize(outsize); stream_buffer::iterator it = cs.flush(out_buffer.begin()); out_stream.write(out_buffer.begin(), it);
It is written in some kind of pseudo-code but i hope it is clear enough now :)
I think it is inproper to begin with "streams". "Streams" imply a source of data and that is irrelevant from a cipher's point of view. I'd recommend thinking in terms of algorithm as in <algorithm> -- operations on pairs of iterators or ranges. Something basic along the lines of: /** * pre-condition: distance(begin, end) == cipher's block size. */ template <typename InputIterator, typename OutputIterator> OutputIterator cipher_update (InputIterator begin, InputIterator end, OutputIterator out); /** * no precondition as above: padding as necessary. */ template <typename InputIterator, typename OutputIterator> OutputIterator cipher_finalize (InputIterator begin, InputIterator end, OutputIterator out); These generic algorithms could be specialized through "tag dispatching" as always to increase performance for special cases. -- Pedro Lamarão
participants (3)
-
Ames Andreas
-
Pedro Lamarão
-
Sergey