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

📄 sha256impl.c

📁 IBE是一种非对称密码技术
💻 C
字号:
/* Copyright 2005-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 "sha256.h"
#include "errorctx.h"

int SHA256SetDigestInitState (
   VoltAlgorithmObject *obj,
   VtItem *newState
   )
{
  int status, index;
  UInt32 current;
  unsigned char *buffer;
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA256Ctx *sha256Ctx = (VoltSHA256Ctx *)(digestCtx->localDigestCtx);
  VOLT_DECLARE_FNCT_LINE (fnctLine)

  do
  {
    /* Make sure we have a new state and the length is correct.
     */
    VOLT_SET_FNCT_LINE (fnctLine)
    status = VT_ERROR_INVALID_ASSOCIATED_INFO;
    if ( (newState->data == (unsigned char *)0) || (newState->len != 32) )
      break;

    buffer = newState->data;
    for (index = 0; index < 8; ++index)
    {
      /* Get the next four bytes of the state as an int.
       */
      current =
        ((UInt32)(buffer[0]) << 24) +
        ((UInt32)(buffer[1]) << 16) +
        ((UInt32)(buffer[2]) <<  8) +
        ((UInt32)(buffer[3]));
      sha256Ctx->initState[index] = current;
      buffer += 4;
    }

    status = 0;

  } while (0);

  VOLT_LOG_ERROR_INFO_COMPARE (
    status, 0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
    (char *)0, "SHA256SetDigestInitState", fnctLine, (char *)0)

  return (status);
}

int SHA256Init (
   VoltAlgorithmObject *obj
   )
{
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA256Ctx *sha256Ctx = (VoltSHA256Ctx *)(digestCtx->localDigestCtx);

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

  return (0);
}

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

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

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

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

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

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

  /* As long as there are complete blocks in the dataToDigest, call
   * SHA256Transform on them.
   */
  while (dataToDigestLen >= 64)
  {
    sha256Ctx->SHA256Transform ((Pointer)sha256Ctx, 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 (sha256Ctx->currentBlock, dataToDigest, dataToDigestLen);
  sha256Ctx->currentBlockLen = dataToDigestLen;

  return (0);
}

int SHA256Final (
   VoltAlgorithmObject *obj,
   unsigned char *digest
   )
{
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA256Ctx *sha256Ctx = (VoltSHA256Ctx *)(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 (
    sha256Ctx->currentBlock + sha256Ctx->currentBlockLen, 0,
    64 - sha256Ctx->currentBlockLen);
  sha256Ctx->currentBlock[sha256Ctx->currentBlockLen] = 0x80;
  if (sha256Ctx->currentBlockLen > 55)
  {
    sha256Ctx->SHA256Transform ((Pointer)sha256Ctx, sha256Ctx->currentBlock);
    Z2Memset (sha256Ctx->currentBlock, 0, 64);
  }

  /* 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).
   */
  sha256Ctx->countHigh <<= 3;
  sha256Ctx->countHigh |= (sha256Ctx->countLow >> 29);
  sha256Ctx->countLow <<= 3;
  sha256Ctx->currentBlock[56] = (unsigned char)(sha256Ctx->countHigh >> 24);
  sha256Ctx->currentBlock[57] = (unsigned char)(sha256Ctx->countHigh >> 16);
  sha256Ctx->currentBlock[58] = (unsigned char)(sha256Ctx->countHigh >> 8);
  sha256Ctx->currentBlock[59] = (unsigned char)(sha256Ctx->countHigh);
  sha256Ctx->currentBlock[60] = (unsigned char)(sha256Ctx->countLow >> 24);
  sha256Ctx->currentBlock[61] = (unsigned char)(sha256Ctx->countLow >> 16);
  sha256Ctx->currentBlock[62] = (unsigned char)(sha256Ctx->countLow >> 8);
  sha256Ctx->currentBlock[63] = (unsigned char)(sha256Ctx->countLow);

  sha256Ctx->SHA256Transform ((Pointer)sha256Ctx, sha256Ctx->currentBlock);

  /* The state is the digest.
   */
  digest[0]  = (unsigned char)(sha256Ctx->state[0] >> 24);
  digest[1]  = (unsigned char)(sha256Ctx->state[0] >> 16);
  digest[2]  = (unsigned char)(sha256Ctx->state[0] >> 8);
  digest[3]  = (unsigned char)(sha256Ctx->state[0]);
  digest[4]  = (unsigned char)(sha256Ctx->state[1] >> 24);
  digest[5]  = (unsigned char)(sha256Ctx->state[1] >> 16);
  digest[6]  = (unsigned char)(sha256Ctx->state[1] >> 8);
  digest[7]  = (unsigned char)(sha256Ctx->state[1]);
  digest[8]  = (unsigned char)(sha256Ctx->state[2] >> 24);
  digest[9]  = (unsigned char)(sha256Ctx->state[2] >> 16);
  digest[10] = (unsigned char)(sha256Ctx->state[2] >> 8);
  digest[11] = (unsigned char)(sha256Ctx->state[2]);
  digest[12] = (unsigned char)(sha256Ctx->state[3] >> 24);
  digest[13] = (unsigned char)(sha256Ctx->state[3] >> 16);
  digest[14] = (unsigned char)(sha256Ctx->state[3] >> 8);
  digest[15] = (unsigned char)(sha256Ctx->state[3]);
  digest[16] = (unsigned char)(sha256Ctx->state[4] >> 24);
  digest[17] = (unsigned char)(sha256Ctx->state[4] >> 16);
  digest[18] = (unsigned char)(sha256Ctx->state[4] >> 8);
  digest[19] = (unsigned char)(sha256Ctx->state[4]);
  digest[20] = (unsigned char)(sha256Ctx->state[5] >> 24);
  digest[21] = (unsigned char)(sha256Ctx->state[5] >> 16);
  digest[22] = (unsigned char)(sha256Ctx->state[5] >> 8);
  digest[23] = (unsigned char)(sha256Ctx->state[5]);
  digest[24] = (unsigned char)(sha256Ctx->state[6] >> 24);
  digest[25] = (unsigned char)(sha256Ctx->state[6] >> 16);
  digest[26] = (unsigned char)(sha256Ctx->state[6] >> 8);
  digest[27] = (unsigned char)(sha256Ctx->state[6]);
  digest[28] = (unsigned char)(sha256Ctx->state[7] >> 24);
  digest[29] = (unsigned char)(sha256Ctx->state[7] >> 16);
  digest[30] = (unsigned char)(sha256Ctx->state[7] >> 8);
  digest[31] = (unsigned char)(sha256Ctx->state[7]);

  return (0);
}

void SHA256Transform (
   Pointer ctx,
   unsigned char *block
   )
{
  int index;
  UInt32 *state = ((VoltSHA256Ctx *)ctx)->state;
  UInt32 *W = ((VoltSHA256Ctx *)ctx)->W;
  UInt32 *K = ((VoltSHA256Ctx *)ctx)->K;
  UInt32 A, B, C, D, E, F, G, H, T1, T2;

  /* Initialize the working variables.
   */
  A = state[0];
  B = state[1];
  C = state[2];
  D = state[3];
  E = state[4];
  F = state[5];
  G = state[6];
  H = state[7];

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

  /* Expand the block.
   */
  for (index = 16; index < 64; ++index)
  {
    T1 = SHA256_SIGMA_1 (W[index - 2]);
    T2 = SHA256_SIGMA_0 (W[index - 15]);
    W[index] = T1 + W[index - 7] + T2 + W[index - 16];
  }

  /* Adjust the working variables 64 times.
   */
  for (index = 0; index < 64; ++index)
  {
    T1 =
      H + SHA256_CAP_SIGMA_1 (E) + SHA256_CH (E, F, G) + K[index] + W[index];
    T2 = SHA256_CAP_SIGMA_0 (A) + SHA256_MAJ (A, B, C);
    H = G;
    G = F;
    F = E;
    E = D + T1;
    D = C;
    C = B;
    B = A;
    A = T1 + T2;
  }

  state[0] += A;
  state[1] += B;
  state[2] += C;
  state[3] += D;
  state[4] += E;
  state[5] += F;
  state[6] += G;
  state[7] += H;

  return;
}

⌨️ 快捷键说明

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