SHAKE

Test digest

crypto-condor tests SHAKE implementations through a single digest function that is equivalent to the following pseudo-code:

def digest(data: bytes, output_length: int) -> bytes:
    h = shake128.init()
    h.update(data)
    return h.final(output_length)

Naming convention

To test a SHAKE implementation, the function must conform to one of these conventions:

CC_SHAKE_128_digest[_bit]

CC_SHAKE_256_digest[_bit]

bit is an optional parameter. If present, the implementation is considered to be bit-oriented. By default, it is considered byte-oriented.

Function signature

Its signature must be:

int digest(
uint8_t *digest,
const size_t digest_size,
const uint8_t *input,
const size_t input_size,
)

Produces digests of arbitrary length.

Parameters:
  • digest[Out] An allocated buffer, used to return the digest.

  • digest_size[In] The desired size of the digest.

  • input[In] The input data.

  • input_size[In] The size of the input data in bytes.

Returns:

A status value.

Return values:
  • 0 – OK

  • -1 – Digest failed.

Example

To test that the harness integration is working correctly, we use the following OpenSSL harness.

#include <openssl/evp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int generic_digest(uint8_t *digest, const size_t digest_size,
                   const uint8_t *input, const size_t input_size,
                   const char *name) {
  const EVP_MD *md = EVP_get_digestbyname(name);
  if (md == NULL) {
    fprintf(stderr, "Failed to get digest %s\n", name);
    return -1;
  }

  EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
  if (!EVP_DigestInit_ex2(mdctx, md, NULL)) {
    fprintf(stderr, "Init failed\n");
    goto clean;
  }
  if (!EVP_DigestUpdate(mdctx, input, input_size)) {
    fprintf(stderr, "Update failed\n");
    goto clean;
  }
  if (!EVP_DigestFinalXOF(mdctx, digest, digest_size)) {
    fprintf(stderr, "Final failed\n");
    goto clean;
  }

  return 0;

clean:
  EVP_MD_CTX_free(mdctx);
  return -1;
}

int CC_SHAKE_128_digest(uint8_t *digest, const size_t digest_size,
                        const uint8_t *input, const size_t input_size) {
  return generic_digest(digest, digest_size, input, input_size, "SHAKE-128");
}

int CC_SHAKE_256_digest(uint8_t *digest, const size_t digest_size,
                        const uint8_t *input, const size_t input_size) {
  return generic_digest(digest, digest_size, input, input_size, "SHAKE-256");
}

Compile the shared library with the -lssl -lcrypto options.

gcc -fPIC -shared shake_harness.c -o shake.so -lssl -lcrypto

Then test the harness.

crypto-condor-cli test harness shake.so