Cryptix logo

A simple test data interpreter

(Cryptix Application Note #5 --November 1997)

 Table of Contents

Return to the Application Notes Index or the FAQ or the Overview.


Overview

Assessing the correctness of a cipher or message digest algorithm implementation involves running the algorithm with a known set of parameter values and checking the results against pre-computed values obtained either manually or with another correct implementation.

The process of writing the test class is a time-consuming one and, most of the time, requires the programmer to use repetitive tasks slightly adapted to the specifics of the algorithm being tested.

The abstract nature of the java implementations of such algorithms and test procedures, inherent to the language being an Object-Oriented one, implies a more abstract method of testing that can save Quality Assurance people as well as programmers time and resources.

This dissociation between the algorithms and the data for their most common test protocols is emphasised by the Sun JCE API and Cryptix's clean-room implementation known as the IJCE (International JCE).

The cryptix.util.test.Maker class is a simple interpreter for a basic data definition language that can be used to test the correctness of cipher algorithm and message digest implementations. In essence instead of having a Test class for each implementation, incorporating the code and the test data, the user invokes Maker with as many test data files as needed or required. The syntax of such data files is simple enough that non-programmers can create them and indeed conduct the tests.


Message digest related data definition syntax

A simple example of a test data input file for Maker follows:

//
// MD2 test data
//
 
md MD2
data
    ""
    <8350E5A3E24C153DF2275C9F80692773>
 
    "a"
    <32EC01EC4A6DAC72C0AB96FB34C0B5D1>
 
    "abc"
    <DA853B0D3F88D99B30283A69E6DED6BB>
 
    "message digest"
    <AB4F496BFB2A530B219FF33031FE06B0>
 
    "abcdefghijklmnopqrstuvwxyz"
    <4E8DDFF3650292AB5A4108C3AA47940B>

Comments

The first three lines are comments. A comment starts with the two characters // and runs until an end-of-line is encountered. Maker ignores all comments. They are defined to allow an additional level of meta-information for use by the users.

A comment need not start at the beginning of a line.

 

The md keyword

The md keyword tells Maker that the subsequent information is to be used with a java.security.MessageDigest subclass. It is followed by an Identifier that has to match with a message digest algorithm implementation class name, or an alias of the latter. Aliases are defined in the security provider properties file, which for the Cryptix strong cryptographic library is Cryptix.properties found in the cryptix-lib package.

 

The data keyword for a message digest implementation

The data keyword tells Maker that the subsequent information is to be interpreted as test data for the algorithm last defined.

The structure of data elements differ depending on whether the algorithm is a MessageDigest (indicated with an md keyword) or a Cipher (indicated with the cipher keyword) one.

For message digest test data are defined as either single-iteration or multi-iteration.

Message digest single-iteration test data

A single iteration is a pair of data formed by a string-literal and a hexadecimal-literal separated by a white space (one or more space, tab, new line or carriage return characters).

The semantics of the single-iteration statement is that Maker has to digest the input string literal and check if the result matches the given hexadecimal literal.

Message digest multi-iteration test data

A multi-iteration test data consists of:

  1. Numeric literal, say n,
  2. The symbol "*",
  3. A string literal, and finally
  4. A hexadecimal literal.

Maker will update the message digest object n times using as input the string literal and finally check the result against the designated hexadecimal literal.

Here is an example of a Maker input file using the multi-iteration test data syntax:

//
// RIPEMD128 test data
//
 
md RIPEMD128
data
    ""
    <CDF26213A150DC3ECB610F18F6B38B46>
 
    "a"
    <86BE7AFA339D0FC7CFC785E72F578D33>
 
    ...
 
    1000000 * "a"
    <4A7F5723F954EBA1216C9D8F6320431F>


Cipher related data definition syntax

A simple Maker input file for testing a cipher implementation follows:

//
// CAST5 test data
//
 
cipher CAST5
 
// test #1
 
data
// key                               input              output
 <0123456712345678234567893456789A> <0123456789ABCDEF> <238B4FE5847E44B2>
 <01234567123456782345>             <0123456789ABCDEF> <EB6A711A2C02271B>
 <0123456712>                       <0123456789ABCDEF> <7AC816D16E9B302E>
 
 
// test #2
 
data <0123456712> <0123456789ABCDEF> speed

The cipher keyword

Similar to md, the cipher keyword tells Maker that the subsequent information is to be used with a java.security.Cipher subclass. It is always followed by an Identifier that has to match with a cipher algorithm implementation class name, or an alias of the latter.

 

The data keyword for a cipher implementation

For a cipher object, the data elements can be: two-way test data, symmetric test data or speed test data.

A two-way test data is formed by a triplet of hexadecimal literals to be interpreted as the key, an input value and the certified output value respectively. When Maker recognises a two-way test data statement, it:

  1. initialises the cipher object for encryption using the given key;
  2. encrypts the input and
  3. test the result against the designated output; It then
  4. reinitialises the same cipher with the same key this time for decryption
  5. decrypts the output and
  6. test the result against the designated input.

 

The speed keyword

The speed keyword indicates a speed test data to be conducted on a cipher implementation. It is the last element of a triplet where the first two are similar to those found in a two-way test data; ie: key and input.

When Maker parses the speed keyword, it runs the cipher 100,000 times updating the same input value and printing both the start and finish date/times. It then decrypts the so far obtained result the same number of times and check if the final result matches the given input, printing along the timing information.

 

The auto keyword

A symmetric test data is a triplet consisting of two hexadecimal literals and the keyword auto. Here is an example:

//
// RC2 test data
//
 
cipher RC2
data
  <0123456789abcdef>
  <
  7595C3E6 114A0978 0C4AD452 338E1FFD 9A1BE949 8F813D76 533449B6 778DCAD8
  C78A8D2B A9AC6608 5D0E53D5 9C26C2D1 C490C1EB BE0CE66D 1B6B1B13 B6B919B8
  47C25A91 447A95E7 5E4EF167 79CDE8BF 0A95850E 32AF9689 444FD377 108F98FD
  CBD4E726 56750099 0BCC7E0C A3C4AAA3 04A387D2 0F3B8FBB CD42A1BD 311D7A43
  03DDA5AB 078896AE 80C18B0A F66DFF31 9616EB78 4E495AD2 CE90D7F7 72A81747
  B65F6209 3B1E0DB9 E5BA532F AFEC4750 8323E671 327DF944 4432CB73 67CEC82F
  5D44C0D0 0B67D650 A075CD4B 70DEDD77 EB9B1023 1B6B5B74 1347396D 62897421
  D43DF9B4 2E446E35 8E9C11A9 B2184ECB EF0CD8E7 A877EF96 8F1390EC 9B3D35A5
  585CB009 290E2FCD E7B5EC66 D9084BE4 4055A619 D9DD7FC3 166F9487 F7CB2729
  12426445 998514C1 5D53A18C 864CE3A2 B7555793 98812652 0EACF2E3 066E230C
  91BEE4DD 5304F5FD 0405B35B D99C7313 5D3D9BC3 35EE049E F69B3867 BF2D7BD1
  EAA595D8 BFC0066F F8D31509 EB0C6CAA 006C807A 623EF84C 3D33C195 D23EE320
  C40DE055 8157C822 D4B8C569 D849AED5 9D4E0FD7 F379586B 4B7FF684 ED6A189F
  7486D49B 9C4BAD9B A24B96AB F924372C 8A8FFFB1 0D553549 00A77A3D B5F205E1
  B99FCD86 60863A15 9AD4ABE4 0FA48934 163DDDE5 42A65855 40FD683C BFD8C00F
  12129A28 4DEACC4C DEFE58BE 7137541C 047126C8 D49E2755 AB181AB7 E940B0C0
  >
  auto

When Maker recognises the auto keyword, it encrypts the input value, then decrypts and check if the final result matches the given input.

 

The property and properties keywords

Symmetric ciphers can be run in different modes of operations, with or without padding. Some modes require initialisation data known as Initialisation Vector or IV. In addition certain algorithms are designed to run in a variable number of rounds and a varying degree of cryptographic strengths.

Maker allows the user to set specific values for these parameters with the properties keyword. Here is a fragment from the SAFER test data file (SAFER.mtest):

properties
    mode      CBC
    padding   NONE
    iv        <74536EBDC211484A>
    variant = "K-128"
    rounds =  10
data
    // key
    <42431BA40D291F81D66083C605D3A4D6>
    // input
    <
    00000000 00000000 01020304 05060708 00000000 00000000 01020304 05060708
    00010203 04050607 08090A0B 0C0D0E0F 10111213 14151617 18191A1B 1C1D1E1F
    20212223 24252627 28292A2B 2C2D2E2F 30313233 34353637 38393A3B 3C3D3E3F

As you can see, the properties block has to appear before the data block.

Some properties have their own keywords while algorithm-specific ones don't. Algorithm-specific properties are defined using the following syntax:

property-name = property-value

Where property-name is the name of a property known to the cipher implementation and property-value is either a numeric or a string literal. When Maker encounters a statement of the sort, it calls the cipher object with the setParameter() method defined in the cipher object's superclass; ie. jave.security.Cipher.

If the value is invalid or is of the wrong type, the cipher object itself will reject it and Maker will throw an Error and halts.

In the example above, the data implies that the SAFER implementation knows how to handle two properties named: rounds and variant with the first being a numeric while the last is a string.

 

The mode keyword

The mode keyword should be followed by a java.security.Mode subclass class name. It indicates the mode in which the cipher object will be run.

 

The padding keyword

The padding keyword should be followed by a java.security.PaddingScheme subclass class name. It indicates the padding method to apply for the cipher data.

 

The iv keyword

The iv keyword should be followed by a hexadecimal literal. This literal will be used to set the iv for the cipher being tested.


Other syntax-related issues

The include keyword

The include keyword should be followed by a string literal. Once Maker recognises this statement it instantiates a new copy of Maker (itself) and runs it using the string literal as the name of the data input file. Here is an example:

//
// test include statement of Maker language
//
 
include "MDx.mtest"
include "RIPEMD1xx.mtest"

The hexadecimal literal

A hexadecimal literal is a sequence of hexadecimal characters enclosed within a pair of angle brackets: <>. Maker removes all white space characters from the enclosed sequence before converting it to a byte array.


Generating cryptix.util.test.Maker

Maker is written in JavaCC, the Java equivalent to lex/yacc. The source code is defined in Maker.jj. You can use the already generated java classes or you can recreate them. Here is how:

  1. If you want to use the existing java classes skip to step 2, otherwise delete the following java source files:
    1. ASCII_CharStream.java
    2. Maker.java
    3. MakerConstants.java
    4. MakerTokenManager.java
    5. ParseException.java
    6. Token.java
    7. TokenMgrError.java

  2. Run JavaCC:
    javacc Maker.jj
  3. JavaCC will generate all the files listed in step one above. Compile them with your java compiler. Few warnings will be echoed pertaining to the fact that the JavaCC code uses deprecated methods. Just make sure there are not errors; just warnings.

  4. Make yourself some test data input files and use them with Maker like so:
    java cryptix.util.test.Maker input-file > output-file


Maker syntax in EBNF

The formal syntax of Maker in extended Backus-Naur form, as generated by jjDoc a utility included in the JavaCC package, is available.

 


Cryptix
Raif S. Naffah
Chatswood, 13 November 1997.

Copyright © 1996-1997 Systemics Ltd
on behalf of the Cryptix Development Team.
All rights reserved.
Cryptix is a trademark of Systemics Ltd.