modernc.org/ccgo/v3@v3.16.14/lib/testdata/CompCert-3.6/test/c/sha1.c (about)

     1  /* SHA-1 cryptographic hash function */
     2  /* Ref: Handbook of Applied Cryptography, section 9.4.2, algorithm 9.53 */
     3  
     4  #include <string.h>
     5  #include <stdio.h>
     6  #include <stdlib.h>
     7  
     8  typedef unsigned int u32;
     9  
    10  struct SHA1Context {
    11    u32 state[5];
    12    u32 length[2];
    13    int numbytes;
    14    unsigned char buffer[64];
    15  };
    16  
    17  #define rol1(x) (((x) << 1) | ((x) >> 31))
    18  #define rol5(x) (((x) << 5) | ((x) >> 27))
    19  #define rol30(x) (((x) << 30) | ((x) >> 2))
    20  
    21  static int arch_big_endian;
    22  
    23  static void SHA1_copy_and_swap(void * src, void * dst, int numwords)
    24  {
    25    if (arch_big_endian) {
    26      memcpy(dst, src, numwords * sizeof(u32));
    27    } else {
    28      unsigned char * s, * d;
    29      unsigned char a, b;
    30      for (s = src, d = dst; numwords > 0; s += 4, d += 4, numwords--) {
    31        a = s[0];
    32        b = s[1];
    33        d[0] = s[3];
    34        d[1] = s[2];
    35        d[2] = b;
    36        d[3] = a;
    37      }
    38    }
    39  }
    40  
    41  #define F(x,y,z) ( z ^ (x & (y ^ z) ) )
    42  #define G(x,y,z) ( (x & y) | (z & (x | y) ) )
    43  #define H(x,y,z) ( x ^ y ^ z )
    44  
    45  #define Y1 0x5A827999U
    46  #define Y2 0x6ED9EBA1U
    47  #define Y3 0x8F1BBCDCU
    48  #define Y4 0xCA62C1D6U
    49  
    50  static void SHA1_transform(struct SHA1Context * ctx)
    51  {
    52    int i;
    53    register u32 a, b, c, d, e, t;
    54    u32 data[80];
    55  
    56    /* Convert buffer data to 16 big-endian integers */
    57    SHA1_copy_and_swap(ctx->buffer, data, 16);
    58  
    59    /* Expand into 80 integers */
    60    for (i = 16; i < 80; i++) {
    61      t = data[i-3] ^ data[i-8] ^ data[i-14] ^ data[i-16];
    62      data[i] = rol1(t);
    63    }
    64  
    65    /* Initialize working variables */
    66    a = ctx->state[0];
    67    b = ctx->state[1];
    68    c = ctx->state[2];
    69    d = ctx->state[3];
    70    e = ctx->state[4];
    71  
    72    /* Perform rounds */
    73    for (i = 0; i < 20; i++) {
    74      t = F(b, c, d) + Y1 + rol5(a) + e + data[i];
    75      e = d; d = c; c = rol30(b); b = a; a = t;
    76    }
    77    for (/*nothing*/; i < 40; i++) {
    78      t = H(b, c, d) + Y2 + rol5(a) + e + data[i];
    79      e = d; d = c; c = rol30(b); b = a; a = t;
    80    }
    81    for (/*nothing*/; i < 60; i++) {
    82      t = G(b, c, d) + Y3 + rol5(a) + e + data[i];
    83      e = d; d = c; c = rol30(b); b = a; a = t;
    84    }
    85    for (/*nothing*/; i < 80; i++) {
    86      t = H(b, c, d) + Y4 + rol5(a) + e + data[i];
    87      e = d; d = c; c = rol30(b); b = a; a = t;
    88    }
    89  
    90    /* Update chaining values */
    91    ctx->state[0] += a;
    92    ctx->state[1] += b;
    93    ctx->state[2] += c;
    94    ctx->state[3] += d;
    95    ctx->state[4] += e;
    96  }
    97  
    98  void SHA1_init(struct SHA1Context * ctx)
    99  {
   100    ctx->state[0] = 0x67452301U;
   101    ctx->state[1] = 0xEFCDAB89U;
   102    ctx->state[2] = 0x98BADCFEU;
   103    ctx->state[3] = 0x10325476U;
   104    ctx->state[4] = 0xC3D2E1F0U;
   105    ctx->numbytes = 0;
   106    ctx->length[0] = 0;
   107    ctx->length[1] = 0;
   108  }
   109  
   110  void SHA1_add_data(struct SHA1Context * ctx, unsigned char * data,
   111                     unsigned long len)
   112  {
   113    u32 t;
   114  
   115    /* Update length */
   116    t = ctx->length[1];
   117    if ((ctx->length[1] = t + (u32) (len << 3)) < t)
   118      ctx->length[0]++;    /* carry from low 32 bits to high 32 bits */
   119    ctx->length[0] += (u32) (len >> 29);
   120  
   121    /* If data was left in buffer, pad it with fresh data and munge block */
   122    if (ctx->numbytes != 0) {
   123      t = 64 - ctx->numbytes;
   124      if (len < t) {
   125        memcpy(ctx->buffer + ctx->numbytes, data, len);
   126        ctx->numbytes += len;
   127        return;
   128      }
   129      memcpy(ctx->buffer + ctx->numbytes, data, t);
   130      SHA1_transform(ctx);
   131      data += t;
   132      len -= t;
   133    }
   134    /* Munge data in 64-byte chunks */
   135    while (len >= 64) {
   136      memcpy(ctx->buffer, data, 64);
   137      SHA1_transform(ctx);
   138      data += 64;
   139      len -= 64;
   140    }
   141    /* Save remaining data */
   142    memcpy(ctx->buffer, data, len);
   143    ctx->numbytes = len;
   144  }
   145  
   146  void SHA1_finish(struct SHA1Context * ctx, unsigned char output[20])
   147  {
   148    int i = ctx->numbytes;
   149  
   150    /* Set first char of padding to 0x80. There is always room. */
   151    ctx->buffer[i++] = 0x80;
   152    /* If we do not have room for the length (8 bytes), pad to 64 bytes
   153       with zeroes and munge the data block */
   154    if (i > 56) {
   155      memset(ctx->buffer + i, 0, 64 - i);
   156      SHA1_transform(ctx);
   157      i = 0;
   158    }
   159    /* Pad to byte 56 with zeroes */
   160    memset(ctx->buffer + i, 0, 56 - i);
   161    /* Add length in big-endian */
   162    SHA1_copy_and_swap(ctx->length, ctx->buffer + 56, 2);
   163    /* Munge the final block */
   164    SHA1_transform(ctx);
   165    /* Final hash value is in ctx->state modulo big-endian conversion */
   166    SHA1_copy_and_swap(ctx->state, output, 5);
   167  }
   168  
   169  /* Test harness */
   170  
   171  static void do_test(unsigned char * txt, unsigned char * expected_output)
   172  {
   173    struct SHA1Context ctx;
   174    unsigned char output[20];
   175    int ok;
   176  
   177    SHA1_init(&ctx);
   178    SHA1_add_data(&ctx, txt, strlen((char *) txt));
   179    SHA1_finish(&ctx, output);
   180    ok = memcmp(output, expected_output, 20) == 0;
   181    printf("Test `%s': %s\n",
   182           (char *) txt, (ok ? "passed" : "FAILED"));
   183  }
   184  
   185  /*  Test vectors:
   186   *
   187   *  "abc"
   188   *  A999 3E36 4706 816A BA3E  2571 7850 C26C 9CD0 D89D
   189   *
   190   *  "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
   191   *  8498 3E44 1C3B D26E BAAE  4AA1 F951 29E5 E546 70F1
   192   */
   193  
   194  unsigned char test_input_1[] = "abc";
   195  
   196  unsigned char test_output_1[20] =
   197  { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E ,
   198    0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D };
   199  
   200  unsigned char test_input_2[] =
   201    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
   202  
   203  unsigned char test_output_2[20] =
   204  { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
   205    0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 };
   206  
   207  
   208  static void do_bench(int nblocks)
   209  {
   210    struct SHA1Context ctx;
   211    unsigned char output[20];
   212    unsigned char data[64];
   213    int i;
   214  
   215    for (i = 0; i < 64; i++) data[i] = i;
   216    SHA1_init(&ctx);
   217    for (; nblocks > 0; nblocks--)
   218      SHA1_add_data(&ctx, data, 64);
   219    SHA1_finish(&ctx, output);
   220  }
   221  
   222  int main(int argc, char ** argv)
   223  {
   224    /* Determine endianness */
   225    union { int i; unsigned char b[4]; } u;
   226    u.i = 0x12345678;
   227    switch (u.b[0]) {
   228    case 0x12: arch_big_endian = 1; break;
   229    case 0x78: arch_big_endian = 0; break;
   230    default: printf("Cannot determine endianness\n"); return 2;
   231    }
   232    do_test(test_input_1, test_output_1);
   233    do_test(test_input_2, test_output_2);
   234    do_bench(200000);
   235    return 0;
   236  }