SHA512

#include "sha512.h"

...

void __fastcall TfrmMain::btnWorkClick(TObject *Sender)
{
     char cDigest[SHA512_DIGEST_SIZE];

     memset(cDigest, 0, sizeof(cDigest));

     Sha512 sh;

     sh.Update((BYTE*)ledStringInput->Text.c_str(), strlen(ledStringInput->Text.c_str()));
     sh.Final(cDigest);

     ledSHA512Digest->Text = cDigest;
}
  • sha512.h
/*
 * FIPS 180-2 SHA-224/256/384/512 implementation
 * Last update: 02/02/2007
 * Issue date:  04/30/2005
 *
 * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
 
#ifndef SHA2_H
#define SHA2_H
 
#define SHA224_DIGEST_SIZE ( 224 / 8 )
#define SHA256_DIGEST_SIZE ( 256 / 8 )
#define SHA384_DIGEST_SIZE ( 384 / 8 )
#define SHA512_DIGEST_SIZE ( 512 / 8 )
 
#define SHA256_BLOCK_SIZE  ( 512 / 8 )
#define SHA512_BLOCK_SIZE  (1024 / 8 )
#define SHA384_BLOCK_SIZE  SHA512_BLOCK_SIZE
#define SHA224_BLOCK_SIZE  SHA256_BLOCK_SIZE
 
#ifndef SHA2_TYPES
#define SHA2_TYPES
typedef unsigned char uint8;
typedef unsigned int  uint32;
typedef unsigned long long uint64;
typedef unsigned char BYTE;
#endif
 
class Sha256
{
public:
    Sha256();
    void Update(const BYTE* pData, unsigned int len);
    void Final(BYTE* pDigest);
private:
    void Transfer(const BYTE* pData, unsigned int block_nb);
private:
    unsigned int tot_len;
    unsigned int len;
    unsigned char block[2 * SHA256_BLOCK_SIZE];
    unsigned int h[8];
};
 
class Sha224
{
public:
    Sha224();
    void Update(const BYTE* pData, unsigned int len);
    void Final(BYTE* pDigest);
private:
    void Transfer(const BYTE* pData, unsigned int block_nb);
private:
    unsigned int tot_len;
    unsigned int len;
    unsigned char block[2 * SHA224_BLOCK_SIZE];
    unsigned int h[8];
};
 
class Sha512
{
public:
    Sha512();
    void Update(const BYTE* pData, unsigned int len);
    void Final(BYTE* pDigest);
private:
    void Transfer(const BYTE* pData, unsigned int block_nb);
private:
    unsigned int tot_len;
    unsigned int len;
    unsigned char block[2 * SHA512_BLOCK_SIZE];
    unsigned long long h[8];
};
 
class Sha384
{
public:
    Sha384();
    void Update(const BYTE* pData, unsigned int len);
    void Final(BYTE* pDigest);
private:
    void Transfer(const BYTE* pData, unsigned int block_nb);
private:
    unsigned int tot_len;
    unsigned int len;
    unsigned char block[2 * SHA384_BLOCK_SIZE];
    unsigned long long h[8];
};
 
#endif /* !SHA2_H */
  • sha512.cpp
/*
 * FIPS 180-2 SHA-224/256/384/512 implementation
 * Last update: 02/02/2007
 * Issue date:  04/30/2005
 *
 * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
 
#include <string.h>
 
#include "Sha512.h"
 
#define SHFR(x, n)    (x >> n)
#define ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define ROTL(x, n)   ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define CH(x, y, z)  ((x & y) ^ (~x & z))
#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
 
#define SHA256_F1(x) (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define SHA256_F2(x) (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define SHA256_F3(x) (ROTR(x,  7) ^ ROTR(x, 18) ^ SHFR(x,  3))
#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
 
#define SHA512_F1(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))
#define SHA512_F2(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))
#define SHA512_F3(x) (ROTR(x,  1) ^ ROTR(x,  8 ) ^ SHFR(x,  7))
#define SHA512_F4(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHFR(x,  6))
 
#define UNPACK32(x, str)                      
{                                             
    *((str) + 3) = (uint8) ((x)      );       
    *((str) + 2) = (uint8) ((x) >>  8);       
    *((str) + 1) = (uint8) ((x) >> 16);       
    *((str) + 0) = (uint8) ((x) >> 24);       
}
 
#define PACK32(str, x)                        
{                                             
    *(x) =   ((uint32) *((str) + 3)      )    
           | ((uint32) *((str) + 2) <<  8)    
           | ((uint32) *((str) + 1) << 16)    
           | ((uint32) *((str) + 0) << 24);   
}
 
#define UNPACK64(x, str)                      
{                                             
    *((str) + 7) = (uint8) ((x)      );       
    *((str) + 6) = (uint8) ((x) >>  8);       
    *((str) + 5) = (uint8) ((x) >> 16);       
    *((str) + 4) = (uint8) ((x) >> 24);       
    *((str) + 3) = (uint8) ((x) >> 32);       
    *((str) + 2) = (uint8) ((x) >> 40);       
    *((str) + 1) = (uint8) ((x) >> 48);       
    *((str) + 0) = (uint8) ((x) >> 56);       
}
 
#define PACK64(str, x)                        
{                                             
    *(x) =   ((uint64) *((str) + 7)      )    
           | ((uint64) *((str) + 6) <<  8)    
           | ((uint64) *((str) + 5) << 16)    
           | ((uint64) *((str) + 4) << 24)    
           | ((uint64) *((str) + 3) << 32)    
           | ((uint64) *((str) + 2) << 40)    
           | ((uint64) *((str) + 1) << 48)    
           | ((uint64) *((str) + 0) << 56);   
}
 
/* Macros used for loops unrolling */
 
#define SHA256_SCR(i)                         
{                                             
    w[i] =  SHA256_F4(w[i -  2]) + w[i -  7]  
          + SHA256_F3(w[i - 15]) + w[i - 16]; 
}
 
#define SHA512_SCR(i)                         
{                                             
    w[i] =  SHA512_F4(w[i -  2]) + w[i -  7]  
          + SHA512_F3(w[i - 15]) + w[i - 16]; 
}
 
#define SHA256_EXP(a, b, c, d, e, f, g, h, j)               
{                                                           
    t1 = wv[h] + SHA256_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) 
         + sha256_k[j] + w[j];                              
    t2 = SHA256_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]);       
    wv[d] += t1;                                            
    wv[h] = t1 + t2;                                        
}
 
#define SHA512_EXP(a, b, c, d, e, f, g ,h, j)               
{                                                           
    t1 = wv[h] + SHA512_F2(wv[e]) + CH(wv[e], wv[f], wv[g]) 
         + sha512_k[j] + w[j];                              
    t2 = SHA512_F1(wv[a]) + MAJ(wv[a], wv[b], wv[c]);       
    wv[d] += t1;                                            
    wv[h] = t1 + t2;                                        
}
 
uint32 sha224_h0[8] =
            {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
 
uint32 sha256_h0[8] =
            {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
 
uint64 sha384_h0[8] =
            {0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
             0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
             0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
             0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
 
uint64 sha512_h0[8] =
            {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
             0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
             0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
             0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
 
uint32 sha256_k[64] =
            {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
             0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
             0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
             0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
             0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
             0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
             0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
             0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
             0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
 
uint64 sha512_k[80] =
            {0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
             0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
             0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
             0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
             0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
             0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
             0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
             0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
             0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
             0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
             0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
             0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
             0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
             0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
             0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
             0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
             0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
             0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
             0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
             0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
             0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
             0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
             0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
             0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
             0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
             0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
             0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
             0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
             0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
             0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
             0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
             0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
             0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
             0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
             0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
             0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
             0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
             0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
             0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
             0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
 
/* SHA-256 functions */
 
void Sha256::Transfer(const BYTE* pData,
                   unsigned int block_nb)
{
    uint32 w[64];
    uint32 wv[8];
    uint32 t1, t2;
    const BYTE* sub_block;
 
    for (int i = 0; i < (int) block_nb; i++) {
        sub_block = pData + (i << 6);
 
        for (int j = 0; j < 16; j++) {
            PACK32(&sub_block[j << 2], &w[j]);
        }
 
        for (int j = 16; j < 64; j++) {
            SHA256_SCR(j);
        }
 
        for (int j = 0; j < 8; j++) {
            wv[j] = h[j];
        }
 
        for (int j = 0; j < 64; j++) {
            t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
                + sha256_k[j] + w[j];
            t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
            wv[7] = wv[6];
            wv[6] = wv[5];
            wv[5] = wv[4];
            wv[4] = wv[3] + t1;
            wv[3] = wv[2];
            wv[2] = wv[1];
            wv[1] = wv[0];
            wv[0] = t1 + t2;
        }
 
        for (int j = 0; j < 8; j++) {
            h[j] += wv[j];
        }
    }
}
 
Sha256::Sha256()
{
    for (int i = 0; i < 8; i++) {
        h[i] = sha256_h0[i];
    }
 
    len = 0;
    tot_len = 0;
}
 
void Sha256::Update(const BYTE* pData,
                   unsigned int len)
{
    unsigned int block_nb;
    unsigned int new_len, rem_len, tmp_len;
    const BYTE* shifted_data;
 
    tmp_len = SHA256_BLOCK_SIZE - len;
    rem_len = len < tmp_len ? len : tmp_len;
 
    memcpy(&block[len], pData, rem_len);
 
    if (len + len < SHA256_BLOCK_SIZE) {
        len += len;
        return;
    }
 
    new_len = len - rem_len;
    block_nb = new_len / SHA256_BLOCK_SIZE;
 
    shifted_data = pData + rem_len;
 
    Transfer(block, 1);
    Transfer(shifted_data, block_nb);
 
    rem_len = new_len % SHA256_BLOCK_SIZE;
 
    memcpy(block, &shifted_data[block_nb << 6],
           rem_len);
 
    len = rem_len;
    tot_len += (block_nb + 1) << 6;
}
 
void Sha256::Final(BYTE* pDigest)
{
    unsigned int block_nb;
    unsigned int pm_len;
    unsigned int len_b;
 
    block_nb = (1 + ((SHA256_BLOCK_SIZE - 9)
                     < (len % SHA256_BLOCK_SIZE)));
 
    len_b = (tot_len + len) << 3;
    pm_len = block_nb << 6;
 
    memset(block + len, 0, pm_len - len);
    block[len] = 0x80;
    UNPACK32(len_b, block + pm_len - 4);
 
    Transfer(block, block_nb);
 
    for (int i = 0 ; i < 8; i++) {
        UNPACK32(h[i], &pDigest[i << 2]);
    }
}
 
/* SHA-512 functions */
 
void Sha512::Transfer(const BYTE* pData,
                   unsigned int block_nb)
{
    uint64 w[80];
    uint64 wv[8];
    uint64 t1, t2;
    const BYTE* sub_block;
 
    for (int i = 0; i < (int) block_nb; i++) {
        sub_block = pData + (i << 7);
 
        for (int j = 0; j < 16; j++) {
            PACK64(&sub_block[j << 3], &w[j]);
        }
 
        for (int j = 16; j < 80; j++) {
            SHA512_SCR(j);
        }
 
        for (int j = 0; j < 8; j++) {
            wv[j] = h[j];
        }
 
        for (int j = 0; j < 80; j++) {
            t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
                + sha512_k[j] + w[j];
            t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
            wv[7] = wv[6];
            wv[6] = wv[5];
            wv[5] = wv[4];
            wv[4] = wv[3] + t1;
            wv[3] = wv[2];
            wv[2] = wv[1];
            wv[1] = wv[0];
            wv[0] = t1 + t2;
        }
 
        for (int j = 0; j < 8; j++) {
            h[j] += wv[j];
        }
    }
}
 
Sha512::Sha512()
{
    for (int i = 0; i < 8; i++) {
        h[i] = sha512_h0[i];
    }
 
    len = 0;
    tot_len = 0;
}
 
void Sha512::Update(const BYTE* pData,
                   unsigned int len)
{
    unsigned int block_nb;
    unsigned int new_len, rem_len, tmp_len;
    const BYTE* shifted_data;
 
    tmp_len = SHA512_BLOCK_SIZE - len;
    rem_len = len < tmp_len ? len : tmp_len;
 
    memcpy(&block[len], pData, rem_len);
 
    if (len + len < SHA512_BLOCK_SIZE) {
        len += len;
        return;
    }
 
    new_len = len - rem_len;
    block_nb = new_len / SHA512_BLOCK_SIZE;
 
    shifted_data = pData + rem_len;
 
    Transfer(block, 1);
    Transfer(shifted_data, block_nb);
 
    rem_len = new_len % SHA512_BLOCK_SIZE;
 
    memcpy(block, &shifted_data[block_nb << 7],
           rem_len);
 
    len = rem_len;
    tot_len += (block_nb + 1) << 7;
}
 
void Sha512::Final(BYTE* digest)
{
    unsigned int block_nb;
    unsigned int pm_len;
    unsigned int len_b;
 
 
    block_nb = 1 + ((SHA512_BLOCK_SIZE - 17)
                     < (len % SHA512_BLOCK_SIZE));
 
    len_b = (tot_len + len) << 3;
    pm_len = block_nb << 7;
 
    memset(block + len, 0, pm_len - len);
    block[len] = 0x80;
    UNPACK32(len_b, block + pm_len - 4);
 
    Transfer(block, block_nb);
 
    for (int i = 0 ; i < 8; i++) {
        UNPACK64(h[i], &digest[i << 3]);
    }
}
 
/* SHA-384 functions */
 
Sha384::Sha384()
{
    for (int i = 0; i < 8; i++) {
        h[i] = sha384_h0[i];
    }
 
    len = 0;
    tot_len = 0;
}
 
void Sha384::Update(const BYTE* pData,
                   unsigned int len)
{
    unsigned int block_nb;
    unsigned int new_len, rem_len, tmp_len;
    const BYTE* shifted_data;
 
    tmp_len = SHA384_BLOCK_SIZE - len;
    rem_len = len < tmp_len ? len : tmp_len;
 
    memcpy(&block[len], pData, rem_len);
 
    if (len + len < SHA384_BLOCK_SIZE) {
        len += len;
        return;
    }
 
    new_len = len - rem_len;
    block_nb = new_len / SHA384_BLOCK_SIZE;
 
    shifted_data = pData + rem_len;
 
    Transfer(block, 1);
    Transfer(shifted_data, block_nb);
 
    rem_len = new_len % SHA384_BLOCK_SIZE;
 
    memcpy(block, &shifted_data[block_nb << 7],
           rem_len);
 
    len = rem_len;
    tot_len += (block_nb + 1) << 7;
}
 
void Sha384::Final(BYTE* digest)
{
    unsigned int block_nb;
    unsigned int pm_len;
    unsigned int len_b;
 
 
    block_nb = (1 + ((SHA384_BLOCK_SIZE - 17)
                     < (len % SHA384_BLOCK_SIZE)));
 
    len_b = (tot_len + len) << 3;
    pm_len = block_nb << 7;
 
    memset(block + len, 0, pm_len - len);
    block[len] = 0x80;
    UNPACK32(len_b, block + pm_len - 4);
 
    Transfer(block, block_nb);
 
    for (int i = 0 ; i < 6; i++) {
        UNPACK64(h[i], &digest[i << 3]);
    }
}
 
void Sha384::Transfer(const BYTE* pData,
                   unsigned int block_nb)
{
    uint64 w[80];
    uint64 wv[8];
    uint64 t1, t2;
    const BYTE* sub_block;
 
    for (int i = 0; i < (int) block_nb; i++) {
        sub_block = pData + (i << 7);
 
        for (int j = 0; j < 16; j++) {
            PACK64(&sub_block[j << 3], &w[j]);
        }
 
        for (int j = 16; j < 80; j++) {
            SHA512_SCR(j);
        }
 
        for (int j = 0; j < 8; j++) {
            wv[j] = h[j];
        }
 
        for (int j = 0; j < 80; j++) {
            t1 = wv[7] + SHA512_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
                + sha512_k[j] + w[j];
            t2 = SHA512_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
            wv[7] = wv[6];
            wv[6] = wv[5];
            wv[5] = wv[4];
            wv[4] = wv[3] + t1;
            wv[3] = wv[2];
            wv[2] = wv[1];
            wv[1] = wv[0];
            wv[0] = t1 + t2;
        }
 
        for (int j = 0; j < 8; j++) {
            h[j] += wv[j];
        }
    }
}
 
/* SHA-224 functions */
 
Sha224::Sha224()
{
    for (int i = 0; i < 8; i++) {
        h[i] = sha224_h0[i];
    }
 
    len = 0;
    tot_len = 0;
}
 
void Sha224::Update(const BYTE* pData,
                   unsigned int len)
{
    unsigned int block_nb;
    unsigned int new_len, rem_len, tmp_len;
    const BYTE* shifted_data;
 
    tmp_len = SHA224_BLOCK_SIZE - len;
    rem_len = len < tmp_len ? len : tmp_len;
 
    memcpy(&block[len], pData, rem_len);
 
    if (len + len < SHA224_BLOCK_SIZE) {
        len += len;
        return;
    }
 
    new_len = len - rem_len;
    block_nb = new_len / SHA224_BLOCK_SIZE;
 
    shifted_data = pData + rem_len;
 
    Transfer(block, 1);
    Transfer(shifted_data, block_nb);
 
    rem_len = new_len % SHA224_BLOCK_SIZE;
 
    memcpy(block, &shifted_data[block_nb << 6],
           rem_len);
 
    len = rem_len;
    tot_len += (block_nb + 1) << 6;
}
 
void Sha224::Final(BYTE* digest)
{
    unsigned int block_nb;
    unsigned int pm_len;
    unsigned int len_b;
 
 
    block_nb = (1 + ((SHA224_BLOCK_SIZE - 9)
                     < (len % SHA224_BLOCK_SIZE)));
 
    len_b = (tot_len + len) << 3;
    pm_len = block_nb << 6;
 
    memset(block + len, 0, pm_len - len);
    block[len] = 0x80;
    UNPACK32(len_b, block + pm_len - 4);
 
    Transfer(block, block_nb);
 
    for (int i = 0 ; i < 7; i++) {
        UNPACK32(h[i], &digest[i << 2]);
    }
}
 
void Sha224::Transfer(const BYTE* pData,
                   unsigned int block_nb)
{
    uint32 w[64];
    uint32 wv[8];
    uint32 t1, t2;
    const BYTE* sub_block;
 
    for (int i = 0; i < (int) block_nb; i++) {
        sub_block = pData + (i << 6);
 
        for (int j = 0; j < 16; j++) {
            PACK32(&sub_block[j << 2], &w[j]);
        }
 
        for (int j = 16; j < 64; j++) {
            SHA256_SCR(j);
        }
 
        for (int j = 0; j < 8; j++) {
            wv[j] = h[j];
        }
 
        for (int j = 0; j < 64; j++) {
            t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
                + sha256_k[j] + w[j];
            t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
            wv[7] = wv[6];
            wv[6] = wv[5];
            wv[5] = wv[4];
            wv[4] = wv[3] + t1;
            wv[3] = wv[2];
            wv[2] = wv[1];
            wv[1] = wv[0];
            wv[0] = t1 + t2;
        }
 
        for (int j = 0; j < 8; j++) {
            h[j] += wv[j];
        }
    }
}

SHA1

  • Borland C++ Builder Implemetierung des SHA1 Hash Algorithmus
  • Dank an Dominik Reichl (http://www.dominik-reichl.de)
  • Verwendung:
#include "sha1.h"

...

void __fastcall TfrmSHA1::btnSHA1StringClick(TObject *Sender)
{
     char cHex[128];

     memset(cHex, 0, sizeof(cHex));
    
     CSHA1 sha1;

     sha1.Reset();
     sha1.Update((UINT_8 *)ledString->Text.c_str(), strlen(ledString->Text.c_str()));
     sha1.Final();

     sha1.ReportHash(cHex, CSHA1::REPORT_HEX);

     ledHex->Text = cHex;
}

void __fastcall TfrmSHA1::btnSHA1FileClick(TObject *Sender)
{
     char szFilename[255];
     char szReport[1024];
     bool bSuccess = false;
     CSHA1 sha1;

     strcpy(&szFilename[0], "testfile.exe");
     szReport[0] = 0;

     sha1.Reset();
     bSuccess = sha1.HashFile(szFilename);
     sha1.Final();

     sha1.ReportHash(szReport, CSHA1::REPORT_HEX);

     if (bSuccess) ledHex->Text = szReport;
     else ledHex->Text = "Error.";
}
  • sha1.h
/*
    100% free public domain implementation of the SHA-1 algorithm
    by Dominik Reichl <dominik.reichl@t-online.de>
    Web: http://www.dominik-reichl.de/

    Version 1.7 - 2006-12-21
    - Fixed buffer underrun warning which appeared when compiling with
      Borland C Builder (thanks to Rex Bloom and Tim Gallagher for the
      patch)
    - Breaking change: ReportHash writes the final hash to the start
      of the buffer, i.e. it's not appending it to the string any more
    - Made some function parameters const
    - Added Visual Studio 2005 project files to demo project

    Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
    - You can set the endianness in your files, no need to modify the
      header file of the CSHA1 class any more
    - Aligned data support
    - Made support/compilation of the utility functions (ReportHash
      and HashFile) optional (useful when bytes count, for example in
      embedded environments)

    Version 1.5 - 2005-01-01
    - 64-bit compiler compatibility added
    - Made variable wiping optional (define SHA1_WIPE_VARIABLES)
    - Removed unnecessary variable initializations
    - ROL32 improvement for the Microsoft compiler (using _rotl)

    ======== Test Vectors (from FIPS PUB 180-1) ========

    SHA1("abc") =
        A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D

    SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
        84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1

    SHA1(A million repetitions of "a") =
        34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/

#ifndef ___SHA1_HDR___
#define ___SHA1_HDR___

#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)
#define SHA1_UTILITY_FUNCTIONS
#endif

#include <memory.h> // Required for memset and memcpy

#ifdef SHA1_UTILITY_FUNCTIONS
#include <stdio.h>  // Required for file access and sprintf
#include <string.h> // Required for strcat and strcpy
#endif

#ifdef _MSC_VER
#include <stdlib.h>
#endif

// You can define the endian mode in your files, without modifying the SHA1
// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN
// in your files, before including the SHA1.h header file. If you don't
// define anything, the class defaults to little endian.
#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
#define SHA1_LITTLE_ENDIAN
#endif

// Same here. If you want variable wiping, #define SHA1_WIPE_VARIABLES, if
// not, #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it
// defaults to wiping.
#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES)
#define SHA1_WIPE_VARIABLES
#endif

/////////////////////////////////////////////////////////////////////////////
// Define 8- and 32-bit variables

#ifndef UINT_32

#ifdef _MSC_VER // Compiling with Microsoft compiler

#define UINT_8  unsigned __int8
#define UINT_32 unsigned __int32

#else // !_MSC_VER

#define UINT_8 unsigned char

#if (ULONG_MAX == 0xFFFFFFFF)
#define UINT_32 unsigned long
#else
#define UINT_32 unsigned int
#endif

#endif // _MSC_VER
#endif // UINT_32

/////////////////////////////////////////////////////////////////////////////
// Declare SHA1 workspace

typedef union
{
    UINT_8 c[64];
    UINT_32 l[16];
} SHA1_WORKSPACE_BLOCK;

class CSHA1
{
public:
#ifdef SHA1_UTILITY_FUNCTIONS
    // Two different formats for ReportHash(...)
    enum
    {
        REPORT_HEX = 0,
        REPORT_DIGIT = 1
    };
#endif

    // Constructor and destructor
    CSHA1();
    ~CSHA1();

    UINT_32 m_state[5];
    UINT_32 m_count[2];
    UINT_32 m_reserved1[1]; // Memory alignment padding
    UINT_8 m_buffer[64];
    UINT_8 m_digest[20];
    UINT_32 m_reserved2[3]; // Memory alignment padding

    void Reset();

    // Update the hash value
    void Update(const UINT_8* pData, UINT_32 uLen);
#ifdef SHA1_UTILITY_FUNCTIONS
    bool HashFile(const char* szFileName);
#endif

    // Finalize hash and report
    void Final();

    // Report functions: as pre-formatted and raw data
#ifdef SHA1_UTILITY_FUNCTIONS
    void ReportHash(char* szReport, unsigned char uReportType = REPORT_HEX) const;
#endif
    void GetHash(UINT_8* puDest) const;

private:
    // Private SHA-1 transformation
    void Transform(UINT_32* pState, const UINT_8* pBuffer);

    // Member variables
    UINT_8 m_workspace[64];
    SHA1_WORKSPACE_BLOCK* m_block; // SHA1 pointer to the byte array above
};

#endif
  • sha1.cpp
/*
    100% free public domain implementation of the SHA-1 algorithm
    by Dominik Reichl <dominik.reichl@t-online.de>
    Web: http://www.dominik-reichl.de/

    Version 1.7 - 2006-12-21
    - Fixed buffer underrun warning which appeared when compiling with
      Borland C Builder (thanks to Rex Bloom and Tim Gallagher for the
      patch)
    - Breaking change: ReportHash writes the final hash to the start
      of the buffer, i.e. it's not appending it to the string any more
    - Made some function parameters const
    - Added Visual Studio 2005 project files to demo project

    Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
    - You can set the endianness in your files, no need to modify the
      header file of the CSHA1 class any more
    - Aligned data support
    - Made support/compilation of the utility functions (ReportHash
      and HashFile) optional (useful when bytes count, for example in
      embedded environments)

    Version 1.5 - 2005-01-01
    - 64-bit compiler compatibility added
    - Made variable wiping optional (define SHA1_WIPE_VARIABLES)
    - Removed unnecessary variable initializations
    - ROL32 improvement for the Microsoft compiler (using _rotl)

    ======== Test Vectors (from FIPS PUB 180-1) ========

    SHA1("abc") =
        A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D

    SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
        84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1

    SHA1(A million repetitions of "a") =
        34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/

#include "SHA1.h"

#ifdef SHA1_UTILITY_FUNCTIONS
#define SHA1_MAX_FILE_BUFFER 8000
#endif

// Rotate x bits to the left
#ifndef ROL32
#ifdef _MSC_VER
#define ROL32(_val32, _nBits) _rotl(_val32, _nBits)
#else
#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>32-(_nBits))))
#endif
#endif

#ifdef SHA1_LITTLE_ENDIAN
#define SHABLK0(i) (m_block->l[i] = 
    (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF))
#else
#define SHABLK0(i) (m_block->l[i])
#endif

#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] 
    ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1))

// SHA-1 rounds
#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); }
#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); }
#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); }

CSHA1::CSHA1()
{
    m_block = (SHA1_WORKSPACE_BLOCK*)m_workspace;

    Reset();
}

CSHA1::~CSHA1()
{
    Reset();
}

void CSHA1::Reset()
{
    // SHA1 initialization constants
    m_state[0] = 0x67452301;
    m_state[1] = 0xEFCDAB89;
    m_state[2] = 0x98BADCFE;
    m_state[3] = 0x10325476;
    m_state[4] = 0xC3D2E1F0;

    m_count[0] = 0;
    m_count[1] = 0;
}

void CSHA1::Transform(UINT_32* pState, const UINT_8* pBuffer)
{
    UINT_32 a = pState[0], b = pState[1], c = pState[2], d = pState[3], e = pState[4];

    memcpy(m_block, pBuffer, 64);

    // 4 rounds of 20 operations each. Loop unrolled.
    _R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3);
    _R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7);
    _R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11);
    _R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15);
    _R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19);
    _R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23);
    _R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27);
    _R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31);
    _R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35);
    _R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39);
    _R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43);
    _R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47);
    _R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51);
    _R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55);
    _R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59);
    _R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63);
    _R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67);
    _R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71);
    _R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75);
    _R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79);

    // Add the working vars back into state
    pState[0] += a;
    pState[1] += b;
    pState[2] += c;
    pState[3] += d;
    pState[4] += e;

    // Wipe variables
#ifdef SHA1_WIPE_VARIABLES
    a = b = c = d = e = 0;
#endif
}

// Use this function to hash in binary data and strings
void CSHA1::Update(const UINT_8* pData, UINT_32 uLen)
{
    UINT_32 i, j;

    j = (m_count[0] >> 3) & 63;

    if((m_count[0] += (uLen << 3)) < (uLen << 3))
        m_count[1]++;

    m_count[1] += (uLen >> 29);

    if((j + uLen) > 63)
    {
        i = 64 - j;
        memcpy(&m_buffer[j], pData, i);
        Transform(m_state, m_buffer);

        for( ; (i + 63) < uLen; i += 64)
            Transform(m_state, &pData[i]);

        j = 0;
    }
    else i = 0;

    if((uLen - i) != 0)
        memcpy(&m_buffer[j], &pData[i], uLen - i);
}

#ifdef SHA1_UTILITY_FUNCTIONS
// Hash in file contents
bool CSHA1::HashFile(const char* szFileName)
{
    unsigned long ulFileSize, ulRest, ulBlocks;
    unsigned long i;
    UINT_8 uData[SHA1_MAX_FILE_BUFFER];
    FILE* fIn;

    if(szFileName == NULL) return false;

    fIn = fopen(szFileName, "rb");
    if(fIn == NULL) return false;

    fseek(fIn, 0, SEEK_END);
    ulFileSize = (unsigned long)ftell(fIn);
    fseek(fIn, 0, SEEK_SET);

    if(ulFileSize != 0)
    {
        ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER;
        ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER;
    }
    else
    {
        ulBlocks = 0;
        ulRest = 0;
    }

    for(i = 0; i < ulBlocks; i++)
    {
        fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn);
        Update((UINT_8*)uData, SHA1_MAX_FILE_BUFFER);
    }

    if(ulRest != 0)
    {
        fread(uData, 1, ulRest, fIn);
        Update((UINT_8*)uData, ulRest);
    }

    fclose(fIn); fIn = NULL;
    return true;
}
#endif

void CSHA1::Final()
{
    UINT_32 i;
    UINT_8 finalcount[8];

    for(i = 0; i < 8; i++)
        finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)]
            >> ((3 - (i & 3)) * 8) ) & 255); // Endian independent

    Update((UINT_8*)"200", 1);

    while ((m_count[0] & 504) != 448)
        Update((UINT_8*)"0", 1); // vor die 0 muss noch ein Backslash!

    Update(finalcount, 8); // Cause a SHA1Transform()

    for(i = 0; i < 20; i++)
        m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);

    // Wipe variables for security reasons
#ifdef SHA1_WIPE_VARIABLES
    memset(m_buffer, 0, 64);
    memset(m_state, 0, 20);
    memset(m_count, 0, 8);
    memset(finalcount, 0, 8);
    Transform(m_state, m_buffer);
#endif
}

#ifdef SHA1_UTILITY_FUNCTIONS
// Get the final hash as a pre-formatted string
void CSHA1::ReportHash(char* szReport, unsigned char uReportType) const
{
    unsigned char i;
    char szTemp[16];

    if(szReport == NULL) return;

    if(uReportType == REPORT_HEX)
    {
        sprintf(szTemp, "%02X", m_digest[0]);
        strcpy(szReport, szTemp);

        for(i = 1; i < 20; i++)
        {
            sprintf(szTemp, " %02X", m_digest[i]);
            strcat(szReport, szTemp);
        }
    }
    else if(uReportType == REPORT_DIGIT)
    {
        sprintf(szTemp, "%u", m_digest[0]);
        strcpy(szReport, szTemp);

        for(i = 1; i < 20; i++)
        {
            sprintf(szTemp, " %u", m_digest[i]);
            strcat(szReport, szTemp);
        }
    }
    else strcpy(szReport, "Error: Unknown report type!");
}
#endif

// Get the raw message digest
void CSHA1::GetHash(UINT_8* puDest) const
{
    memcpy(puDest, m_digest, 20);
}

Blowfish

  • Der folgende Quellcode ist eine BCB-Abwandlung des C++Blowfish Beispieles von Bruce Schneiers Seite (www.schneier.com)
  • Zu beachten: Die Länge des Inputs muss immer ein Vielfaches von 8 sein (64 Bit)!
  • Im Beispiel werden 3 TLabeledEdit (Key, Input, Output) und 2 Buttons (Encrypt, Decrypt) verwendet.
  • Verwendung:
#include "blowfish.h"

...

void __fastcall TForm1::btnEncClick(TObject *Sender)
{
    char Key[MAX_PASSWD];
    char Input[MAX_STRING];

    memset(Key, 0, MAX_PASSWD);
    memset(Input, 0, MAX_STRING);

    Blowfish Blow;

    strcpy(Key, ledKey->Text.c_str()); // Key aus Labeled Edit kopieren
    strcpy(Input, ledInput->Text.c_str()); // Input-String aus Labeled Edit kopieren

    Blow.Set_Passwd(Key); // zuerst Passwort setzen

    // String encrypten
    if (Blow.Encrypt(Input, ledInput->Text.Length())) ledOutput->Text = Input; // codierten String ausgeben
    else ledOutput->Text = "Crypt error."
}

void __fastcall TForm1::btnDecClick(TObject *Sender)
{
    char Key[MAX_PASSWD];
    char Input[MAX_STRING];

    memset(Key, 0, MAX_PASSWD);
    memset(Input, 0, MAX_STRING);

    Blowfish Blow;

    strcpy(Key, ledKey->Text.c_str()); // Key aus Labeled Edit kopieren
    strcpy(Input, ledOutput->Text.c_str()); // Input-String aus Labeled Edit kopieren

    Blow.Set_Passwd(Key); // zuerst Passwort setzen

    // String decrypten
    if (Blow.Decrypt(Input, ledOutput->Text.Length())) ledInput->Text = Input; // decodierten String ausgeben
    else ledInput->Text = "Decrypt error.";
}
  • blowfish.h
#ifndef ___BLOWFISH_H___
#define ___BLOWFISH_H___

#define NUM_SUBKEYS 18
#define NUM_S_BOXES 4
#define NUM_ENTRIES 256

#define MAX_STRING 256
#define MAX_PASSWD 56 // 448bits

struct WordByte
{
    unsigned int three:8;
    unsigned int two:8;
    unsigned int one:8;
    unsigned int zero:8;
};

union Word_blf
{
    unsigned int word;
    WordByte byte;
};

struct DWord_blf
{
    Word_blf word0;
    Word_blf word1;
};

class Blowfish
{
    private:

    unsigned int PA[NUM_SUBKEYS];
    unsigned int SB[NUM_S_BOXES][NUM_ENTRIES];

    void Gen_Subkeys(char *);
    inline void BF_En(Word_blf *, Word_blf *);
    inline void BF_De(Word_blf *, Word_blf *);

    public:

    Blowfish();
    ~Blowfish();

    void Reset();
    void Set_Passwd(char * = NULL);
    bool Encrypt(void *, unsigned int);
    bool Decrypt(void *, unsigned int);
};
#endif
  • blowfish.cpp
#include <iostream.h>
#include <string.h>
#include "blowfish.h"

#define F(x) (((SB[0][x.byte.zero] + SB[1][x.byte.one]) ^ SB[2][x.byte.two]) + SB[3][x.byte.three])

void Blowfish::Gen_Subkeys(char *Passwd)
{
    unsigned int i,j,len=strlen(Passwd);
    Word_blf Work, null0, null1;

    if (len > 0)
    {
        j = 0;

        for (i=0;i<NUM_SUBKEYS;i++)
        {
            Work.byte.zero = Passwd[(j++)%len];
            Work.byte.one = Passwd[(j++)%len];
            Work.byte.two = Passwd[(j++)%len];
            Work.byte.three = Passwd[(j++)%len];
            PA[i] ^= Work.word;
        }

        null0.word = null1.word = 0;

        for (i=0;i<NUM_SUBKEYS;i+=2)
        {
            BF_En(&null0,&null1);
            PA[i] = null0.word;
            PA[i+1] = null1.word;
        }

        for (j=0;j<NUM_S_BOXES;j++)
        {
            for (i=0;i<NUM_ENTRIES;i+=2)
            {
                BF_En(&null0,&null1);
                SB[j][i] = null0.word;
                SB[j][i+1] = null1.word;
            }
        }
    }

    Work.word = null0.word = null1.word = 0;
    Passwd = NULL;
    len = 0;
}

void Blowfish::BF_En(Word_blf *x1,Word_blf *x2)
{
    Word_blf w1=*x1,w2=*x2;

    w1.word ^= PA[0];
    w2.word ^= F(w1)^PA[1]; w1.word ^= F(w2)^PA[2];
    w2.word ^= F(w1)^PA[3]; w1.word ^= F(w2)^PA[4];
    w2.word ^= F(w1)^PA[5]; w1.word ^= F(w2)^PA[6];
    w2.word ^= F(w1)^PA[7]; w1.word ^= F(w2)^PA[8];
    w2.word ^= F(w1)^PA[9]; w1.word ^= F(w2)^PA[10];
    w2.word ^= F(w1)^PA[11]; w1.word ^= F(w2)^PA[12];
    w2.word ^= F(w1)^PA[13]; w1.word ^= F(w2)^PA[14];
    w2.word ^= F(w1)^PA[15]; w1.word ^= F(w2)^PA[16];
    w2.word ^= PA[17];

    *x1 = w2;
    *x2 = w1;
}

void Blowfish::BF_De(Word_blf *x1,Word_blf *x2)
{
    Word_blf w1=*x1,w2=*x2;

    w1.word ^= PA[17];
    w2.word ^= F(w1)^PA[16]; w1.word ^= F(w2)^PA[15];
    w2.word ^= F(w1)^PA[14]; w1.word ^= F(w2)^PA[13];
    w2.word ^= F(w1)^PA[12]; w1.word ^= F(w2)^PA[11];
    w2.word ^= F(w1)^PA[10]; w1.word ^= F(w2)^PA[9];
    w2.word ^= F(w1)^PA[8]; w1.word ^= F(w2)^PA[7];
    w2.word ^= F(w1)^PA[6]; w1.word ^= F(w2)^PA[5];
    w2.word ^= F(w1)^PA[4]; w1.word ^= F(w2)^PA[3];
    w2.word ^= F(w1)^PA[2]; w1.word ^= F(w2)^PA[1];
    w2.word ^= PA[0];

    *x1 = w2;
    *x2 = w1;
}

Blowfish::Blowfish()
{
    Reset();
}

Blowfish::~Blowfish()
{
    Reset();
}

void Blowfish::Reset()
{
    unsigned int i,j;

    unsigned int PA_Init[NUM_SUBKEYS] =
    {
        0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
        0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
        0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
        0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
        0x9216d5d9, 0x8979fb1b
    };

    unsigned int SB_Init[NUM_S_BOXES][NUM_ENTRIES] =
    {
        0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
        0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
        0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
        0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
        0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
        0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
        0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
        0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
        0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
        0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
        0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
        0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
        0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
        0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
        0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
        0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
        0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
        0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
        0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
        0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
        0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
        0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
        0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
        0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
        0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
        0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
        0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
        0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
        0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
        0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
        0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
        0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
        0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
        0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
        0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
        0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
        0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
        0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
        0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
        0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
        0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
        0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
        0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
        0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
        0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
        0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
        0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
        0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
        0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
        0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
        0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
        0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
        0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
        0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
        0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
        0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
        0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
        0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
        0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
        0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
        0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
        0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
        0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
        0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
        0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
        0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
        0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
        0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
        0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
        0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
        0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
        0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
        0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
        0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
        0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
        0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
        0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
        0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
        0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
        0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
        0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
        0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
        0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
        0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
        0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
        0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
        0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
        0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
        0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
        0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
        0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
        0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
        0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
        0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
        0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
        0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
        0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
        0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
        0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
        0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
        0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
        0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
        0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
        0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
        0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
        0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
        0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
        0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
        0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
        0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
        0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
        0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
        0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
        0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
        0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
        0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
        0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
        0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
        0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
        0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
        0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
        0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
        0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
        0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
        0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
        0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
        0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
        0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
        0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
        0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
        0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
        0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
        0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
        0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
        0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
        0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
        0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
        0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
        0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
        0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
        0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
        0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
        0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
        0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
        0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
        0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
        0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
        0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
        0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
        0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
        0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
        0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
        0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
        0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
        0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
        0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
        0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
        0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
        0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
        0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
        0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
        0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
        0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
        0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
        0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
        0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
        0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
        0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
        0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
        0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
        0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
        0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
        0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
        0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
        0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
        0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
        0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
        0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
        0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
        0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
        0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
        0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
        0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
        0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
        0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
        0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
        0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
        0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
        0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
        0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
        0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
        0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
        0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
        0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
        0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
        0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
        0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
        0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
        0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
        0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
        0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
        0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
        0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
        0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
        0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
        0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
        0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
        0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
        0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
        0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
        0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
        0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
        0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
        0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
        0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
        0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
        0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
        0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
        0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
        0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
        0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
        0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
        0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
        0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
        0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
        0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
        0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
        0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
        0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
        0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
        0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
        0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
        0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
        0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
        0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
        0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
        0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
        0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
        0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
        0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
        0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
        0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
        0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
        0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
        0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
        0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
        0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
        0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
        0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
        0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
        0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
        0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
        0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
        0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
        0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
        0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
    };

    for (i=0;i<NUM_SUBKEYS;i++)
    {
        PA[i] = PA_Init[i];
    }

    for (j=0;j<NUM_S_BOXES;j++)
    {
        for (i=0;i<NUM_ENTRIES;i++)
        {
            SB[j][i] = SB_Init[j][i];
        }
    }
}

void Blowfish::Set_Passwd(char *Passwd)
{
    Reset();

    if (strlen(Passwd) > 0) Gen_Subkeys(Passwd);

    Passwd = NULL;
}

bool Blowfish::Encrypt(void *Ptr, unsigned int N_Bytes)
{
    unsigned int i;
    DWord_blf *Work;

    if (N_Bytes%8) return false;

    N_Bytes /= 8;
    Work = (DWord_blf *)Ptr;

    for (i=0;i<N_Bytes;i++)
    {
        BF_En(&Work->word0, &Work->word1);
        Work++;
    }

    Work = NULL;

    return true;
}

bool Blowfish::Decrypt(void *Ptr,unsigned int N_Bytes)
{
    unsigned int i;
    DWord_blf *Work;

    if (N_Bytes%8) return false;

    N_Bytes /= 8;
    Work = (DWord_blf *)Ptr;

    for (i=0;i<N_Bytes;i++)
    {
        BF_De(&Work->word0, &Work->word1);
        Work++;
    }

    Work = NULL;

    return true;
}

MD5

  • Der folgende Quellcode ist eine BCB-Abwandlung des MD5 Message Digest Algorithm zum Codieren von Strings mittels MD5 Checksummen.
  • Verwendung:
#include "md5.h";

...

MD5Obj *pMD5 = new MD5Obj();

// MD5-Hash eines Strings
AnsiString sInput = "abc"; //MD5 Hash: 900150983cd24fb0d6963f7d28e17f72
AnsiString sTest = pMD5->MD5_CheckString(sInput);

// MD5-Hash einer Datei
int iFileSize;
int iFileHandle;
int iBytesRead;
char *pchTemp;
AnsiString sMD5Str = "";

iFileHandle = FileOpen(sInput.c_str(), fmShareDenyWrite);

if (iFileHandle)
{
  iFileSize = FileSeek(iFileHandle, 0, 2);
  FileSeek(iFileHandle, 0, 0);

  pchTemp = new char[iFileSize+1];

  iBytesRead = FileRead(iFileHandle, pchTemp, iFileSize);

  if (iBytesRead == iFileSize) sMD5Str = pMD5->MD5_CheckFile(pchTemp, iFileSize);

  delete[] pchTemp;

  FileClose(iFileHandle);
}

if (pMD5) delete pMD5;
  • md5.h
#ifndef MD5_H
#define MD5_H
#ifdef __alpha
typedef unsigned int uint32;
#else
typedef unsigned long uint32;
#endif

#include <vcl.h>

struct MD5Context
{
    uint32 buf[4];
    uint32 bits[2];
    unsigned char in[64];
};

class MD5Obj
{
    public:

    MD5Obj(){};
    void MD5Init(struct MD5Context *ctx);
    void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len);
    void MD5Final(unsigned char digest[16], struct MD5Context *ctx);
    void MD5Transform(uint32 buf[4], uint32 in[16]);
    AnsiString MD5_CheckString(AnsiString sInputString);
    AnsiString MD5_CheckFile(char *cpFileData, int iLength);
};

typedef struct MD5Context MD5_CTX;

#endif
  • md5.cpp
// A Borland C++ implementation of the RSA Data Security, Inc. MD5 Message Digest Algorithm, as defined in RFC 1321.

#include "stdio.h"
#include <string.h>
#include "md5.h"
#ifdef sgi
#define HIGHFIRST
#endif

#ifdef sun
#define HIGHFIRST
#endif

#ifndef HIGHFIRST 
#define byteReverse(buf, len)
#else

void byteReverse(unsigned char *buf, unsigned longs)
{
    uint32 t;

    do
    {
        t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | ((unsigned) buf[1] << 8 | buf[0]);

        *(uint32 *) buf = t;
        buf += 4;

    } while (--longs);
}

#endif

#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))

#define MD5STEP(f, w, x, y, z, data, s) ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
//---------------------------------------------------------------------------
void MD5Obj::MD5Init(struct MD5Context *ctx)
{
    ctx->buf[0] = 0x67452301;
    ctx->buf[1] = 0xefcdab89;
    ctx->buf[2] = 0x98badcfe;
    ctx->buf[3] = 0x10325476;
    ctx->bits[0] = 0;
    ctx->bits[1] = 0;
}
//---------------------------------------------------------------------------
void MD5Obj::MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len)
{
    uint32 t;
    t = ctx->bits[0];

    if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) ctx->bits[1]++;

    ctx->bits[1] += len >> 29;
    t = (t >> 3) & 0x3f;

    if (t)
    {
        unsigned char *p = (unsigned char *) ctx->in + t;
        t = 64 - t;

        if (len < t)
        {
            memcpy(p, buf, len);
            return;
        }

        memcpy(p, buf, t);
        byteReverse(ctx->in, 16);

        MD5Transform(ctx->buf,(uint32*)ctx->in);

        buf += t;
        len -= t;
    }

    while (len >= 64)
    {
        memcpy(ctx->in, buf, 64);
        byteReverse(ctx->in, 16);

        MD5Transform(ctx->buf, (uint32 *) ctx->in);

        buf += 64;

        len -= 64;
    }

    memcpy(ctx->in, buf, len);
}
//---------------------------------------------------------------------------
void MD5Obj::MD5Final(unsigned char digest[16], struct MD5Context *ctx)
{
    unsigned count;
    unsigned char *p;

    count = (ctx->bits[0] >> 3) & 0x3F;
    p = ctx->in + count;
    *p++ = 0x80;
    count = 64 - 1 - count;

    if (count < 8)
    {
        memset(p, 0, count);
        byteReverse(ctx->in, 16);

        MD5Transform(ctx->buf, (uint32 *) ctx->in);

        memset(ctx->in, 0, 56);
    }
    else
    {
        memset(p, 0, count - 8);
    }

    byteReverse(ctx->in, 14);

    ((uint32 *) ctx->in)[14] = ctx->bits[0];
    ((uint32 *) ctx->in)[15] = ctx->bits[1];


    MD5Transform(ctx->buf,(uint32 *) ctx->in);

    byteReverse((unsigned char *) ctx->buf, 4);

    memcpy(digest, ctx->buf, 16);
    memset(ctx, 0, sizeof(ctx));
}
//---------------------------------------------------------------------------
void MD5Obj::MD5Transform(uint32 buf[4], uint32 in[16])
{
    register uint32 a, b, c, d;
    a = buf[0];
    b = buf[1];
    c = buf[2];
    d = buf[3];

    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);

    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 
    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 
    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 
    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 
    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 
    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 
    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 
    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 
    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 
    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 
    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 
    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 
    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 
    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 

    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 
    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 
    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 
    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 
    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 
    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 
    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 
    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 
    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 
    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 
    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 
    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 
    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 
    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 
    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 
    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 

    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 
    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 
    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 
    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 
    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 
    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 
    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 
    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 
    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 
    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 
    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 
    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 
    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 
    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 
    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 
    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 

    buf[0] += a; 
    buf[1] += b; 
    buf[2] += c; 
    buf[3] += d;
}
//--------------------------------------------------------------------------- 
AnsiString MD5Obj::MD5_CheckString(AnsiString sInputString)
{
    struct MD5Context ctx;
    char *password = sInputString.c_str();
    unsigned char digest[16];

    MD5Init (&ctx);
    MD5Update (&ctx, password, strlen(password));
    MD5Final (digest, &ctx);
    char tmp[33];

    for (int s=0; s<16; s++) sprintf (&tmp[s+s], "%02x", digest[s]);

    AnsiString sRetStr = tmp;

    return sRetStr;
}
//---------------------------------------------------------------------------
AnsiString MD5Obj::MD5_CheckFile(char *cpFileData, int iLength)
{
    struct MD5Context ctx;
    unsigned char digest[16];

    MD5Init (&ctx);
    MD5Update (&ctx, cpFileData, iLength);
    MD5Final (digest, &ctx);
    char tmp[33];

    for (int s=0; s<16; s++) sprintf (&tmp[s+s], "%02x", digest[s]);

    AnsiString sRetStr = tmp;

    return sRetStr;
}

ROT 13

// Prinzip: Da das Alphabet 26 Buchstaben hat, kann durch einfache Rotation
// der Buchstaben um 13 Stellen ein Text unleserlich gemacht werden.
// Mit dem selben Algorithmus ist es dann auch wieder möglich,
// den so chiffrierten Text wieder zu dekodieren.
// Es werden hierbei nur die Buchstaben rotiert,
// keine Zahlen und Sonderzeichen.
void rot13(char *string)
{
    int len = strlen(string), x;

    for (x = 0; x <= len; x++)
    {
        if (((string[x] >= 65) && (string[x] <= 77)) || ((string[x] >= 97) && (string[x] <= 109)))
        {
            printf("%c", string[x]+13);
        }
        else if (((string[x] >= 78) && (string[x] <= 90)) || ((string[x] >= 110) && (string[x] <= 122)))
             {
                printf("%c", string[x]-13);
             }
             else printf("%c",string[x]);
    }
}