M_hashkeys__sha3 Module

NAME

M_hashkeys__sha3(3fm) - [M_hashkeys__sha3::INTRO] a module implementing the SHA-3 hash function

SYNOPSIS

Procedures:

 use M_hashkeys__sha3, only : sha3
 use M_hashkeys__sha3, only : sha3_update
 use M_hashkeys__sha3, only : sha3_state
 use M_hashkeys__sha3, only : sha3_digest
 use M_hashkeys__sha3, only : sha3_hexdigest
 use M_hashkeys__sha3, only : sha3_file
 use M_hashkeys__sha3, only : sha3_auto_test

DESCRIPTION

This module implements the SHA-3 hash function, according to FIPS
PUB 202, SHA-3 Standard: Permutation-Based Hash and Extendable-Output
Functions, a NIST publication.

Originally based on routines from http://alcinoe.net/fortran.html

In this module, we focus on hashing strings of bytes (as opposed to
strings of bits whose length is not a multiple of 8). We also focus
on providing a fixed-length digest, rather than extendable output. For
us, bytes mean integers of kind 1.

There are two ways of using the module:

  - a functional form, in which the whole array of bytes to hash
    is passed to a function, which returns an array of bytes:

       digest = sha3( buffer, d )

    where d is an integer (default kind) that specifies the digest
    length in bits (so that 'digest' should have a size of d/8)

  - a subroutine form, which is typically used like this:

        type(sha3_state) :: S
        call sha3_update( S, buffer1, d )
        call sha3_update( S, buffer2 )
        ...
        call sha3_digest( S, digest )
    where you pass the data to hash little by little with
    'sha3_update', and finish the process with 'sha3_digest' (after
    you which can start anew with the same state)

According to the standard, the digest size d may be one of 224, 256,
384, 512, which results in arrays of bytes of size 28, 32, 48 and
64. These arrays of bytes can be converted into a hexadecimal string
of length 56, 64, 96 and 128 by calling the 'sha3_hexdigest' function:

     hd = sha3_hexdigest( digest )

If the data to hash is a string, one may convert it to an array of
bytes or integer(kind=int8) using the transfer intrinsic:

   buffer = transfer( string, buffer )

where size(buffer) = len(string)

The final routine exported by the module is sha3_auto_test(), which
hashes some test vectors, as found on:

   http://www.di-mgt.com.au/sha_testvectors.html

and some files in the directory 'test_vectors', for which
the digest was found using the Python implementation from

   https://github.com/gvanas/KeccakCodePackage.

EXAMPLE

Sample program

program demo_M_hashkeys__sha3
use M_hashkeys__sha3
implicit none
character(len=128) :: fname, arg
   call get_command_argument( 1, arg )
   if ( arg(1:1) .eq. '-' ) then
      if ( trim(arg) .eq. '-a' ) then
         call sha3_auto_test()
      else
         call get_command_argument( 2, fname )
        select case(trim(arg))
        case('-224'); call sha3_file( 224, trim(fname) )
        case('-256'); call sha3_file( 256, trim(fname) )
        case('-384'); call sha3_file( 384, trim(fname) )
        case('-512'); call sha3_file( 512, trim(fname) )
        case default
            print *,'usage: "sha3 -a" or "sha3 (-224|-256|-384|-512) fname"'
        end select
      endif
   else
      print *, 'usage: "sha3 -a" or "sha3 (-224|-256|-384|-512) fname"'
      print *, 'usage: "sha3 -a" or "sha3 (-224|-256|-384|-512) fname"'
   endif

end program demo_M_hashkeys__sha3


Uses


Derived Types

type, public ::  sha3_state

Components

Type Visibility Attributes Name Initial
integer(kind=int64), public, dimension(5,5) :: S
integer(kind=int8), public, dimension(:), pointer :: buffer
integer, public :: bufsize = -1
integer, public :: c
integer, public :: d
integer, public :: r

Functions

public function sha3(buffer, d)

Arguments

Type IntentOptional Attributes Name
integer(kind=int8), intent(in), dimension(:) :: buffer
integer, intent(in) :: d

Return Value ../../../integer(kind=int8), dimension(d/8)

public function sha3_hexdigest(d)

Arguments

Type IntentOptional Attributes Name
integer(kind=int8), intent(in), dimension(:) :: d

Return Value character(len=size)


Subroutines

public subroutine sha3_auto_test()

Arguments

None

public subroutine sha3_digest(state, digest)

!GFORTRAN 8.3 BUG!*!state%buffer( state%r/8 ) = transfer(int(b‘10000110’,kind=int8),state%buffer(1))

Read more…

Arguments

Type IntentOptional Attributes Name
type(sha3_state), intent(inout) :: state
integer(kind=int8), intent(out), dimension(:) :: digest

public subroutine sha3_file(d, fname, hdigest)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: d
character(len=*), intent(in) :: fname
character(len=*), intent(out), optional :: hdigest

public subroutine sha3_update(state, buffer, d)

Arguments

Type IntentOptional Attributes Name
type(sha3_state), intent(inout) :: state
integer(kind=int8), intent(in), dimension(:) :: buffer
integer, intent(in), optional :: d

public subroutine test_suite_M_hashkeys__sha3()

setup teardown

Arguments

None