C Shell Objective-C Makefile
Latest commit 92cda02 Aug 8, 2017 @adegtyarev adegtyarev Merge pull request #2 from degtyarevalexey/issue-1
Fix typo in -h output


GOST R 34.11-2012 hash function with 512/256 bit digest

This is portable implementation of the GOST R 34.11-2012 hash function.
The standard for this hash function developed by the Center for
Information Protection and Special Communications of the Federal
Security Service of the Russian Federation with participation of the
Open joint-stock company "Information Technologies and Communication
Systems" (InfoTeCS JSC).

* GCC, Clang or ICC compiler supporting 64-bit integers.

* GNU make (or any compatible make).

Compile and install
The software is smart enough to detect the most suitable configuration
for running hardware and software platform.  In almost all cases it is
sufficient just to type 'make' on top of the source directory:

# make
gcc46 -g -O2 [other compile options..]

This will configure and compile a binary program file named

Usage instructions

# ./gost3411-2012 -h
Usage: [-25bhqrte] [-s string] [files ...]

The program outputs GOST R 34.11-2012 hash digest in hexadecimal format.

 -2 - 256-bit digest.
 -5 - 512-bit digest (default).
 -t - Testing mode to produce hash of example messages defined in
 -b - Benchmark mode (to see how fast or slow this implementation
 -s - Print a digest of the given string.
 -r - Reverses the format of the output.  This helps with visual diffs.
 -q - Quiet mode - only the digest is printed out.
 -e - Switch endianness when printing out resulting hash.  Default: least
      significant first.  With this options set all bytes in resulting
      hash are printed in reversed order, more precisely, most
      significant first.

Each file listed on the command line is processed and hash is printed
for each one.  Stdin is read as input when executed without arguments.

Compile-time options
By default, compiler set in 'CC' environment variable is used, falling
back to 'cc' unless set.  You can quickly recompile source with another
compiler by setting CC:

# make CC=clang

Special target called 'remake' may need to be used to overwrite recently
compiled up-to date binary:

# make remake CC=icc

This will recompile sources from scratch using Intel C Compiler with
default flags.  If you need to adjust these compiler flags, try to set
them with CFLAGS knob:

# make remake CC=icc CFLAGS="-O3"

The API to this implementation is quite straightforward and similar to
other hash function APIs.  Actually the CLI utility in this distribution
just use this API as underlying engine.  You may use this API to
implement GOST R 34.11-2012 in your application.


    This is the hash context.  There should be one GOST34112012Context
    for each object to be hashed.

GOST34112012Init(GOST34112012Context *CTX, 
    const unsigned int digest_size);

    Return initialized GOST34112012Context of specified hash size
    (digest_size) on allocated memory block pointed by CTX.  Digest size
    can be either 512 or 256.  Address of "CTX" must be 16-byte aligned.

GOST34112012Update(GOST34112012Context *CTX, const unsigned char *data,
    size_t len);

    Hash some data in memory of "len" bytes size.  Address of "data" must
    be 16-byte aligned.  The best performance results are achieved when
    len is multiple of 64.
    Note that this call does not modify original data in memory.  If
    security is an issue, calling application should destroy that memory
    block right after GOST34112012Update(), by e.g. memset() to zero.

GOST34112012Final(GOST34112012Context *CTX, unsigned char *digest);

    Finalizes hashing process and set GOST R 34.11-2012 hash in
    memory block pointed by "digest".

GOST34112012Cleanup(GOST34112012Context *CTX);

     The data in context including hash itself, buffer and internal
     state zeroed-out.  Context totally destroyed and the object can't be
     used anymore.  Calling application should free() memory used by this

The following constants may be predefined somewhere in your application
code in order to adjust GOST R 34.11-2012 engine behavior:

__GOST3411_LITTLE_ENDIAN__: define this constant on little-endian

__GOST3411_BIG_ENDIAN__: this constant will indicate big-endian system.

If neither of constants defined the engine defaults to little-endian

__GOST3411_HAS_MMX__: use MMX instructions to compute digest.

__GOST3411_HAS_SSE2__: use SSE2 instruction set to speedup computation
of GOST R 34.11-2012 digest.

__GOST3411_HAS_SSE41__: indicate to include SSE4.1 instructions set.

The best performance results achieved on SSE4.1 capable processors with
GCC-4.8 compiler.  A slightly less performance is with SSE2 capable
processors.  The CLI utility in this distribution tries its best to
determine which of SSE to use.  It falls back to portable code unless
any of extensions detected.

Example of usage
    #include <stdlib.h>
    #include <err.h>
    #include "gost3411-2012-core.h"


    GOST34112012Context *CTX;

    unsigned char digest[64];

        if (posix_memalign(&CTX, (size_t) 16, sizeof(GOST34112012Context)))
            err(EX_OSERR, NULL);

        GOST34112012Init(CTX, 512);
        GOST34112012Update(CTX, buffer, (size_t) bufsize);
        GOST34112012Update(CTX, buffer, (size_t) bufsize);
        /* call GOST34112012Update() for each block of data */
        GOST34112012Final(CTX, &digest[0]);
        /* You now have GOST R 34.11-2012 hash in 'digest' */

Portability notes

Platforms tested
FreeBSD x86/x86_64
Linux   x86/x86_64
Darwin  x86/x86_64
Linux   powerpc

To measure performance of this implementation SUPERCOP toolkit has been
used.  You can set SUPERCOP environment variable to any value and then
run `make configure' to prepare this implementation to run on SUPERCOP.

Intel(R) Pentium(R) CPU G6950 @ 2.80GHz    x86: 40 cycles per byte ( 70 MB/s)
Intel(R) Pentium(R) CPU G6950 @ 2.80GHz x86_64: 36 cycles per byte ( 78 MB/s)
Intel(R) Xeon(R)    CPU X5650 @ 2.67GHz x86_64: 31 cycles per byte ( 84 MB/s)
Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz x86_64: 28 cycles per byte (121 MB/s)

Alexey Degtyarev <alexey@renatasystems.org>