⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sha1impl.c

📁 IBE是一种非对称密码技术
💻 C
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
 */
#include "vibecrypto.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "algobj.h"
#include "digest.h"
#include "sha1.h"

int SHA1Init (
   VoltAlgorithmObject *obj
   )
{
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA1Ctx *sha1Ctx = (VoltSHA1Ctx *)(digestCtx->localDigestCtx);

  /* Populate the SHA-1 Ctx with the initial values.
   */
  sha1Ctx->countLow = 0;
  sha1Ctx->countHigh = 0;
  sha1Ctx->currentBlockLen = 0;
  sha1Ctx->state[0] = sha1Ctx->initState[0];
  sha1Ctx->state[1] = sha1Ctx->initState[1];
  sha1Ctx->state[2] = sha1Ctx->initState[2];
  sha1Ctx->state[3] = sha1Ctx->initState[3];
  sha1Ctx->state[4] = sha1Ctx->initState[4];

  return (0);
}

int SHA1Update (
   VoltAlgorithmObject *obj,
   unsigned char *dataToDigest,
   unsigned int dataToDigestLen
   )
{
  unsigned int copyLen;
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA1Ctx *sha1Ctx = (VoltSHA1Ctx *)(digestCtx->localDigestCtx);
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);

  if (dataToDigest == (unsigned char *)0)
    dataToDigestLen = 0;

  /* Add the input length to the running total.
   */
  sha1Ctx->countLow += dataToDigestLen;
  if (sha1Ctx->countLow < dataToDigestLen)
    sha1Ctx->countHigh++;

  /* If we have any data in the currentBlock, start there.
   */
  if (sha1Ctx->currentBlockLen != 0)
  {
    /* Copy bytes into the currentBlock. If there is enough to complete
     * a block, copy enought to complete the block and then run
     * SHA1Transform on it. If not, just copy the input into the block
     * and update currentBlockLen.
     */
    copyLen = dataToDigestLen;
    if ((dataToDigestLen + sha1Ctx->currentBlockLen) >= 64)
      copyLen = 64 - sha1Ctx->currentBlockLen;
    Z2Memcpy (
      sha1Ctx->currentBlock + sha1Ctx->currentBlockLen, dataToDigest,
      copyLen);
    sha1Ctx->currentBlockLen += copyLen;

    /* If we don't have an entire block, we're done.
     */
    if (sha1Ctx->currentBlockLen < 64)
      return (0);

    /* We have a block, process it.
     */
    sha1Ctx->SHA1Transform ((Pointer)sha1Ctx, sha1Ctx->currentBlock);
    dataToDigestLen -= copyLen;
    dataToDigest += copyLen;
    sha1Ctx->currentBlockLen = 0;
  }

  /* As long as there are complete blocks in the dataToDigest, call
   * SHA1Transform on them.
   */
  while (dataToDigestLen >= 64)
  {
    sha1Ctx->SHA1Transform ((Pointer)sha1Ctx, dataToDigest);
    dataToDigestLen -= 64;
    dataToDigest += 64;
  }

  /* If there is any data left over, copy it into the currentBlock. If
   * not, we're done.
   */
  if (dataToDigestLen == 0)
    return (0);

  Z2Memcpy (sha1Ctx->currentBlock, dataToDigest, dataToDigestLen);
  sha1Ctx->currentBlockLen = dataToDigestLen;

  return (0);
}

int SHA1Final (
   VoltAlgorithmObject *obj,
   unsigned char *digest
   )
{
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA1Ctx *sha1Ctx = (VoltSHA1Ctx *)(digestCtx->localDigestCtx);

  /* Perform padding.
   * currentBlock | 0x80 | 0x00 00 ... 00 | length
   * The length is 8 bytes, the length, in bits, of the input.
   * If there is not enough space left in currentBlock to hold the 0x80
   * byte and the 8 length bytes, finish up the current block with 0x80
   * and 0x00 00 00 ... Then create a new block of all 00's except for
   * the last 8 bytes, the length.
   */
  Z2Memset (
    sha1Ctx->currentBlock + sha1Ctx->currentBlockLen, 0,
    64 - sha1Ctx->currentBlockLen);
  if (sha1Ctx->padding == VT_SHA1_STD_PAD)
    sha1Ctx->currentBlock[sha1Ctx->currentBlockLen] = 0x80;
  if (sha1Ctx->currentBlockLen > 55)
  {
    sha1Ctx->SHA1Transform ((Pointer)sha1Ctx, sha1Ctx->currentBlock);
    Z2Memset (sha1Ctx->currentBlock, 0, 64);
  }

  /* If padding following the SHA-1 standard (as opposed to FIPS 186),
   * set the last 8 bytes to be the length. We added number of bytes,
   * we want bits, so multiply by 8 (a left-shift by 3).
   */
  if (sha1Ctx->padding == VT_SHA1_STD_PAD)
  {
    sha1Ctx->countHigh <<= 3;
    sha1Ctx->countHigh |= (sha1Ctx->countLow >> 29);
    sha1Ctx->countLow <<= 3;
    sha1Ctx->currentBlock[56] = (unsigned char)(sha1Ctx->countHigh >> 24);
    sha1Ctx->currentBlock[57] = (unsigned char)(sha1Ctx->countHigh >> 16);
    sha1Ctx->currentBlock[58] = (unsigned char)(sha1Ctx->countHigh >> 8);
    sha1Ctx->currentBlock[59] = (unsigned char)sha1Ctx->countHigh;
    sha1Ctx->currentBlock[60] = (unsigned char)(sha1Ctx->countLow >> 24);
    sha1Ctx->currentBlock[61] = (unsigned char)(sha1Ctx->countLow >> 16);
    sha1Ctx->currentBlock[62] = (unsigned char)(sha1Ctx->countLow >> 8);
    sha1Ctx->currentBlock[63] = (unsigned char)(sha1Ctx->countLow);
  }

  sha1Ctx->SHA1Transform ((Pointer)sha1Ctx, sha1Ctx->currentBlock);

  /* The state is the digest.
   */
  digest[0] = (unsigned char)(sha1Ctx->state[0] >> 24);
  digest[1] = (unsigned char)(sha1Ctx->state[0] >> 16);
  digest[2] = (unsigned char)(sha1Ctx->state[0] >> 8);
  digest[3] = (unsigned char)(sha1Ctx->state[0]);
  digest[4] = (unsigned char)(sha1Ctx->state[1] >> 24);
  digest[5] = (unsigned char)(sha1Ctx->state[1] >> 16);
  digest[6] = (unsigned char)(sha1Ctx->state[1] >> 8);
  digest[7] = (unsigned char)(sha1Ctx->state[1]);
  digest[8] = (unsigned char)(sha1Ctx->state[2] >> 24);
  digest[9] = (unsigned char)(sha1Ctx->state[2] >> 16);
  digest[10] = (unsigned char)(sha1Ctx->state[2] >> 8);
  digest[11] = (unsigned char)(sha1Ctx->state[2]);
  digest[12] = (unsigned char)(sha1Ctx->state[3] >> 24);
  digest[13] = (unsigned char)(sha1Ctx->state[3] >> 16);
  digest[14] = (unsigned char)(sha1Ctx->state[3] >> 8);
  digest[15] = (unsigned char)(sha1Ctx->state[3]);
  digest[16] = (unsigned char)(sha1Ctx->state[4] >> 24);
  digest[17] = (unsigned char)(sha1Ctx->state[4] >> 16);
  digest[18] = (unsigned char)(sha1Ctx->state[4] >> 8);
  digest[19] = (unsigned char)(sha1Ctx->state[4]);

  return (0);
}

void SHA1Transform (
   Pointer ctx,
   unsigned char *block
   )
{
  int index;
  UInt32 *state = ((VoltSHA1Ctx *)ctx)->state;
  UInt32 *W = ((VoltSHA1Ctx *)ctx)->W;
  UInt32 A, B, C, D, E, temp;

  A = state[0];
  B = state[1];
  C = state[2];
  D = state[3];
  E = state[4];

  /* Get the block as 16 words.
   */
  for (index = 0; index < 16; ++index, block += 4)
    SHA1_GET_UINT32 (block, W[index])

  /* Expand the block.
   */
  for (index = 16; index < 80; ++index)
  {
    temp = W[index - 3] ^ W[index - 8] ^ W[index - 14] ^ W[index - 16]; 
    W[index] = SHA1_ROTL (temp, 1);
  }

  /* The real work of SHA1Transform.
   */
  /* Rounds 0 - 19
   */
  for (index = 0;  index < 20; ++index)
  {
    temp = SHA1_ROTL (A, 5) + F0 (B, C, D) + E + W[index] + SHA1_K0;
    E = D;
    D = C;
    C = SHA1_ROTL (B, 30);
    B = A;
    A = temp;
  }

  /* Rounds 20 - 39
   */
  for (index = 20; index < 40; ++index)
  {
    temp = SHA1_ROTL (A, 5) + F2 (B, C, D) + E + W[index] + SHA1_K2;
    E = D;
    D = C;
    C = SHA1_ROTL (B, 30);
    B = A;
    A = temp; 
  }

  /* Rounds 40 - 59
   */
  for (index = 40; index < 60; ++index)
  {
    temp = SHA1_ROTL (A, 5) + F4 (B, C, D) + E + W[index] + SHA1_K4;
    E = D;
    D = C;
    C = SHA1_ROTL (B, 30);
    B = A;
    A = temp;
  }

  /* Rounds 60 - 79
   */
  for (index = 60; index < 80; ++index)
  {
    temp = SHA1_ROTL (A, 5) + F6 (B, C, D) + E + W[index] + SHA1_K6;
    E = D;
    D = C;
    C = SHA1_ROTL (B, 30);
    B = A;
    A = temp;
  }

  /* Add the results of the rounds to the state.
   */
  state[0] += A;
  state[1] += B;
  state[2] += C;
  state[3] += D;
  state[4] += E;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -