[glib] gchecksum: Adds SHA512 support



commit 6e2046207a2fe1c013bbf348b87d54a1375dea7a
Author: Eduardo Lima Mitev <elima igalia com>
Date:   Fri Nov 16 18:20:09 2012 +0100

    gchecksum: Adds SHA512 support
    
    https://bugzilla.gnome.org/show_bug.cgi?id=602715

 glib/gchecksum.c      |  317 ++++++++++++++++++++++++++++++++++++++++++++++++-
 glib/gchecksum.h      |    4 +-
 glib/tests/checksum.c |  192 ++++++++++++++++++++++++++++++
 3 files changed, 511 insertions(+), 2 deletions(-)
---
diff --git a/glib/gchecksum.c b/glib/gchecksum.c
index 2920479..cf0ea9b 100644
--- a/glib/gchecksum.c
+++ b/glib/gchecksum.c
@@ -54,7 +54,7 @@
  * Support for checksums has been added in GLib 2.16
  **/
 
-#define IS_VALID_TYPE(type)     ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA256)
+#define IS_VALID_TYPE(type)     ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA512)
 
 /* The fact that these are lower case characters is part of the ABI */
 static const gchar hex_digits[] = "0123456789abcdef";
@@ -102,6 +102,21 @@ typedef struct
   guchar digest[SHA256_DIGEST_LEN];
 } Sha256sum;
 
+#define SHA512_BLOCK_LEN       128 /* 1024 bits message block */
+#define SHA512_DIGEST_LEN       64
+
+typedef struct
+{
+  guint64 H[8];
+
+  guint8 block[SHA512_BLOCK_LEN];
+  guint8 block_len;
+
+  guint64 data_len[2];
+
+  guchar digest[SHA512_DIGEST_LEN];
+} Sha512sum;
+
 struct _GChecksum
 {
   GChecksumType type;
@@ -112,6 +127,7 @@ struct _GChecksum
     Md5sum md5;
     Sha1sum sha1;
     Sha256sum sha256;
+    Sha512sum sha512;
   } sum;
 };
 
@@ -1069,6 +1085,284 @@ sha256_sum_digest (Sha256sum *sha256,
     digest[i] = sha256->digest[i];
 }
 
+/*
+ * SHA-512 Checksum
+ *
+ * Implemented following FIPS-180-2 standard at
+ * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf.
+ * References in the form [Âx.y.z] map to sections in that document.
+ *
+ *   Author: Eduardo Lima Mitev <elima igalia com>
+ */
+
+/* SHA-384 and SHA-512 functions [Â4.1.3] */
+#define Ch(x,y,z)  ((x & y) ^ (~x & z))
+#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
+#define SHR(n,x)   (x >> n)
+#define ROTR(n,x)  (SHR (n, x) | (x << (64 - n)))
+#define SIGMA0(x)  (ROTR (28, x) ^ ROTR (34, x) ^ ROTR (39, x))
+#define SIGMA1(x)  (ROTR (14, x) ^ ROTR (18, x) ^ ROTR (41, x))
+#define sigma0(x)  (ROTR ( 1, x) ^ ROTR ( 8, x) ^ SHR  ( 7, x))
+#define sigma1(x)  (ROTR (19, x) ^ ROTR (61, x) ^ SHR  ( 6, x))
+
+#define PUT_UINT64(n,b,i)                G_STMT_START{   \
+    (b)[(i)    ] = (guint8) (n >> 56);                   \
+    (b)[(i) + 1] = (guint8) (n >> 48);                   \
+    (b)[(i) + 2] = (guint8) (n >> 40);                   \
+    (b)[(i) + 3] = (guint8) (n >> 32);                   \
+    (b)[(i) + 4] = (guint8) (n >> 24);                   \
+    (b)[(i) + 5] = (guint8) (n >> 16);                   \
+    (b)[(i) + 6] = (guint8) (n >>  8);                   \
+    (b)[(i) + 7] = (guint8) (n      ); } G_STMT_END
+
+static void
+sha512_sum_init (Sha512sum *sha512)
+{
+  /* Initial Hash Value [Â5.3.4] */
+  sha512->H[0] = 0x6a09e667f3bcc908;
+  sha512->H[1] = 0xbb67ae8584caa73b;
+  sha512->H[2] = 0x3c6ef372fe94f82b;
+  sha512->H[3] = 0xa54ff53a5f1d36f1;
+  sha512->H[4] = 0x510e527fade682d1;
+  sha512->H[5] = 0x9b05688c2b3e6c1f;
+  sha512->H[6] = 0x1f83d9abfb41bd6b;
+  sha512->H[7] = 0x5be0cd19137e2179;
+
+  sha512->block_len = 0;
+
+  sha512->data_len[0] = 0;
+  sha512->data_len[1] = 0;
+}
+
+/* SHA-384 and SHA-512 constants [Â4.2.3] */
+static const guint64 SHA512_K[80] = {
+  0x428a2f98d728ae22, 0x7137449123ef65cd,
+  0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
+  0x3956c25bf348b538, 0x59f111f1b605d019,
+  0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
+  0xd807aa98a3030242, 0x12835b0145706fbe,
+  0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
+  0x72be5d74f27b896f, 0x80deb1fe3b1696b1,
+  0x9bdc06a725c71235, 0xc19bf174cf692694,
+  0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
+  0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
+  0x2de92c6f592b0275, 0x4a7484aa6ea6e483,
+  0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
+  0x983e5152ee66dfab, 0xa831c66d2db43210,
+  0xb00327c898fb213f, 0xbf597fc7beef0ee4,
+  0xc6e00bf33da88fc2, 0xd5a79147930aa725,
+  0x06ca6351e003826f, 0x142929670a0e6e70,
+  0x27b70a8546d22ffc, 0x2e1b21385c26c926,
+  0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
+  0x650a73548baf63de, 0x766a0abb3c77b2a8,
+  0x81c2c92e47edaee6, 0x92722c851482353b,
+  0xa2bfe8a14cf10364, 0xa81a664bbc423001,
+  0xc24b8b70d0f89791, 0xc76c51a30654be30,
+  0xd192e819d6ef5218, 0xd69906245565a910,
+  0xf40e35855771202a, 0x106aa07032bbd1b8,
+  0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
+  0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
+  0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
+  0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
+  0x748f82ee5defb2fc, 0x78a5636f43172f60,
+  0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+  0x90befffa23631e28, 0xa4506cebde82bde9,
+  0xbef9a3f7b2c67915, 0xc67178f2e372532b,
+  0xca273eceea26619c, 0xd186b8c721c0c207,
+  0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
+  0x06f067aa72176fba, 0x0a637dc5a2c898a6,
+  0x113f9804bef90dae, 0x1b710b35131c471b,
+  0x28db77f523047d84, 0x32caab7b40c72493,
+  0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
+  0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
+  0x5fcb6fab3ad6faec, 0x6c44198c4a475817
+};
+
+static void
+sha512_transform (guint64      H[8],
+                  guint8 const data[SHA512_BLOCK_LEN])
+{
+  gint i;
+  gint t;
+  guint64 a, b, c, d, e, f, g, h;
+  guint64 M[16];
+  guint64 W[80];
+
+  /* SHA-512 hash computation [Â6.3.2] */
+
+  /* prepare the message schedule */
+  for (i = 0; i < 16; i++)
+    {
+      gint p = i * 8;
+
+      M[i] =
+        ((guint64) data[p + 0] << 56) |
+        ((guint64) data[p + 1] << 48) |
+        ((guint64) data[p + 2] << 40) |
+        ((guint64) data[p + 3] << 32) |
+        ((guint64) data[p + 4] << 24) |
+        ((guint64) data[p + 5] << 16) |
+        ((guint64) data[p + 6] <<  8) |
+        ((guint64) data[p + 7]      );
+    }
+
+  for (t = 0; t < 80; t++)
+    if (t < 16)
+      W[t] = M[t];
+    else
+      W[t] = sigma1 (W[t - 2]) + W[t - 7] + sigma0 (W[t - 15]) + W[t - 16];
+
+  /* initialize the eight working variables */
+  a = H[0];
+  b = H[1];
+  c = H[2];
+  d = H[3];
+  e = H[4];
+  f = H[5];
+  g = H[6];
+  h = H[7];
+
+  for (t = 0; t < 80; t++)
+    {
+      guint64 T1, T2;
+
+      T1 = h + SIGMA1 (e) + Ch (e, f, g) + SHA512_K[t] + W[t];
+      T2 = SIGMA0 (a) + Maj (a, b, c);
+      h = g;
+      g = f;
+      f = e;
+      e = d + T1;
+      d = c;
+      c = b;
+      b = a;
+      a = T1 + T2;
+    }
+
+  /* Compute the intermediate hash value H */
+  H[0] += a;
+  H[1] += b;
+  H[2] += c;
+  H[3] += d;
+  H[4] += e;
+  H[5] += f;
+  H[6] += g;
+  H[7] += h;
+}
+
+static void
+sha512_sum_update (Sha512sum    *sha512,
+                   const guchar *buffer,
+                   gsize         length)
+{
+  gsize block_left, offset = 0;
+
+  if (length == 0)
+    return;
+
+  sha512->data_len[0] += length * 8;
+  if (sha512->data_len[0] < length)
+    sha512->data_len[1]++;
+
+  /* try to fill current block */
+  block_left = SHA512_BLOCK_LEN - sha512->block_len;
+  if (block_left > 0)
+    {
+      gsize fill_len;
+
+      fill_len = MIN (block_left, length);
+      memcpy (sha512->block + sha512->block_len, buffer, fill_len);
+      sha512->block_len += fill_len;
+      length -= fill_len;
+      offset += fill_len;
+
+      if (sha512->block_len == SHA512_BLOCK_LEN)
+        {
+          sha512_transform (sha512->H, sha512->block);
+          sha512->block_len = 0;
+        }
+    }
+
+  /* process complete blocks */
+  while (length >= SHA512_BLOCK_LEN)
+    {
+      memcpy (sha512->block, buffer + offset, SHA512_BLOCK_LEN);
+
+      sha512_transform (sha512->H, sha512->block);
+
+      length -= SHA512_BLOCK_LEN;
+      offset += SHA512_BLOCK_LEN;
+    }
+
+  /* keep remaining data for next block */
+  if (length > 0)
+    {
+      memcpy (sha512->block, buffer + offset, length);
+      sha512->block_len = length;
+    }
+}
+
+static void
+sha512_sum_close (Sha512sum *sha512)
+{
+  guint l;
+  gint zeros;
+  guint8 pad[SHA512_BLOCK_LEN * 2] = { 0, };
+  guint pad_len = 0;
+  gint i;
+
+  /* apply padding [Â5.1.2] */
+  l = sha512->block_len * 8;
+  zeros = 896 - (l + 1);
+
+  if (zeros < 0)
+    zeros += 128 * 8;
+
+  pad[0] = 0x80; /* 1000 0000 */
+  zeros -= 7;
+  pad_len++;
+
+  memset (pad + pad_len, 0x00, zeros / 8);
+  pad_len += zeros / 8;
+  zeros = zeros % 8;
+
+  /* put message bit length at the end of padding */
+  PUT_UINT64 (sha512->data_len[1], pad, pad_len);
+  pad_len += 8;
+
+  PUT_UINT64 (sha512->data_len[0], pad, pad_len);
+  pad_len += 8;
+
+  /* update checksum with the padded block */
+  sha512_sum_update (sha512, pad, pad_len);
+
+  /* copy resulting 64-bit words into digest */
+  for (i = 0; i < 8; i++)
+    PUT_UINT64 (sha512->H[i], sha512->digest, i * 8);
+}
+
+static gchar *
+sha512_sum_to_string (Sha512sum *sha512)
+{
+  return digest_to_string (sha512->digest, SHA512_DIGEST_LEN);
+}
+
+static void
+sha512_sum_digest (Sha512sum *sha512,
+                   guint8    *digest)
+{
+  memcpy (digest, sha512->digest, SHA512_DIGEST_LEN);
+}
+
+#undef Ch
+#undef Maj
+#undef SHR
+#undef ROTR
+#undef SIGMA0
+#undef SIGMA1
+#undef sigma0
+#undef sigma1
+
+#undef PUT_UINT64
 
 /*
  * Public API
@@ -1101,6 +1395,9 @@ g_checksum_type_get_length (GChecksumType checksum_type)
     case G_CHECKSUM_SHA256:
       len = SHA256_DIGEST_LEN;
       break;
+    case G_CHECKSUM_SHA512:
+      len = SHA512_DIGEST_LEN;
+      break;
     default:
       len = -1;
       break;
@@ -1175,6 +1472,9 @@ g_checksum_reset (GChecksum *checksum)
     case G_CHECKSUM_SHA256:
       sha256_sum_init (&(checksum->sum.sha256));
       break;
+    case G_CHECKSUM_SHA512:
+      sha512_sum_init (&(checksum->sum.sha512));
+      break;
     default:
       g_assert_not_reached ();
       break;
@@ -1270,6 +1570,9 @@ g_checksum_update (GChecksum    *checksum,
     case G_CHECKSUM_SHA256:
       sha256_sum_update (&(checksum->sum.sha256), data, length);
       break;
+    case G_CHECKSUM_SHA512:
+      sha512_sum_update (&(checksum->sum.sha512), data, length);
+      break;
     default:
       g_assert_not_reached ();
       break;
@@ -1317,6 +1620,10 @@ g_checksum_get_string (GChecksum *checksum)
       sha256_sum_close (&(checksum->sum.sha256));
       str = sha256_sum_to_string (&(checksum->sum.sha256));
       break;
+    case G_CHECKSUM_SHA512:
+      sha512_sum_close (&(checksum->sum.sha512));
+      str = sha512_sum_to_string (&(checksum->sum.sha512));
+      break;
     default:
       g_assert_not_reached ();
       break;
@@ -1384,6 +1691,14 @@ g_checksum_get_digest (GChecksum  *checksum,
         }
       sha256_sum_digest (&(checksum->sum.sha256), buffer);
       break;
+    case G_CHECKSUM_SHA512:
+      if (checksum_open)
+        {
+          sha512_sum_close (&(checksum->sum.sha512));
+          str = sha512_sum_to_string (&(checksum->sum.sha512));
+        }
+      sha512_sum_digest (&(checksum->sum.sha512), buffer);
+      break;
     default:
       g_assert_not_reached ();
       break;
diff --git a/glib/gchecksum.h b/glib/gchecksum.h
index b0621f2..be6ab65 100644
--- a/glib/gchecksum.h
+++ b/glib/gchecksum.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
  * @G_CHECKSUM_MD5: Use the MD5 hashing algorithm
  * @G_CHECKSUM_SHA1: Use the SHA-1 hashing algorithm
  * @G_CHECKSUM_SHA256: Use the SHA-256 hashing algorithm
+ * @G_CHECKSUM_SHA512: Use the SHA-512 hashing algorithm
  *
  * The hashing algorithm to be used by #GChecksum when performing the
  * digest of some data.
@@ -47,7 +48,8 @@ G_BEGIN_DECLS
 typedef enum {
   G_CHECKSUM_MD5,
   G_CHECKSUM_SHA1,
-  G_CHECKSUM_SHA256
+  G_CHECKSUM_SHA256,
+  G_CHECKSUM_SHA512
 } GChecksumType;
 
 /**
diff --git a/glib/tests/checksum.c b/glib/tests/checksum.c
index 3bf8164..900a538 100644
--- a/glib/tests/checksum.c
+++ b/glib/tests/checksum.c
@@ -582,6 +582,193 @@ const char *SHA256_sums[] = {
   "df3a0c35d5345d6d792415c1310bd4589cdf68bac96ed599d6bb0c1545ffc86c"
 };
 
+const gchar *SHA512_sums[] = {
+  "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+  "b2396a002fe7aec008808687d7cbacb340b7f7a090008382f3c95870f6fb10415f61f5737c102d4bfec58fe525407ea2001e761dab1da8a501d9523921f0ec21",
+  "11ee0d7b40a7a4dd95f63b8c2a9a36b77daee5ca7d46fb5cb7f871db29650ce9c78306ec1fa9c4075ad0615a7f9e63697dd05cf79cedcdecc82cade38ce7638a",
+  "d1eb8fca18f1ed13c254f228435ba23ba203b42d6fb38bf84aaae54760a3964e671149b5d10317a0d3ecdcd0021053e6c596fb0b05c33214cfd5455d325ab53e",
+  "a4b96da738e2cf6a3d127a0ec33725a6953aa44140ad820415aab4ab3d2baf67d7c260b36d3c6d479e85cb3b0d00b54a555e41993519eeb594cb7796eb9aecec",
+  "c9401760fc70ce01607f7d635a8b71ff2985d543ac715e772c2252967537772392eeb9884af7a8685b099628df73650b05b5511997eafd0627c8a47d5f16cbf5",
+  "f8243bcab27b16f47c58d10a486775e02eae948cbb650ff22e68e501e41b78a0784abfe67b2992d5acd0d5ee4b18e495870e1189e4e9f256066fb1e28149a97d",
+  "dd8519e311bff211839edb8a822b6434e15d2c4e3beeb529d43646f7fcc710b393f4f7a6c928e660817e3fd70b280e9e7128a6d3b0a431f4f4dbef4b1527f35e",
+  "c643d169d3e822e42f2b60d2bf48b36d6bf1d8d8bbd0c18fb00fa4fca79faa6f0d3633a0ce7a2fd62fa332712a45feeedbfd4c5cbdc30f743979aec79fdf6286",
+  "bbedb9d77e386908fbce019fed3f8237b6c95b13137948844d68347116d2caf7a495a9f34af79cd762bba0190e1900afe3e922b5162ff77f265ccbd275718183",
+  "b6084d61c87ea222d8f7506fad7b7250741f34ad8a075df75c18a31ef380385587474991c3256cd8e464c0594d45c6d1505ac5fd50289731089f86bc1bf4cd5b",
+  "4f4fbc4b5702df96d75ef959d5aeb32a7c74dfc14358d79a473e92bc16f4848262409f35fbb2d169ce7b7f16cc9f5d661860c6393c0ad2a2b25907e177324573",
+  "1548bfb55f25295008b7f6e11cfab72bd7b4525902897747b585e94c7dc4b9baaca57032e2139df5fc8fbfd5f82115327db42ee15b87052f679de6a586eef4b5",
+  "51020dc906ee7a3fb202099269dfbdfc01e2a8477f474db279edc23b90da683de99b7c0c5367086508a89a5c76ad1ea8ed05456ddab592a5135497e92f12348b",
+  "a7a3e5d22ab9ec75d7e15aed5742d4c83569279f2f9c61076ebd9ca13f3c8842642df2ee03f81646ac1dbddd29a53ef816a350e662977c73b3a051a56df01965",
+  "c5c60fce714297d6ea30f078756b33b11bed89e69513ed900a91885c14141184bb32b65936cddd3432ace744bdab8b0fc46b0542cbad0d96726c5325ab6b148a",
+  "29e6100e1107481303663798fa0195a4f56cd410f52087a9b877c742fdadb293473d91b3ad3a6606a75f3b8787fefa68e94f1129bad7c77f6df251fd5b82d96e",
+  "bc26056e51dd3ee0747b21ba6fe7467a1256b81a595d4165e33b13810a0807b9c04b98e444aed600afff7bea013e362657090b41a10652d5d9dc8ce766f4ce7a",
+  "40c4a4640176132297ff0b5db944e86e0fcdc823ea2e3d30265f9889edff943b63839451d783bbd853653956ae6e9763534270539deb4bb77d814fba5f56a879",
+  "015e6d23e760f612cca616c54f110cb12dd54213f1e046c7607081372402eff4936b379296ed549236020afb37bd3e728a044a4243754f095498c98bc24f77e0",
+  "55af8ef14b57edd35334323adac3fe07e7f4de338c05877f2cc94a11da5b4291e2d4c10f1ba7e1c01b20648e8c8dde2f3df22aaa3bcbcc888e3796b1118e6679",
+  "aece539289caee7baa30fb7915464d12d4d2929acfcf0e12b1f81d76be8967a83b051801bdeb38a62eda5bad70cb98391d8d6767ff3f78900c18e26d9c829331",
+  "bf08cdc2b15698e4cb5f7ec837a7fa3630a0acac52d866b9ecf7e10083d4913bd46afdc91216f922fbae5b6e58116e9fdbde2f41dd32a0dd57bddb0455a305fc",
+  "5049280393cab13415d832fc7ac370e99dd413fdb7a71c213baaa98f8c45f84f892757d1b9ab6a181c84ba880b528768f32d907e89f4e0e003838c4f4f005024",
+  "8d81d423f7c11167a3f016489758ccf4fcb45aa1c916566352f5a0a94ea565d8120c868cf93b38e2f41b16a350fa607edaa288017f541ba36b45b55262efcadd",
+  "4b4c254dd0bc5c4a1a70900bc9eea84c852e11ac3d16f87f1d3aaff0478e46ee58c264d4aea58d2ce1b08e84bd7bbbf032e99521f60fcec637abdb243977dd7c",
+  "afc85167cf33d21418e021a4946801b91bc103c8b2d4a53e01b2a237c293915615b9f2504d117399a4eec2578683c91304a608745db331a2dd7dfa9ccf7352ef",
+  "a435a6f9d0bc4b66e3b62becfb3ea1cbee93b78707847e9219bc62327d9d8aedb48b765e99f5d6b334bf76aacb879d796b998b855bf6ee7db826ac16e4da693f",
+  "bab93872f631b5dd2be09ef4aa1c80ab92f0f3c0593c901a46a04fd2a19e8cc36fa827380da7fc663aa79e2421a6256b5b7106b15823ae49e674950b94747883",
+  "815fdc6d15a1ab485f274638d92442af5ad5db11200b67180bc29dcf70e0598255503431e13c7e6dea4488402f112c4574ca93df4b8b0e07f28ce3d5ff64393f",
+  "ad6f2a6ac5dfc9ed273c1e18f2d16c14221843ff9c2092a30108ddc127cc43c3252f821d599a5d0bb3e66eb40b59d3537ff5a90f3356f78b7075bd9a671bb30c",
+  "b13effea3bd3444f360ae4aaca1fd334b23a46a9d8ad64bd88de51589b80a745f794456e612921be4f4e819cf2f7661241bcb2b19afa9917ad87802008243f8c",
+  "afea68e278d0da3a9f07d0591dee8acee064de85ff63644f2da7e92947e4c73fa7ad2db9b2d2bb1d0b27fe16cfd274d3b230d7fc89c3159be40a8e5d2ef1fc5d",
+  "ca148b59a34ca4c558ccce905d557babdfa9eb8264097cc50f230d3853b5139838b52d888937e0d1de33a9c6bbd11fdfb0eebb7f805d2c090f0c4aeede00df49",
+  "a73db6aeeaa8ec452aad71bc56da4467d4530f67ede3cde54bbab5081e732c76ea550220125fdaf4fe874c448fd7e6400f5e1a80c3ab4f733bbeac0172a833e0",
+  "282a28dad323190b3d2f11035cca91fdeee4a7b0c5606e28786055c5ad96dc03ea7b05dcbad19a653fa073aaac50d5170e5de5eaf266a3fde2e59ae4ad94f2f6",
+  "240b9cd3ac60c56da080baf790e882eca4ea75644c5967ed8266d0f1946847f0e3e243bf1189df20c990c94683d15ec6e903ede830e57e0727ef7e4066a97b0b",
+  "2c247a65e8b946837e79fe8a0918a997e50766b967e0d9d14f354bbd58a9db4a7672e92649a49fb2289035a14ed0892d7592a1d269b672a4ec8867c3d346aea2",
+  "d7c26aead784f5ff1e87045fb9137ebea95f06498da0c2a1e9ee8793fad537b1b41090e57f30acfe43594b4c6f0184d924890ee67d92615abaa3bd2624f236b1",
+  "4b29f8d8420e499011e18d64c1e90446c8ab2927dd774b022fbacd7552a888fe48a172679562e69838099b6761610325d587ecd4c94a8d55e1b3ec44f5207736",
+  "3e5a0fd20cefab3b91f0e57f2f874601305e6781c154baf4c8e6a4e09557cb404df189b0b6a8cdb655d59ed88fccf29e6459950841c739106f0a7731e17a1053",
+  "f07aa6f2f93be5a8122f0ad8d659ff66488f4fcfbda7f77b2f56eee4223497a1b31a93d66d251159dac5ccc343a15a85f73e5814eb7d9baeeead010ba751222e",
+  "edbddb6c20b0f7d250c1dc453898b0b110c819754348e8b2fde6889dd680bec51c686ba81a52963b4a716def84b3f3f4e911191c3d6c73cc7f9e060cfe05173b",
+  "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6",
+  "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed",
+  "5e1e2c9fd51c753fe537e43c1982035b2a86c641d22a98677af89f442bda95a509a35c4fc2861ee4ca5eea20e6450902ecd116a95976b96ec37d0f58be6f84cd",
+  "162930d5e90bee1c86b56fffe4bafafeee94815d343bc4184f87f3ded2fa4fc44c981199d0331c79e41eb1e2008bee02639e9a0764b9c39e00a8cbcca6f43979",
+  "1216c818be9f2bc1bd993d29b6931a400d474ee439e5824c879e1030206d4698daff0f51977c8e701d8ffd2d0cf9a300c7f1ae547d93058695ac034fed20c3d7",
+  "4039837b00e37ff43c29585971a68f89414a6951aeba2ae692e6ece11a6a3e58b9d2bad15176c918aef644a576a4dd4497cd22884067f27fadef262e79ec8a9f",
+  "9d7c27566c55459b1a183f2698eb5ced70a298a73e10072deedc3a200e0a391d7e5fcf6a802aa12cb469cf70f928f01960df1e8d7471c0b8ab3c572403a30098",
+  "b733d09fbc2b5266f4d113e1f260994f58771ac555145ae33f737ae814adf91738f37b3a982e6071d226846261c6f1440655d167c5ce04df4eba23f62a661996",
+  "e94f8fac70a3b7a4c0d29946e7c6433d29a749cd8f165938e8b13dadc0901b198ff6b4395c2ac802083dce48422ec3aa455d612bb379bcb0e9ff5216418acf6d",
+  "0039c0e979793cfa23748b7cf7a2e3982eba9aef9a301575d50f332fe20a960f300511460b6ae7645ba9b656416aa781e833ebbeb6ba9bbe5f7f643c9a156d59",
+  "cee648b7c0b14c531a64e6026e97adfa8d2b71f1c89985a7bac502b552eb4986bf2dcccbbe6e68040818232398d70508f90d37ec6576d216b733a7b52de78bd6",
+  "f96caca679e2776a8933ccfaf848f58ed1de564fcbce00ddccdbf7bdf9819f1fb06574c34323009cdb5b0ef430d90e08e4da17953d34b72bd87373de840b0299",
+  "7c2522efaf0251854ed9d68aed3ee646553401f87c162719b602c676d5f2f45391f7fb8d2619d3e20055435cbaa78defd51dbd95e5c351420dd62e2f53cc77d5",
+  "ae7572c1f8f8e89c48ea25401f79942b8cb1a0316409f29c957ac0de9b3edec509dd29baee2cbbd7fbfb81dcda750ce59d1ceed9234f4edca8194656f00831c9",
+  "2fbd6b7ad16da77fd307b4cd712ed70d4a21313f966fda3b6f60d73dd3cab0aaaa6c9455fc4a5103f99d80fb0490a8310c603bdbb6b925ccb14c87b1e9c2ceb7",
+  "3cebd0bde4ac281151020e3c944e40dc3ca9203fd8af0bd2009ded0ec50566c53f630aaca6ddd40041b1c0e6e77df43b503e37c9fe913711c03a10ef3785d54d",
+  "3ede082cea90fb909f21a299c1bd39494f44e9f4f614cc69d080482d12c39c6082748f7253fe9ed80cd85f09a11db35f68b453981269f4cda03728d936ac2e97",
+  "b60bb7fb62fcb4e673dc4c5b8c5c8ec3a9c31569f6b3425043cbe7814508373c5a07fad5d27c090ba61de97a1a3596370c77feac711af76c80f7795004de81b4",
+  "e7a60093f04ca5cca156ed165bb2b4cf7cc0bc538240fd121bea824f7ea309a362d1e5deb15550fe7ae56e533f99f290c5a570913e537605c53dbb525284cf54",
+  "e4d0de74f09f714ed7b97667f4c462f3b4b7802b1cd6698fd7d1ad97c0eb09bc39fda853f1fcca9570767738e576215bfd7ee76ac72d1da5280b582296329f24",
+  "f02f601c2c27fd84b75a643c8ee26e6d4421140f75d2af30709e621ef198e05615bd6b568a4f67c70f9fe898c7cd3026e3379dafb01d969dacb20049d62c4682",
+  "291aea713e6c8567bfaae8fa6b2711557320ffeb44ad3ded077abffde0bfec8fc9c6cb86aab677a4d99b6e150408b7a8d4bac9c876c9335e07cc25ab49162767",
+  "139f3f4d4009be42ae62422718bc65ae0c416916b6761b5c2a80b2b55be51cd243eeac5caee9b2bbee20f3e55a91365b86199d3fc0557db3db979219f5839bdd",
+  "187249bab389e589bef61e903e2c7e016d94cb0ca2491d07fe4bf2e0484ae5640145de666e0cfb577d4d60953fb9ac75db0c07dad4e3f7dfa1bc30619c88cdfb",
+  "bef11c0d3c5267ddfecacfee56913fb60679ea346470f6d045b48535df4a56be6edd3a57ee9c48045f8a321b4fed4cf613474220764998526541b5ae401cb1d0",
+  "c40ccf026171ba822e721e2ba3862cbbfd8331db99f4f580bd0388ba75f2f89b929a1ec80fc19945c0ef79fbd5b92de0cd772418ffd0c8147e1306680a9663b5",
+  "7c35d4fd4a95464d5191a3f5e9f3edb8893c66d5891dee0a53038a2222432a6ee88d3f887e1348beab0008472f8df84d178da7c584a00d2db43c1535203da390",
+  "e2de986a6b5c8ef705c59a8eda38e1855e6896e948cbdbd6042d934341a4777645d39cd8969f53415ab900138fad8a8543bc87c7371d32bc9c97566d0774aba8",
+  "b13c9913ec130f5bf2e40adc283a96ae4903d71782279cb8794e926abc82937e01a2cff494f4d168506341b492642dd0c04a657e016f9d8d8b57b20465aeff72",
+  "38e89130fabdcea2f555f71ea2094005cff7e039b4a7421a7b40d56c457705e857908ec53bfe463ece568d75f75ad959868d78c5baa7cae309ffea4cfeacb380",
+  "ceabf765aeed49868054c62e3bbc2c00b5368d3714b7c96649b2edb26f0b6640c69b8a04097dbcdb9664cf426f0efab7ecd8269e3cac7ee8b8784424c3389d0a",
+  "eac764653fe8bdf0a6f876f8c27cb9dd6b986974a405e383c840f2fa359640a580905ac37753040b8801a0ae6835d3d0d9295e9ca40bbcad903a2ece091bb547",
+  "a5f601eda3c483432c8b34af1ca5a5b2ed75801936ec4bed7570bda19cd4a79b2c1f24e505df4ab2b91c43028555358b44f6246062ab1f60687a98c49c5a4ccb",
+  "254efa3bd9575a0fc856d53f8542c0cc64cbf4891b1b3ee97060d596a51ff8471d0186868af59ca50d73b8f509352c146757a5bd86f59ebcec6ee4db2fa2fded",
+  "b439ae6bf400df4edaea40570cf2e6478b031355a0491f94cc213b345f0794db6773cf3779e300dcf12d42a24662a9668ecbb79c87f888454354c440366f0f1d",
+  "f99d86d1ea7a5dde3fae3baab3f6603b7805d6818f44b724902836bc857cad8bd9f8626cfdfaff8d76b86dad3f69bde28abbe78a0dab090e6c501166343d99bc",
+  "5b3f6a33c7f9e80d98c0d16f18ed989acb2c723e3f84b929f07cd9eab4a9a20e736aa12ad9808daf69310c61c2e63db15904703a9fd4e3ac74933e55772ebbdf",
+  "1d9e66a96556fcbaca8ef242da4dcdd83d1339369bdfa9d2af0c1940396d43adc302cfde629bdd0b5ae5d8f995a558597ef11bb04bc818e807dc5b0ac0d7a730",
+  "3b9279b07e9574821d827cf1985039948c26329ea5767138b06b2e91b01ad64475dc88985e5f1c664655343237d97fb884e700819b61e1cf12b7ecac38207c1a",
+  "5631f6bcaeb487bf843cf54e12cff6d72ab5f1786bad51d9e90ead7f340387b2a271cb85aa417a0898b6a9e4f33eac155e5224152051ca21fef4f6e0b1c76a49",
+  "5994362806cad2c71fa69291840f5798365b238cb710aa7515c36d059e96009bfdb41155d8f9ca008b7b536ebe1c1e49b401b5334a75a4cf8e7891f3907a864f",
+  "bfa6a6ae5248a4668d4dcc50b1022c76d04e6aab799a77f2641e34a8df9f30a4a0fb29de6bde727d6941adf32775c2739eb4d2ad7575661a0010ed957deed45b",
+  "830c371d35a9590bfc897ec2d49ed52ac1df87dcb1664eec4fa4ef13bcc80b4f8cdd9cfb29ffb32e01d3e35b44094dd43a1df0081d1435b7298a2ea729453c86",
+  "f0fd5c15bcbfa9041e1c53754ff0b5972930be7fee568fef02de68becd088303e4dd6da8a204bb569f0d7c73e0c478816e77cac412681ecabc3a371d5afe4b56",
+  "b29b5852cb2d3523aa98d0ec3f94813187c2dc0993d35be9f6247810d35bf4aacb6ee5f993fccfc8c9d7d9524ffa8c01ae2042510d3ac950ee62315235fd3afe",
+  "1064a5e41eb6faa80f2aba180fe59c3b0f237c43d608b235382a9b22057f4d6ac91a316c4582bfafd4ea04ecc427eca886860240d88ba8af9508064e71eaa52a",
+  "5574086049660e7cd1d2cd4b774758df61e8499ad2a25295322639035aa4bfa29fd1e33a438e74ebe79fd0dd17a90cc0f88e9282ff5fb2205c155094057bd27e",
+  "07c40b39525c7c8afbba33afb909f538aeb400286488e77cdbc195a7d135dec54d419aed450b44d7ac3b05878365d35fdef5651d6d30c2d81c5b8fb106fc3334",
+  "2174d552a8786edd25c3d6bcedbce5fa84a80801845ac338df4bb28f6ac51f6ac9023365bbe9b21ddd568a4465ca6ea8da356286f5b2ea627a67d8833880f78a",
+  "5e6ca770fa9cee048a8951e4598df26d4379111b12b62743cbae5b4b19c198e9095df55efb7f478955f3ac8e060e501a709818165b8f3c73909ea2d58227412a",
+  "d52feecbf5c9a9fd6097cfa06ecac142cad3421e7dab3a04ef8dbcba16e21e1a9fdf2c3fcca1f510815e194e71c45f71635427fea15f7945ccde0131452acdc6",
+  "1bdb98a3f797482f004e98597553cc763aec2f2896f9fb0f7fc679702eb043849b6ba3984f4ed304db6cfc82ba222215b9b5dd991b6ceff53dd1f8e67759af92",
+  "fb5606b7f39828a91c0ec5ffb0ecff985179c612f3c5098065d696ddbf525c8a44514b8bf05b9dd0d396420ea3bf106a0bc9d08b929d44ecb83796d146eb09fd",
+  "3dff123b608bfec0b02118a569b55b80f7317de4bad125a9f897a5ddfff0ca8a1382e9a72afc79ae80f2cfe59e7712f4713e68663e3cdfa0d23f5fd848354523",
+  "d47d6576adb48d7bebac60fbde84c92bca384318e21ddc8073ad423bf2b7cb7b9939ffa0b304cd6a522186a813acf0ca8eeae6b7a01755e92662f4fa3df0de71",
+  "293e7812e9fd6f39f9a81e11f858f6743e4e31553b7251edf6aea5dfada1afde12bc1578572347007484fc0e591c1fde72c254c960cedbb8eaa7ac85aac3eb7a",
+  "1227a9c0d52a20f00d7f085e95416b3671ddfcf5b73dfd7caf7c64cf19b95d8b762a0a578600e6af971f3b97a10d7bfaa685460a9beb92942c706c547cf813cb",
+  "15e2c21af9d9209606e728b4ad464c108b7e386d21da4344ecdfd03cc5827432d161b14ddeb621be6c2861ff7547e011c63c490f3d809aefac7ae5162cc6d655",
+  "c54c0de631c7998fb2da9d3ad2f0f8a87a5f658c292ff1e76443f19a8d51e34e0465063e49086d9c891dc79cb2bc08a9611b108ff928093e6b8c985d14cdb281",
+  "33b2ff02a79184ef6639867bb72bdaf0c93740c36e1b5e26a0f3db94d2af7bdc323af8b10fdaa57caa08b2ba5e17f4236753e657dbc158bae140b71955bbe120",
+  "0462f7739cdd8690faefe555246466bedf67b7b9b7a9694ea92c28a4af4180f42cdd7839d7db5c1f8baaa6c6340b9efcab31a8c62674ff3db8f1cca965011230",
+  "b3f4a7006181556befd5251a56543f14e9aa479699749f949d038020111bd305a679a83dcf66e66460b970da6cccd67f1f3f4c4da99d4e52d9ee34dcad7176c0",
+  "bcd2deaa39624795411746e1e33101b7e44e1e9bbec7ae104f0308c6a24dfc89271a43a547a6484194dac6ab6614e974be6990ae3d8d11bbe65d27ea68ffc144",
+  "b2700cab398bca05a23850a5f393ef9c71eb9cead13036e93b66cb2cdb288f00e0dfe35e1a16f1039abdc7e1d7393ed3df3eda7e75e8d0de28c6ff68066b907e",
+  "3e99f7ef52ae5b3eb4bafe745a7bc6170b5c4a0f61f5a0dc0294254a1e87543fac10f46ebdc29a1e8ef5ae715636e0aedc578b5560ba55365eb4c28b226682ad",
+  "e2e67d7cb85acfb52791fce61b08d79df6f90a92dc8e0cf26b5bddf3a7deb5ce6c23a9098cb066ba065e6991a66d9449dc9166417ef86001f48b45d7718bd124",
+  "a038eb72223e8fbcf4040ea988b53f8aeac0b6029a85d44182c4742bd5e9e454e3470c19ba2dfdae71c2f1f31bbf543e704e0cfa55e98772c9cc056882031bad",
+  "82a1d1c2764f32dd54d242b26d82a559301375e74dfdc149bdb2a3c27b2fe2645d85b2aa8e6a892a846b157bf3119c6079b3512239043de0bb77eb0612ca6dd8",
+  "3d04e36beac7a7d845655bb52da45d80f7862fd989c256b09d6cbf654c946b8b40b0432ea43a6b60864b1addda95501518609b690265d969ee909f07f8a02f97",
+  "e37d5080c16d8a2ad752796482a570759f69d9274f6b55d11ffa4b3b14350edc3dff02f83fb360086a5d53b7ad68020ec781e22a05f3984afed3002743f1e3ec",
+  "b3133139eefd7742f993815f8171c611209b2e76900e753517c6eb6b6482ce8f98c7a2a7e02e5cf08680115884733ebe72a7cde5604aff31e00b4d82b5fc6ca6",
+  "b5ec00879e0c890d570c4ed0e93b32e92579df18350835db4333318e52675b54b18ff156195c9808547ab72ea36a6dfdaf478a9360668baea162ed2d665ab54e",
+  "1d892e3482147fb943b8029fe2c4b8e5a711a06993d6d5b3ef66e691b2aa72ce2668c501af83f94203a40b4c37465cede2dc127b7a2dfd5e300453ecca177a39",
+  "ebe5dae73d7539eee9b5b281cfc36b39a749f40a7e43d7508d8fc535d3b3bc9c51bf2815b63e04ca26c4225b099cead47f37c5524e5379de221e49c59d870f2b",
+  "67477cf7b6f426399073619c6dbb7cb0958e8e7b41e2c3591b5a716c69aaf13ff37d53d5d8baa93dcbdef3c7fc800a0c379767ce09f714983991d3568e3265cd",
+  "8417261aacd1ecf031d17fad6a4ae726250f62b6ef4986fdb532086b2c2fa8afea21739eb9e949662d7512c11bc5cbb558f9ccf3bf4e69b9285964edbe0d5a96",
+  "bc667649dd008529a9d5fa3e8bde8420786e00a63e3481976811b2e9b395df6edc6eb6182be7d91cc92e6a4dae309456a5b3ba6754c1203a50b38d287ad7ca7f",
+  "bcfe7aa19ae72582d859539c050dc53f18442ccaf1a08415464a669b72503b45bdb13553653ccd20399b74069f3260d43a80d6f91dced3cf09bc72b32f05ab89",
+  "7d3b8dc4f5dafee652db9f134111fe3d7be1383491c308a24de6d19c85f3ed3b28543e78a360f1c7dc90ecc3f4c0731293e3523372a554af290b3e5720abacb3",
+  "3af3fd8d186ded54088d93099079679f30b33b472ad9c45a1ef56f66f55d324a8ac19971f7e5b585c4355fae0f5bc32437376bfa240976975f4b9a8bbee7897f",
+  "cbe6405ce8db3c3fcc956d76def5bb3199fbafa808cab6ee399af30998b36f0c82620e9ff9d48636157aefc92e1a4526e646c885c66f4a0a7617f4bb51da5e5c",
+  "4b29415c4bf027830612f3a83db423949535d6b7d036a5adce3ebe824ba200037f517de8953c000d5d2481209948f4d4b8cf90d799347b90e79c6f0593169ada",
+  "b0cc887af7da5630f9d9771f9c8cc8539526f045c340e08e65d6fdc97d20577d57b192c4672bfc6dfca5c800933ff2fa07d160cabea90d28ead54c05c3b7a37e",
+  "04bcf2550faa52348d1cfcd971ee0bb7f639d68a19c3305a109fe012e66ecbdf44c57ea0788edec16630e42247da4a3fc2e7eba13e760bd4d401bc19f09071d0",
+  "3a9c39158f01951db962e4d7decd60cb250f14e041c1ff88205f6c9b5daad930d2affaa896f8bbf586cfa81506c8cfeb31405b9eb1c9be6ab8b2829408219b0e",
+  "b2fac91e5eade54d6100b7fc4cfe42fce3e22dbdf51bd613f4e8a3496ab6101159cb2e559aa4d0d650209f2eec6a02f63f15483b899dd4e5e933273b31139dab",
+  "5c5568e3ad468eec55a92ba557a57ac03a6235fecf1cfb55c09796afe3e927f8f9801d1d07b2df4060470bb11b09f83f34c5122eb887d9a94c0f5f145fb9e56e",
+  "bdab9cac7cb2ab91d14950a32e0a62c668dd91e2b8754193d146ea8672d29222c6ed5c2ea60f0a7851eb7277ee7f9cedc0489f892adde2a04ca80e038135f198",
+  "af3ea76bbbcaf5774bc4958b07568c837f948a5daf8a560c5755149a70614dcb64faff186217799b7589225076f2758b8cc0d84c075a1c752a09a826004bbe76",
+  "3b50e163d5ba96a2e7e3329340fde381a535af02fc517168a7d6d4195cf272e61768a1f3e5d45868597bb32c49380f4ba21e788c92fc6114729a44b4706ebca4",
+  "37dd3a8ad218aa44b07878828283301cf39da589111e5fb65298002c3a7b9f013c36128fe66f93ea72dad5d99ff42d774ae999f1e8d84d3c1fb61d78f478c329",
+  "670b50a1f26c26febdb8fa31e1bc9f03afe3f725bd7deefb465070de06777de9ae55479d271961265624bb25c685b48e42e72601f52391986f2b97203d983797",
+  "5e2c8d428816d02642bb094f9bcb0d8a3e48108c4549fa1bb7347d0d15a3d37bbc3af5ce8f9279616dcc802f142dc0e246dc76fc182c103747f5225da8cc4841",
+  "8e2e77fdc06eb9324f7b1d858ce6442263d880caf256bf9d62970f1ad765e81bb6a95a5bdc88fa87b37007872443952b85448ad4dbcf7ff012e2b1d44f53f699",
+  "8937de9272ae5f8a1ccece91f5cccf118904a5e7fd21edc9d077a6a1d312e621f4cd96f4a950b74f2f481985495c4fdbb8500c2386aba7d133486931195a06ea",
+  "cdc9687c2404ecd21f1f9b7fbb272fed78ade6ad8547024dcbf931258a3f3045b0d644ec402d2bd13ac7e3c883c94800ef001b797c9e5dfebce8aa44f24829dd",
+  "5719bee028987d23eaf51350467f153e9d440c51e1266038b4ebbcd573ac74b79008566646075e2a1a2b5a6b3a1404450cca32b0fd29dfe2f7cc7e2f4585d07c",
+  "2eda00c8cf9efdd46f79b95e177cb98b1d566526ec12829ff82da0a78dc047e68d6f0e776715df6fd9aed5df4168b9e33aa015552105fa0a21e8cb038d28be1b",
+  "d372e62ba258d701eb7fba23617d7967e5190f8114cefee27284744952f1da02e1e8de8c9dd7a9bff520a7061a18dbe99ebf33342670644129ac8190135dde78",
+  "5c3a473fd13763eaea52dc52e5eb6ac7e5df5c35ea8812e8be7d41293ea8ebea66bb76d8cf58680c3859f350c98b4ad6771b8c6e4cffec4622fd3ce5ad87216b",
+  "d206f0f3af96718772e2362df47e0f65085033820e1eed17ada51a8c880f41e0cc4b539363fe414ffdafc87cb95053a447f154567cacb94a56faf26423614973",
+  "933d85bb2e7a3b8bf7437ed6fcc52202d6d797a466c21bc50c74c348dc6a8e06535e8aa9fb2c309e6cb947709992f816dd89f99205909198743848d13803713b",
+  "e76363cd6d53d7610f4955df2acfc305337f6e3dbbfa2be6c11ac0f486149ec402dacabe810ef305fb4fa06054b03aa06cd9d512149eb52e443de3f9d442395e",
+  "a3e64c7cad5a7aee65dc47c3fbbd0f52289b118eee07e43e5b997d3d71577995b906a37bc4e5688b5d36e26602276e242e49bfad1f786b927ccedb627fd61401",
+  "7cea74c5c65aa40575672969dab244911275c73ede90543b3e19da85a038065dd971329c8c7dc23eb260bc9e5df9e6f4e4f29f6d6ffc9fac51d2d8175f7f4342",
+  "a4ae36fc9c75d72384ca96cfbf5dd3d55750ff1dbbfe01d71088fc86b955faf48cd6a9bd45a8ac7d429ea4eb94a5108998f05b1c69f506f8d429e415678b35f5",
+  "7f27474f5ecc49c4cc5c8835a408c2137c3063402e893b6fa8435158892f7cf4066ed695053bea7c394ef3877821956a89d94632b32286ad65f6b0c6b3397f6a",
+  "5d868eb076cbe09c47cf570d3aef8facea44af0898a11b8500161d0f6e402a9112ea2e41e28bbea388c9234529b5fae5ef74631c044df7c218efa5d82efb78e3",
+  "6cec12204ee0972baeeaffca5c912647af39291a7e2b81664e562ad12a2b17fd4e092cdb1197aa9f1330a0a7c8bcc7f623069d325b21b14a5803515a61dd0fb3",
+  "fd3393f5c582297309610f427cb14001df921bcfb0a771f37a51e6166a2fe143ca7fd329fccc47ab5766056caa4dbfa9da5f221a4ca054644cbfa939df491e3e",
+  "9917e3cf093607bc286cffc60269af690f4eb9f704107c906627cf3259de31d923f696628e730283b51513890ccd90c40f4bc2cb762980b7531810bd2a333882",
+  "95522c31784f34aea08529a4a09a283b30085cbab3843babf96f0b45f406c9b3a76b6373635074428b23e17f4977e9fcd065b44a9161a26b7fe66fd5391d6d78",
+  "91778a52ce45d4b77f1d91e3cdb38464ac16c880b28916733a31367a3b2015082017f767267bafaa1ae769611f05bb6b60c307fb080cdd4bf2892704e5aa1af3",
+  "09a1466f07160ca2da1f999236a7cc016c9be9a5f66abe80ee2694df708d58d5b572cd9c2dbedff202b940d874938caad417183e71012b77e446afb3832b809d",
+  "1227c21bc6e15c7bf0aec79febae2e8787b97c33c3d96c2b2fac1a43fcb841576cc4c806aec038534cbf0476cf90fedc70eca44339523904e37020c14cbf2151",
+  "2ed90b58e8009fafd9c7dd299547bcdea69a6c72d4af00be9a5f5d81422cfe6f275a00af7579291fba526ea0d872620f72321b5a712e08849493024422d3009e",
+  "64a10ff891e361e3a7919614152053bfbce6b02c8241f6551550cf704203833c538d879c8631d04656f0e67963b8b56ff546fe9a7f1ee073f0fb92259a702328",
+  "d4bcc92ceeeb193aae5f673d444275bc2b400116c48c8e70e5fdc19606982f574823171a6590d377399ebbff7ea66c643998b0b9a3ede9c82acef9ec4232356c",
+  "407d968198d56fefb39af30c26d7af2d32231c388ae8f9d68eee68a5a491be488f21ac41c2cdbd2e5a6ca5cad398662477c070d6954e8bf2447b39b471019f0b",
+  "38c7a0ebfefee5d4809fdb78d07626d1fbcc7a398fed72a94623c819b8320c2744de1249d5f4fd8a40da86489d9b4c4370c8dd64cb31f072b79159a2403666be",
+  "36d93692644eb4a082a92e6c12ac7cd91f8b064b79f6f484f40c2ba4a1071516ab4134351661f23794199e60193dae637615eb03fa3d3d988710d0dc67a2ff3e",
+  "05e6f04cc9fb24de203d06a65911276d3408def644d0eaabea8daa3f05924faf79e8d14161a94e1eb2cf28dfecc9dcc63aa6f820ca28a8b6a7677f9e6f89bc5a",
+  "b5bdf2b8009369341985a4d6920b7dd0b2bfd088968050b208d3eeef95e2444abc88227de54866c419bbfe008a91de2c6ec7f028cf7161a7335f929b09005f3c",
+  "d57d75ec354a3ae54aabd4a0e4c1d352426031ae401cbd6d18d5de72cddad32822f057a9aea2f64d7531540832a8fd37498f27ecac24cf70783d8ae7dbae16da",
+  "9eb628ff8258d6eb5ba260cbc7f66a32d0d35f72eb7d7f70614c0c4d6ba72f8bb7204f8ee704493fc798a74de6659378ba0627b8b8a88630d4220375a5906a6e",
+  "d992753f9de4963cf53679d6612de1987725bb9608fe23cfd6506c4d07b1efbb4bddbad542a5f4194e6d4744bf6c3eccdddabbc04d01197f2ad84c35bf885896",
+  "6689fd5d94a7dcb6b20bcda530db758c5d373ebfbc0f57808b95a14f45326478a0cad7a0d6ebd22f8c70e39f41f7b9610ab9b475785b93807e16059ab5dda7bf",
+  "93893c6b57bcec91f2d19c8668c5b59b6c5a66492b71770e914ff30489a6efa7f030fd42bd342d8202ce9df99c0a5ed56e1e4ab06ae0ed6d359e3b140076d5bd",
+  "76ca602812d40fed5cef33b7310e7b8bb5a5de549fc63219f5dabb3cc8ca70658151417e2fc041d6fa05484321be2f57bca1d0300be701031646aab039125fbc",
+  "0c71f03a2b3ad8765aacb895f6a19de92fbf77b0e40a61622888c2886bb5bbb8c3b4ebe4e6abae661e4f0b72aae10753d890aab9d18941fdf18078b77f187d31",
+  "8e2d159af8fae54ca736e3f3412d7de329631db7bb561dc0e82266c50958f22fdd7ef8181ce62e9632f7443608c1d3405503af23c804083e1058c6118bd8a52e",
+  "83be1fa27282e68590c15074ac8443f9f53e064ff8c5c2d65304266eab1d998fb23f180f3811c5ec5cbc88597e037f5a7b908eba287dcdbab5ae473e65325611",
+  "681f00cf54a854e4b2d26dfd264ea4f0695360d0f23c82a024e0403775925b2f2f9f1aed94f123a5a683241c73d4e9b6abb7473787eb48dfefbbb54d0d122a71",
+  "4ba62bdeee45a2f100f7d7e62482913cc64b3a8fda4c1e833568d98403d0d6a9a788d3980fcb3a9b62599403012014b3f2926e264d83c4167f9f99a1f29a9e2a",
+  "a40d8ae569c4a15e542d0fc9a2270b1e253a5757bf64f3769ec2c0e6a2b8f82d8934c1cc0450c1cce806b6b876de1fbafcb2e06ec4519edea2fdab9a6f54ddad",
+  "5430372627c0d0f0e6ed0550b77a4256640c1de9da96c7faa7606c7c1b0cbc6ab793bfd279b505bdce09b46cb7f5d73217bdc0a18240541656ee9888999c3339",
+  "c9d0a880ded82409ac942823379d65acfc1b11e54fd44cf0d4569eb204e372bb10d4d111915de64163031dc533715b29f14a6f910a3d58662bd13768e31c2aad",
+  "a326708cd8da2fab8f4b7870dda03800446f520532638ed7bf8177c509c53a65ec3127730ab2f02d3f911927d1f265d147bb53ec5cc0dfebdb68d0f50eb2aff3",
+  "ea381acd65980fd5eb1e8cb5b25ccae38afcfb9fa1308014bbcc96d9b80255cc8ea8225f4c6fc2477b7af3aa2c61228a9d7a6be1bd92b8687ca25b0f912757d0",
+  "42255ddad4f1c30ad42e85752bc3685fff22da82dd8ca85f7616112acf2c4644d40330b7e7bd4707c8094d1034cae77a503cbe20d0bbf2519bed7a758817bfae",
+  "9da644c289075656b5339317f7100d954b49e67e6c3f981451bf7982c52f003016470c781fa0af61a965fc0ae50f1bbc8d94ffe91e10dc09f27dbe5b1fc2827c"
+};
+
 typedef struct {
   GChecksumType  checksum_type;
   const gchar   *sum;
@@ -832,5 +1019,10 @@ main (int argc, char *argv[])
   add_checksum_string_test (G_CHECKSUM_SHA256, "SHA256", SHA256_sums);
   add_checksum_bytes_test (G_CHECKSUM_SHA256, "SHA256", SHA256_sums);
 
+  for (length = 0; length <= FIXED_LEN; length++)
+    add_checksum_test (G_CHECKSUM_SHA512, "SHA512", SHA512_sums[length], length);
+  add_checksum_string_test (G_CHECKSUM_SHA512, "SHA512", SHA512_sums);
+  add_checksum_bytes_test (G_CHECKSUM_SHA512, "SHA512", SHA512_sums);
+
   return g_test_run ();
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]