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

📄 sha512impl.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 "sha512.h"
#include "errorctx.h"

int SHA512SetDigestInitState (
   VoltAlgorithmObject *obj,
   VtItem *newState
   )
{
  int status, index;
  UInt64 current;
  unsigned char *buffer;
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA512Ctx *sha512Ctx = (VoltSHA512Ctx *)(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 != 64) )
      break;

    buffer = newState->data;
    for (index = 0; index < 8; ++index)
    {
      /* Get the next four bytes of the state as an int.
       */
      current =
        ((UInt64)(buffer[0]) << 56) +
        ((UInt64)(buffer[1]) << 48) +
        ((UInt64)(buffer[2]) << 40) +
        ((UInt64)(buffer[3]) << 32) +
        ((UInt64)(buffer[4]) << 24) +
        ((UInt64)(buffer[5]) << 16) +
        ((UInt64)(buffer[6]) <<  8) +
        ((UInt64)(buffer[7]));
      sha512Ctx->initState[index] = current;
      buffer += 8;
    }

    status = 0;

  } while (0);

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

  return (status);
}

int SHA512Init (
   VoltAlgorithmObject *obj
   )
{
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA512Ctx *sha512Ctx = (VoltSHA512Ctx *)(digestCtx->localDigestCtx);

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

  return (0);
}

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

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

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

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

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

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

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

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

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

  return (0);
}

int SHA512Final (
   VoltAlgorithmObject *obj,
   unsigned char *digest
   )
{
  int indexD, indexS, shiftCount;
  UInt64 currentValue;
  VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
  VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)(obj->classCtx);
  VoltSHA512Ctx *sha512Ctx = (VoltSHA512Ctx *)(digestCtx->localDigestCtx);

  /* Perform padding.
   * currentBlock | 0x80 | 0x00 00 ... 00 | length
   * The length is 16 bytes, the length, in bits, of the input.
   * If there is not enough space left in currentBlock to hold the 0x80
   * byte and the 16 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 16 bytes, the length.
   */
  Z2Memset (
    sha512Ctx->currentBlock + sha512Ctx->currentBlockLen, 0,
    128 - sha512Ctx->currentBlockLen);
  sha512Ctx->currentBlock[sha512Ctx->currentBlockLen] = 0x80;
  if (sha512Ctx->currentBlockLen > 111)
  {
    sha512Ctx->SHA512Transform ((Pointer)sha512Ctx, sha512Ctx->currentBlock);
    Z2Memset (sha512Ctx->currentBlock, 0, 128);
  }

  /* Set the last 16 bytes to be the length. We added number of bytes,
   * we want bits, so multiply by 8 (a left-shift by 3).
   */
  sha512Ctx->countHigh <<= 3;
  sha512Ctx->countHigh |= (sha512Ctx->countLow >> 61);
  sha512Ctx->countLow <<= 3;
  sha512Ctx->currentBlock[112] = (unsigned char)(sha512Ctx->countHigh >> 56);
  sha512Ctx->currentBlock[113] = (unsigned char)(sha512Ctx->countHigh >> 48);
  sha512Ctx->currentBlock[114] = (unsigned char)(sha512Ctx->countHigh >> 40);
  sha512Ctx->currentBlock[115] = (unsigned char)(sha512Ctx->countHigh >> 32);
  sha512Ctx->currentBlock[116] = (unsigned char)(sha512Ctx->countHigh >> 24);
  sha512Ctx->currentBlock[117] = (unsigned char)(sha512Ctx->countHigh >> 16);
  sha512Ctx->currentBlock[118] = (unsigned char)(sha512Ctx->countHigh >> 8);
  sha512Ctx->currentBlock[119] = (unsigned char)(sha512Ctx->countHigh);
  sha512Ctx->currentBlock[120] = (unsigned char)(sha512Ctx->countLow >> 56);
  sha512Ctx->currentBlock[121] = (unsigned char)(sha512Ctx->countLow >> 48);
  sha512Ctx->currentBlock[122] = (unsigned char)(sha512Ctx->countLow >> 40);
  sha512Ctx->currentBlock[123] = (unsigned char)(sha512Ctx->countLow >> 32);
  sha512Ctx->currentBlock[124] = (unsigned char)(sha512Ctx->countLow >> 24);
  sha512Ctx->currentBlock[125] = (unsigned char)(sha512Ctx->countLow >> 16);
  sha512Ctx->currentBlock[126] = (unsigned char)(sha512Ctx->countLow >> 8);
  sha512Ctx->currentBlock[127] = (unsigned char)(sha512Ctx->countLow);

  sha512Ctx->SHA512Transform ((Pointer)sha512Ctx, sha512Ctx->currentBlock);

  /* The state is the digest.
   */
  for (indexS = 0; indexS < 8; ++indexS)
  {
    currentValue = sha512Ctx->state[indexS];
    for (indexD = 0, shiftCount = 56; indexD < 8; ++indexD, shiftCount -= 8)
      digest[indexD] = (unsigned char)(currentValue >> shiftCount);

    digest += 8;
  }

  return (0);
}

void SHA512Transform (
   Pointer ctx,
   unsigned char *block
   )
{
  int index;
  UInt64 *state = ((VoltSHA512Ctx *)ctx)->state;
  UInt64 *W = ((VoltSHA512Ctx *)ctx)->W;
  UInt64 *K = ((VoltSHA512Ctx *)ctx)->K;
  UInt64 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 += 8)
  {
    SHA512_GET_UINT64 (block, W[index])
  }

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

  /* Adjust the working variables 80 times.
   */
  for (index = 0; index < 80; ++index)
  {
    T1 =
      H + SHA512_CAP_SIGMA_1 (E) + SHA512_CH (E, F, G) + K[index] + W[index];
    T2 = SHA512_CAP_SIGMA_0 (A) + SHA512_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 + -