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

📄 smartea.h

📁 一款文件加密的小软件
💻 H
字号:
/***
 *    (c)Coryrights Reserved.
 *
 *    SmartEA.h
 *    - SEA(Smart Encryption Algorithm)的运算部件
 *
 *    superStar, 2004.2
 ***/

static int rounds[3] = {                   /* 加密轮数(分别对应3种密钥长度) */
    ROUNDMIN, ROUNDMED, ROUNDMAX
    };
static int keyLen[3] = {16, 24, 32};       /* 密钥长度,单位:字节 */

static BYTE logRuler[8] = {                /* 字节上关于每一比特位的逻辑尺 */
        0x80, 0x40, 0x20, 0x10,
        0x08, 0x04, 0x02, 0x01
    };

static int direction[16][2] = {            /* 转移控制方向增量 */
        {-1, 0},{-1,-1},{0, -1},{1,-1},
        { 2, 0},{ 2, 1},{2,  2},{1, 2},
        { 0, 2},{-1, 2},{-2, 2},{-2,1},
        {-2,-3},{-1,-3},{ 0,-3},{1,-3}
    };

/**
 *  BOOL AskKeys(KEYINFO *ck);
 *  - 选择密钥长度及输入用户密钥。
 *  - 如果输入密钥成功,则返回TRUE,
 *    否则返回FALSE。
 *  - 本函数中使用全局变量
 *    - keyInput(type: WINDOWHANDLE)
 *    - message(type: WINDOWHANDLE)
 *    - keyPanel(type: WINDOWHANDLE)
 *    - key128Item(type: WINDOWHANDLE)
 *    - key192Item(type: WINDOWHANDLE)
 *    - key256Item(type: WINDOWHANDLE)
 *    - keyLen(type: int[])
 *    - rounds(type: int[])
 **/

BOOL
AskKeys(KEYINFO *ck)
{
    int  i, retLen;
    WINDOWHANDLE *pPanel_Key[4];
    char *userKeyType[3] = {
        "key-16Bytes]",
        "key-24Bytes]",
        "key-32Bytes]"
        };
    BYTE ch;

ASKKEYSTART:
    pPanel_Key[0] = &keyPanel;
    pPanel_Key[1] = &key128Item;
    pPanel_Key[2] = &key192Item;
    pPanel_Key[3] = &key256Item;

    if (-1 == (i = Panel(pPanel_Key, 4)))      /* 密钥长度选择 */
    {
        return FALSE;
    }
    ck->keyType = i;
    ck->seedKey = (BYTE *)                     /* 为种子密钥申请空间 */
                  malloc(keyLen[ck->keyType]
                         * sizeof(BYTE));
    if (NULL == ck->seedKey)
    {
        strcpy(message.displayStr, "[!]\n\n  No enough memory for user key  \n");
        Message(&message);
        getch();
        FreeMessage(&message);
        return FALSE;
    }

    /* 输入用户密钥 */
    keyInput.retStrLen = keyLen[ck->keyType];
    if (ENCRYPT == ck->flag)
    {
        strcpy(keyInput.title, "[ENCRYPT: ");
    }
    else if (DECRYPT == ck->flag)
    {
        strcpy(keyInput.title, "[DECRYPT: ");
    }
    strcat(keyInput.title, userKeyType[i]);
    if (FALSE == Window(&keyInput))
    {
        FreeWindow(&keyInput);
        return FALSE;
    }
    retLen = keyInput.retStrLen;
    CopyTo(ck->seedKey, keyInput.retStr, retLen);
    FreeWindow(&keyInput);

    /* 如果没有输入任何密钥,则给出提示 */
    if (0 == retLen)
    {
        strcpy(message.displayStr, "[!]\n\n  Need to input user key  \n");
        Message(&message);
        getch();
        FreeMessage(&message);
        goto ASKKEYSTART;
    }
    /* 如果输入密钥的长度达到选定的长度 */
    else if (retLen == keyLen[ck->keyType])
    {
        return TRUE;
    }
    /* 如果实际输入的密钥长度不够,则余下部分交
     * 替填入已输入密钥各个字节循环移位后的值,
     * 以构造出达到选定长度的新密钥          */
    else if (retLen < keyLen[ck->keyType])
    {
        for (i=retLen;
             i<keyLen[ck->keyType];
             i++)
        {
            ch = ck->seedKey[i%retLen];
            ck->seedKey[i] = (ch >> i%8) | (ch << (8-i%8));
        }
        return TRUE;
    }
}

/**
 *  BOOL ExpandKeys(KEYINFO *ck);
 *  - 根据种子密钥(及用户密钥)扩展轮子密钥
 *  - 本函数中使用全局变量
 *    - message(type: WINDOWHANDLE)
 *    - keyLen(type: int[])
 *    - rounds(type: int[])
 **/

BOOL
ExpandKeys(KEYINFO *ck)
{
    int  i, j, t;
    BYTE bTmp[8], tmp;

    ck->childKey                       /* 为轮子密钥申请空间 */
        = (BYTE *) malloc(rounds[ck->keyType]
                          * 8 * sizeof(BYTE));
                                  
    if (NULL == ck->childKey)
    {
        strcpy(message.displayStr, "[!]\n\n  No enough memory for child key  \n");
        Message(&message);
        getch();
        FreeMessage(&message);
        return FALSE;
    }

    t = keyLen[ck->keyType]/8;         /* 扩展出轮子密钥 */
    for (i=0; i<t; i++)
    {
        for (j=0; j<8; j++)
        {
            ck->childKey[i*8+j] = ck->seedKey[i*8+j];
        }
    }

    for (i=t;
         i<rounds[ck->keyType];        /* 这里要求加密轮数至少大于t */
         i++)
    {
        for (j=0; j<8; j++)
        {
            bTmp[j] = ck->seedKey[(i%t)*8+j]
                      + ck->seedKey[((i+1)%t)*8+j];
        }
        Brown(bTmp);
        for (j=0; j<8; j++)
        {
            ck->childKey[i*8+j]
                = ck->seedKey[(i%t)*8+j]
                = bTmp[j];
        }
    }

    for (i=0; i<4; i++)                /* 扩展出白化子密钥 */
    {
        for (j=0; j<8; j++)
        {
            bTmp[j] = ck->seedKey[(i%t)*8+j]
                      + ck->seedKey[((i+1)%t)*8+j];
        }
        Brown(bTmp);
        for (j=0; j<8; j++)
        {
            if (i < 2)
            {
                ck->kw0[i*8+j]
                    = ck->seedKey[(i%t)*8+j]
                    = bTmp[j];
            }
            else if (i >= 2)
            {
                ck->kw1[(i-2)*8+j]
                    = ck->seedKey[(i%t)*8+j]
                    = bTmp[j];
            }
        }
    }

    if (ENCRYPT == ck->flag);         /* 判断是否要颠倒轮子密钥顺序 */
    else if (DECRYPT == ck->flag)
    {
        t = rounds[ck->keyType];      /* 颠倒轮子密钥 */
        for (i=0; i<t/2; i++)
        {
            for (j=0; j<8; j++)
            {
                tmp = ck->childKey[i*8+j];
                ck->childKey[i*8+j]
                   = ck->childKey[(t-1-i)*8+j];
                ck->childKey[(t-1-i)*8+j] = tmp;
            }
        }
        for (i=0; i<16; i++)          /* 颠倒白化子密钥 */
        {
            tmp = ck->kw0[i];
            ck->kw0[i] = ck->kw1[i];
            ck->kw1[i] = tmp;
        }
    }

    return TRUE;
}

/**  BOOL Key(KEYINFO *ck);
 *   - 输入用户密钥以及扩展出轮子密钥,白化子密钥
 *   - 如果成功返回TRUE,否则返回FALSE
 **/

BOOL
Key(KEYINFO *ck)
{
    /* 得到密钥 */
    if (FALSE == AskKeys(ck))
    {
        return FALSE;
    }
    /* 密钥扩展,得到轮子密钥 */
    if (FALSE == ExpandKeys(ck))
    {
        return FALSE;
    }

    return TRUE;
}

/**
 *   void FreeKey(KEYINFO *ck);
 *   - 释放密钥
 **/

void
FreeKey(KEYINFO *ck)
{
    if (NULL != ck->seedKey)
    {
        free(ck->seedKey);
        ck->seedKey = NULL;
    }
    if (NULL != ck->childKey)
    {
        free(ck->childKey);
        ck->childKey = NULL;
    }
}

/**
 * void Brown(BYTE* data);
 * - SmartEA 算法之Brown函数,该函数对8x8位
 *   矩阵作伪布朗运动,转移次数32次
 *  - 本函数中使用全局变量
 *    - logRuler(type: int[])
 *    - direction(type: int[])
 **/

void
Brown(BYTE* data)
{
    int curx, cury, curDir, i;

    /* 根据data(8字节)的头3位和
     * 尾3位确定跳转的初始位置 */
    curx = data[0] >> 5;
    cury = data[7] & 0x07;

    for (i=0; i<32; i++)                   /* 伪布朗运动(跳转次数32) */
    {
        data[curx] ^= logRuler[cury];      /* 对当前点的比特作取反操作 */

        curDir =                           /* 得到转移方向控制组的4比特值 */
           (i%2) ? (data[(i/2)%8] & 0x0f)
                 : (data[(i/2)%8] >> 4);

        /* 根据curDir的值查表得到x,y方向
         * 的增量,并计算出新位置的下标 */
        curx += direction[curDir][0];
        cury += direction[curDir][1];

        if (curx < 0 || curx > 7)          /* 如果越界,则在边界处进行反射 */
        { 
            curx = (curx + 8) % 8;
        }
        if (cury < 0 || cury > 7)
        { 
            cury = (cury + 8) % 8;
        }
    }
}

/**
 *  void Feistel(BYTE* data, KEYINFO *ck);
 *  - rounds[ck.keyType]轮Feistel网络加密(或解密)
 *  - 本函数中使用全局变量
 *    - rounds(type: int[])
 **/

void
Feistel(BYTE* data, KEYINFO *ck)
{
    int  rds, i;
    BYTE tmp, bTmp[8];

    for (rds=0; rds<rounds[ck->keyType]; rds++)
    {
        for (i=0; i<8; i++)                /* 明文与轮子密钥模256加 */
        {
            bTmp[i] = data[i+8]
                      + ck->childKey[rds*8+i];
        }

        Brown(bTmp);

        /* Feistel结构下的异或和交换操作,注
         * 意只交换除最后一轮外的其他轮    */
        if (rds < (rounds[ck->keyType]- 1))
        {
            for (i=0; i<8; i++ )           /* 交换左、右部分(非最后一轮) */
            {
                tmp = data[i+8];
                data[i+8] = bTmp[i] ^ data[i];
                data[i]   = tmp;
            }
        }
        else
        {
            for (i=0; i<8; i++ )
            {
                data[i] ^= bTmp[i];        /* Feistel网络的最后一轮不交换左、右部分 */
            }
        }
    }
}

/**
 *   void SEA(BYTE* data, KEYINFO *ck);
 *   - SEA算法主体函数
 **/

void
SEA(BYTE* data, KEYINFO *ck)
{
    int i;
    BYTE bTmp[8];

    /* 1. 初始白化,和kw0相异或 */
    for(i=0; i<16; i++)
    {
        data[i] ^= ck->kw0[i];
    }

    /* 2. 前向混合 */
    for(i=0; i<8; i++)              /* data左半部分和右半部分按字节加 */
    {
        bTmp[i] = data[i] + data[i + 8];
    }
    Brown(bTmp);

    /* 对data左半部分加上bTmp, 右半部分减去bTmp. 均按字节操作 */
    for(i=0; i<8; i++)
    {
        data[i]    += bTmp[i];     /* 左半部分加上bTmp */
	data[i + 8] = (data[i+8]>=bTmp[i]) ?		
                      (data[i+8]-bTmp[i]) : (256-(bTmp[i]-data[i+8]));
			           /* 右半部分减去bTmp */
	}
    Feistel(data, ck);

    /* 3. 后向混合 */
    for(i=0; i<8; i++)             /* data左半部分和右半部分按字节加 */
    {
        bTmp[i] = data[i] + data[i + 8];
    }
    Brown(bTmp);

    /* 对data左半部分减去bTmp, 右半部分加上bTmp. 均按字节操作 */
    for(i=0; i<8; i++)
    {
			           /* 左半部分减去bTmp */
	data[i]     = (data[i]>=bTmp[i]) ?		
                      (data[i]-bTmp[i]) : (256-(bTmp[i]-data[i]));

        data[i+8] += bTmp[i];      /* 右半部分加上bTmp */

	}

    /* 4. 末尾白化,和kw1相异或 */
    for(i=0; i<16; i++)
    {
        data[i] ^= ck->kw1[i];
    }
}

⌨️ 快捷键说明

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