[svn:parrot] r49806 - in trunk: . runtime/parrot/library/Digest

gerd at svn.parrot.org gerd at svn.parrot.org
Mon Nov 8 11:30:07 UTC 2010


Author: gerd
Date: Mon Nov  8 11:30:06 2010
New Revision: 49806
URL: https://trac.parrot.org/parrot/changeset/49806

Log:
add a sha256 message digest function from the SHA-2 family

Added:
   trunk/runtime/parrot/library/Digest/sha256.pir   (contents, props changed)
Modified:
   trunk/MANIFEST

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Mon Nov  8 03:26:48 2010	(r49805)
+++ trunk/MANIFEST	Mon Nov  8 11:30:06 2010	(r49806)
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Mon Nov  1 23:38:16 2010 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Mon Nov  8 10:35:52 2010 UT
 #
 # See below for documentation on the format of this file.
 #
@@ -1163,6 +1163,7 @@
 runtime/parrot/library/Data/Dumper/Base.pir                 [library]
 runtime/parrot/library/Data/Dumper/Default.pir              [library]
 runtime/parrot/library/Digest/MD5.pir                       [library]
+runtime/parrot/library/Digest/sha256.pir                    [library]
 runtime/parrot/library/Getopt/Obj.pir                       [library]
 runtime/parrot/library/HTTP/Daemon.pir                      [library]
 runtime/parrot/library/HTTP/Message.pir                     [library]

Added: trunk/runtime/parrot/library/Digest/sha256.pir
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/runtime/parrot/library/Digest/sha256.pir	Mon Nov  8 11:30:06 2010	(r49806)
@@ -0,0 +1,723 @@
+# Copyright (C) 2010, Parrot Foundation.
+# $Id$
+#
+# Parrot SHA-2 library; Gerd Pokorra <gp at zimt.uni-siegen.de>
+#
+# Based on sha256.c, from sha256sum
+#           written by David Madore
+#
+# Functions that are from the SHA-2 family to compute SHA-224 and SHA-256
+# message digest according to the NIST specification FIPS 180-3:
+# http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
+#
+# NIST = National Institute of Standards and Technology
+# FIPS = Federal Information Processing Standards
+
+# This is the start of the implemation and sha224 is not done yet!
+
+=head1 NAME
+
+sha256.pir - calculates message digest checksums
+
+=head1 SYNOPSIS
+
+  load_bytecode "Digest/sha256.pbc"
+  $P0 = sha256sum("foo")
+  sha256_print($P0)
+
+or
+
+  load_bytecode "Digest/sha256.pbc"
+  $P0 = sha256sum("bar")
+  $S0 = sha256_hex($P0)
+
+=head1 DESCRIPTION
+
+This is a pure Parrot sha256 hash routine. You should run it with the JIT
+core if possible.
+
+=head1 SUBROUTINES
+
+=head2 sha256sum
+
+Pass in a string, returns an Integer array with the result.
+
+=head2 sha256_hex
+
+Pass it the Integer array from sha256sum to get the checksum as string.
+
+=head2 sha256_print
+
+Pass it the Integer array to print the checksum.
+
+=head1 BUGS
+
+Still has some limitations on input buffer size, largely due to memory
+consumption which should be resolved soon.
+
+=cut
+
+
+.HLL 'parrot'
+
+#.loadlib 'bit_ops'
+
+###########################################################################
+
+# Export function entries to globals
+
+.sub onload :load
+
+    .local pmc f
+    f = get_hll_global ['Digest'], '_sha256sum'
+    set_global "sha256sum", f
+    f = get_hll_global ['Digest'], '_sha256_hex'
+    set_global "sha256_hex", f
+    f = get_hll_global ['Digest'], '_sha256_print'
+    set_global "sha256_print", f
+.end
+
+###########################################################################
+
+# Main backend entry point
+
+.namespace ["Digest"]
+
+.sub _sha256sum
+    .param string str
+
+    .local pmc context
+    context = new 'FixedIntegerArray'
+    context = 8
+
+    .local pmc buffer
+    buffer = _sha256_create_buffer (str)
+
+    _sha256_init (context)
+    _sha256_process_buffer (context, buffer)
+
+    .return (context)
+.end
+
+
+###########################################################################
+
+# Create an internal scratchpad buffer
+
+.sub _sha256_create_buffer
+    .param string str
+
+    .local pmc buffer
+    buffer = new 'FixedIntegerArray'
+
+    .local int counter
+    .local int subcounter
+    .local int slow_counter
+
+    .local int word, len
+
+     len = length str
+
+     $I1 = len - 1
+
+     # Work out how many words to allocate
+     .local int words
+     words  = len + 8
+     words |= 63
+     inc words
+     words /= 4
+
+     buffer = words
+
+     word         = 0
+     counter      = 0
+     subcounter   = 0
+     slow_counter = 0
+
+create_buffer_loop:
+
+     $I5 = counter + subcounter
+
+     if $I5 > len goto create_buffer_break
+
+     # pad character, which goes last (append the bit "1" to the end of the
+     #                                 message)
+     $I4 = 0x80
+
+     if $I5 > $I1 goto string_char
+     $I4 = ord str, $I5
+
+string_char:
+
+     word <<= 8
+     word  |= $I4
+
+     inc subcounter
+     if subcounter != 4 goto create_buffer_loop
+
+     word = _byte_order (word)
+
+     buffer[slow_counter] = word
+
+     word       = 0
+     counter   += 4
+     subcounter = 0
+     inc slow_counter
+
+     goto create_buffer_loop
+
+create_buffer_break:
+
+     # Check for a partial word
+
+     if subcounter == 0 goto complete
+     subcounter = 4 - subcounter
+     $I0    = 8*subcounter
+     word <<= $I0
+
+     word = _byte_order (word)
+
+     buffer[slow_counter] = word
+
+complete:
+
+     # The length of the string go into the last two words (64 bits)
+
+     $I0 = len << 3
+     dec words
+     $I0 = _byte_order ($I0)
+     buffer[words] = $I0
+
+     $I0 = len >>> 29
+     dec words
+     buffer[words] = $I0
+
+     .return (buffer)
+.end
+
+###########################################################################
+
+# Pass in the Interger array and return the final checksum as a string
+
+.sub _sha256_hex
+    .param pmc context
+
+    $S0 = sprintf "%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx", context
+
+    .return ($S0)
+.end
+
+###########################################################################
+
+# Convenience subroutine to print the Message Digest
+# - Pass in the Integer array
+# - Retrieve the final checksum as a string
+# - Print the Message Digest
+
+.sub _sha256_print
+    .param pmc context
+
+    $S0 = _sha256_hex (context)
+    print $S0
+
+    .return ($S0)
+.end
+
+###########################################################################
+
+# Set the start constants of the SHA256 algorithm
+
+.sub _sha256_init
+    .param pmc context
+
+    # Initial constants
+    context[0] = 0x6a09e667
+    context[1] = 0xbb67ae85
+    context[2] = 0x3c6ef372
+    context[3] = 0xa54ff53a
+    context[4] = 0x510e527f
+    context[5] = 0x9b05688c
+    context[6] = 0x1f83d9ab
+    context[7] = 0x5be0cd19
+
+.end
+
+###########################################################################
+
+.sub _Ch
+    .param pmc context
+
+    .local int E, F, G, result 
+
+    E = context[4]
+    F = context[5]
+    G = context[6]
+
+    # Ch(x,y,z) = ( x and y ) xor ( not(x) and z ) = z xor ( x and ( y xor z )
+    # here as:    Ch(E,F,G)                        = G xor ( E and ( F xor G )
+    result = bxor F, G
+    result = band E, result
+    result = bxor G, result
+
+    .return (result)
+.end
+
+###########################################################################
+
+.sub _Maj
+    .param pmc context
+
+    .local int A, B, C, extension, result
+
+    A = context[0]
+    B = context[1]
+    C = context[2]
+ 
+    # Maj(x,y,z) = ( x and y ) xor ( x and z ) xor ( y and z )
+    #            = ( x and y ) or ( z and ( x or y ) )
+    # here as: Maj(A,B,C) = ( A and B ) or ( C and ( A or B ) )
+    result = bor A, B
+    result = band C, result
+    extension = band A, B
+    result = bor extension, result
+
+    .return (result)
+.end
+
+###########################################################################
+
+.sub _rotate_right
+    # circular right shift operation, where x is a 32-bit word and n is an
+    # integer
+    .param int x
+    .param int n
+
+    .local int extension, result
+    extension = shr x, n 
+
+    result = 32 - n
+    result = shl x, result
+    # For 64-bit architectures, to remove leading 32-bit
+    result = band result, 0xffffffff
+
+    result = bor extension, result
+
+    .return (result) 
+.end
+
+###########################################################################
+
+.sub _Sigma_0
+    .param pmc context
+
+    .local int A, intermediate, result
+
+    A = context[0]
+
+    intermediate = _rotate_right( A, 2 )
+    result = _rotate_right( A, 13 )
+    result = bxor intermediate, result
+
+    intermediate = _rotate_right( A, 22 )
+    result = bxor intermediate, result
+
+    .return (result)
+.end
+
+###########################################################################
+
+.sub _Sigma_1
+    .param pmc context
+
+    .local int E, intermediate, result
+
+    E = context[4]
+
+    intermediate = _rotate_right( E, 6 )
+    result = _rotate_right( E, 11 )
+    result = bxor intermediate, result
+
+    intermediate = _rotate_right( E, 25 )
+    result = bxor intermediate, result
+
+    .return (result)
+.end
+
+###########################################################################
+
+.sub _sigma0
+    .param int value
+
+    .local int intermediate, result
+   
+    intermediate = _rotate_right( value, 7 )
+    result = _rotate_right( value, 18 )
+    result = bxor intermediate, result
+
+    intermediate = shr value, 3
+    result = bxor intermediate, result
+
+    .return (result)
+.end
+
+###########################################################################
+
+.sub _sigma1
+    .param int value
+
+    .local int intermediate, result
+   
+    intermediate = _rotate_right( value, 17 )
+    result = _rotate_right( value, 19 )
+    result = bxor intermediate, result
+
+    intermediate = shr value, 10
+    result = bxor intermediate, result
+
+    .return (result)
+.end
+
+###########################################################################
+
+.sub _byte_order
+    # If the byte oder (byte sex) is big-endian, then nothing is to do
+    # here, that is not implemented and has to been fixed
+    .param int w
+    .local int part1, part2, part3, part4
+
+    part1 = w & 0x000000ff
+    part2 = w & 0x0000ff00
+    part3 = w & 0x00ff0000
+    part4 = w & 0xff000000
+
+    part1 = part1 <<  24
+    part2 = part2 <<  8
+    part3 = part3 >>> 8
+    part4 = part4 >>> 24
+
+    part1 |= part2
+    part1 |= part3
+    part1 |= part4
+
+    # For 64-bit architectures
+    part1 = part1 & 0xffffffff
+
+    .return (part1)
+.end
+
+###########################################################################
+
+.sub _W_from_t
+    .param pmc message
+    .param int m_index
+
+    .local int tmp, result
+
+    tmp = m_index - 2
+    tmp = band tmp, 0x0f
+    tmp = message[tmp]
+    tmp = _sigma1 (tmp)
+
+    result = m_index - 7
+    result = band result, 0x0f
+    result = message[result]
+
+    result += tmp
+
+    tmp = m_index - 15
+    tmp = band tmp, 0x0f
+    tmp = message[tmp]
+    tmp = _sigma0 (tmp)
+
+    result += tmp
+
+    tmp = band m_index, 0x0f
+    tmp = message[tmp]
+
+    result += tmp
+    result = band result, 0xffffffff
+
+    tmp = band m_index, 0x0f
+    message[tmp] = result
+
+    .return (result)
+.end 
+
+###########################################################################
+
+.sub _sha256_process_block
+    .param pmc context
+    .param pmc buffer
+
+    .local int a_save, b_save, c_save, d_save, e_save, f_save, g_save, h_save
+    a_save = context[0]
+    b_save = context[1]
+    c_save = context[2]
+    d_save = context[3]
+    e_save = context[4]
+    f_save = context[5]
+    g_save = context[6]
+    h_save = context[7]
+
+    # 64 round constants as 32-bit words
+    .local pmc K
+    K = new 'FixedIntegerArray'
+    K = 64
+    K[0]  = 0x428a2f98
+    K[1]  = 0x71374491
+    K[2]  = 0xb5c0fbcf
+    K[3]  = 0xe9b5dba5
+    K[4]  = 0x3956c25b
+    K[5]  = 0x59f111f1
+    K[6]  = 0x923f82a4
+    K[7]  = 0xab1c5ed5
+    K[8]  = 0xd807aa98
+    K[9]  = 0x12835b01
+    K[10] = 0x243185be
+    K[11] = 0x550c7dc3
+    K[12] = 0x72be5d74
+    K[13] = 0x80deb1fe
+    K[14] = 0x9bdc06a7
+    K[15] = 0xc19bf174
+    K[16] = 0xe49b69c1
+    K[17] = 0xefbe4786
+    K[18] = 0x0fc19dc6
+    K[19] = 0x240ca1cc
+    K[20] = 0x2de92c6f
+    K[21] = 0x4a7484aa
+    K[22] = 0x5cb0a9dc
+    K[23] = 0x76f988da
+    K[24] = 0x983e5152
+    K[25] = 0xa831c66d
+    K[26] = 0xb00327c8
+    K[27] = 0xbf597fc7
+    K[28] = 0xc6e00bf3
+    K[29] = 0xd5a79147
+    K[30] = 0x06ca6351
+    K[31] = 0x14292967
+    K[32] = 0x27b70a85
+    K[33] = 0x2e1b2138
+    K[34] = 0x4d2c6dfc
+    K[35] = 0x53380d13
+    K[36] = 0x650a7354
+    K[37] = 0x766a0abb
+    K[38] = 0x81c2c92e
+    K[39] = 0x92722c85
+    K[40] = 0xa2bfe8a1
+    K[41] = 0xa81a664b
+    K[42] = 0xc24b8b70
+    K[43] = 0xc76c51a3
+    K[44] = 0xd192e819
+    K[45] = 0xd6990624
+    K[46] = 0xf40e3585
+    K[47] = 0x106aa070
+    K[48] = 0x19a4c116
+    K[49] = 0x1e376c08
+    K[50] = 0x2748774c
+    K[51] = 0x34b0bcb5
+    K[52] = 0x391c0cb3
+    K[53] = 0x4ed8aa4a
+    K[54] = 0x5b9cca4f
+    K[55] = 0x682e6ff3
+    K[56] = 0x748f82ee
+    K[57] = 0x78a5636f
+    K[58] = 0x84c87814
+    K[59] = 0x8cc70208
+    K[60] = 0x90befffa
+    K[61] = 0xa4506ceb
+    K[62] = 0xbef9a3f7
+    K[63] = 0xc67178f2
+
+    .local int Ki, T1, T2, tmp
+    .local pmc M_t
+    M_t = new 'FixedIntegerArray'
+    M_t = 16
+    .local int counter
+    counter = 0
+
+LOOP:   if counter > 63 goto DONE
+    # part 1 from the calculation of T1
+    tmp = _Sigma_1 (context)
+    T1 = context[7]
+    T1 += tmp
+    tmp = _Ch (context)
+    T1 += tmp
+    Ki = K [counter]
+    T1 = T1 + Ki
+    T1 = band T1, 0xffffffff
+
+    # calculataion of T2
+    T2 = _Sigma_0 (context)
+    tmp = _Maj (context)
+    T2 += tmp
+    T2 = band T2, 0xffffffff
+
+    if counter < 16 goto NIL_TO_15
+
+    # calculation of W(t) from 16 to 63
+    tmp = _W_from_t (M_t, counter)
+    T1 += tmp
+
+    goto COMMON_CHANGE_PART
+
+NIL_TO_15:
+    # part 2 from the calculation of T1
+    # change the byte-order 
+    tmp = buffer[counter]
+    tmp = _byte_order(tmp)
+
+    # add to the message block
+    M_t[counter] = tmp
+
+    T1 = T1 + tmp       # that is T1
+    T1 = band T1, 0xffffffff
+
+COMMON_CHANGE_PART:
+    # set context for next round
+    tmp = context[6]
+    context[7] = tmp            # h=g
+    tmp = context[5]
+    context[6] = tmp            # g=f
+    tmp = context[4]
+    context[5] = tmp            # f=e
+    tmp = context[3]
+    tmp += T1
+    tmp = tmp & 0xffffffff
+    context[4] = tmp            # e=d+T1
+    tmp = context[2]
+    context[3] = tmp            # d=c
+    tmp = context[1]
+    context[2] = tmp            # c=b
+    tmp = context[0]
+    context[1] = tmp            # b=a
+    tmp = T1 + T2
+    tmp = tmp & 0xffffffff
+    context[0] = tmp            # a=T1+T2
+
+    inc counter
+    goto LOOP
+
+DONE:
+    tmp = context[0]
+    a_save += tmp
+    a_save = a_save & 0xffffffff
+    context[0] = a_save
+    tmp = context[1]
+    b_save += tmp
+    b_save = b_save & 0xffffffff
+    context[1] = b_save
+    tmp = context[2]
+    c_save += tmp
+    c_save = c_save & 0xffffffff
+    context[2] = c_save
+    tmp = context[3]
+    d_save += tmp
+    d_save = d_save & 0xffffffff
+    context[3] = d_save
+    tmp = context[4]
+    e_save += tmp
+    e_save = e_save & 0xffffffff
+    context[4] = e_save
+    tmp = context[5]
+    f_save += tmp
+    f_save = f_save & 0xffffffff
+    context[5] = f_save
+    tmp = context[6]
+    g_save += tmp
+    g_save = g_save & 0xffffffff
+    context[6] = g_save
+    tmp = context[7]
+    h_save += tmp
+    h_save = h_save & 0xffffffff
+    context[7] = h_save
+.end
+
+###########################################################################
+
+.sub _sha256_process_buffer
+    .param pmc context
+    .param pmc buffer
+
+    .local int idx, i2, len, tmp
+    .local pmc part
+
+    part = new 'FixedIntegerArray'
+    part = 16
+
+    idx = 0
+    i2 = 0
+    len = elements buffer
+
+BLOCK_LOOP:
+    tmp = idx + i2
+    tmp = buffer[tmp]
+    part[i2] = tmp
+    inc i2
+    if i2 < 16 goto BLOCK_LOOP
+
+    _sha256_process_block (context, part)
+
+    idx += 16
+    i2 = 0
+    if idx < len goto BLOCK_LOOP
+
+.end
+
+## Functions that could be used for debugging
+###########################################################################
+
+.sub _print_integer_in_hex_format
+    .param int hex_num
+    $P0 = new 'FixedIntegerArray'
+    $P0 = 1
+    $P0[0] = hex_num 
+    $S0 = sprintf "%08lx", $P0 
+
+    print 'value in hex-format: '
+    say $S0
+    #say ''
+.end
+
+###########################################################################
+
+.sub _print_round
+    .param pmc context
+
+    $S0 = sprintf "%08X %08X %08X %08X %08X %08X %08X %08X", context
+    say $S0
+.end
+
+###########################################################################
+
+.sub _print_message
+    .param pmc buffer
+
+    .local int idx, i2, len, tmp
+    .local pmc part
+
+    part = new 'FixedIntegerArray'
+    part = 16
+
+    idx = 0
+    i2 = 0
+    len = elements buffer
+
+AGAIN:
+    tmp = idx + i2
+    tmp = buffer[tmp]
+    part[i2] = tmp
+    inc i2
+    if i2 < 16 goto AGAIN
+    sprintf $S0, " 0: %08x\n 1: %08x\n 2: %08x\n 3: %08x\n 4: %08x\n 5: %08x\n 6: %08x\n 7: %08x\n 8: %08x\n 9: %08x\n10: %08x\n11: %08x\n12: %08x\n13: %08x\n14: %08x\n15: %08x\n", part
+    say $S0
+
+    idx += 16
+    i2 = 0
+    if idx < len goto AGAIN
+.end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:


More information about the parrot-commits mailing list