Design Philosophy

 

Engineering principles

The toolkit contains no (non-constant) global variables, and can be used in multi-threaded and multi-tasking environments. All calls follow a simple construct-set-use-destruct pattern, allowing simple interfaces to an object-oriented application. All interfaces are fully specified in a way that can be interpreted in assembler, allowing subsets of the system to be used in a wide variety of circumstances.

Modularity

The toolkit consists of about thirty independent modules, each with precise specifications and several implementations. This enables the user to select - independently for each application - the exact functionality, performance and memory usage required. Functionality of minor importance can be serviced with a very small module, leaving space for high performance implementations of the important functions.

As a typical example, in an application where only the RSA implementation is speed critical and memory constraints are tight, one could select a speed-optimised version of RSA and memory-optimised versions of the other modules. If, at a later date, the requirements should change, individual modules can be replaced as desired and the uniformity of the interface means no further work is needed.

Memory model

All internal memory allocations (there are about twenty in total in the toolkit) use the mem module, which comes in several interchangeable versions. The simplest version just assumes that an operating system call will be made. Another version allocates a fixed (#define'd) amount of memory at the start, and uses and re-uses this memory from then on. This allows an embedded system to be absolutely certain that memory allocation failure cannot occur. The memory needed for such an allocation can be calculated precisely for a given set of functionality, using internal toolkit functions.

There is also a range of `cache' systems that allow data included at compile time, or calculated by previous calls with the same environment, to be used to improve performance.

Library dependencies

The CPKtec library does not require any libraries. It must be possible to allocate memory somehow, but this requirement is encapsulated into a tiny module (which, for example, calls malloc if it is available).

Quantifying performance

The CPKtec toolkit is quantitative about performance. A "T-number" is used to define the tradeoff a particular implementation makes between speed and size.

  • A T2 implementation allows just 1 byte of extra memory to be used per 1% improvement in run time. This essentially means an implementation which will go to any lengths to save memory, and is suitable for functionality that is required but which will almost never be used.
  • A T3 implementation allows 10 bytes for each 1% performance improvement. This is still a very small implementation, but significantly faster and insignificantly larger than T2. Such an implementation is suitable for modules that are not performance critical.
  • A T4 implementation allows 100 bytes for each 1% performance improvement. This is a good small reasonable level - there are many algorithms that can deliver more than 1% improvement per 100 extra bytes, and these are included in a T4 version. T4 implementations are suitable for the main jobs in a small computer.
  • A T5 implementation allows 1 Kbyte for each 1%. This opens the door to some fairly marginal improvements which, considering the system from top to bottom, mean that the system is several kilobytes bigger and tens of percent faster. These implementations are suitable for general use.
  • A T6 implementation allows 10 Kbytes for a 1% improvement. At this level, large numbers of special-case routines and large lookup tables become appropriate, resulting in a system of perhaps twice the size and 20% faster overall. A T6 implementatin is for use when performance is the only important factor.

Return to Technology page

 


Copyright © Cambridge Public Key Technology Ltd 2002-2006 CPKtec logo