unit uSm4;
//Editor:ShenHong
//Date:2020-3-24
interface
{$define XYSSL_SM4_H}
const SM4_ENCRYPT=1;
SM4_DECRYPT=0;
//Expanded SM4 S-boxes /* Sbox table: 8bits input convert to 8 bits output*/
SboxTable : array [0..15] of array [0..15] of byte = (
($d6,$90,$e9,$fe,$cc,$e1,$3d,$b7,$16,$b6,$14,$c2,$28,$fb,$2c,$05),
($2b,$67,$9a,$76,$2a,$be,$04,$c3,$aa,$44,$13,$26,$49,$86,$06,$99),
($9c,$42,$50,$f4,$91,$ef,$98,$7a,$33,$54,$0b,$43,$ed,$cf,$ac,$62),
($e4,$b3,$1c,$a9,$c9,$08,$e8,$95,$80,$df,$94,$fa,$75,$8f,$3f,$a6),
($47,$07,$a7,$fc,$f3,$73,$17,$ba,$83,$59,$3c,$19,$e6,$85,$4f,$a8),
($68,$6b,$81,$b2,$71,$64,$da,$8b,$f8,$eb,$0f,$4b,$70,$56,$9d,$35),
($1e,$24,$0e,$5e,$63,$58,$d1,$a2,$25,$22,$7c,$3b,$01,$21,$78,$87),
($d4,$00,$46,$57,$9f,$d3,$27,$52,$4c,$36,$02,$e7,$a0,$c4,$c8,$9e),
($ea,$bf,$8a,$d2,$40,$c7,$38,$b5,$a3,$f7,$f2,$ce,$f9,$61,$15,$a1),
($e0,$ae,$5d,$a4,$9b,$34,$1a,$55,$ad,$93,$32,$30,$f5,$8c,$b1,$e3),
($1d,$f6,$e2,$2e,$82,$66,$ca,$60,$c0,$29,$23,$ab,$0d,$53,$4e,$6f),
($d5,$db,$37,$45,$de,$fd,$8e,$2f,$03,$ff,$6a,$72,$6d,$6c,$5b,$51),
($8d,$1b,$af,$92,$bb,$dd,$bc,$7f,$11,$d9,$5c,$41,$1f,$10,$5a,$d8),
($0a,$c1,$31,$88,$a5,$cd,$7b,$bd,$2d,$74,$d0,$12,$b8,$e5,$b4,$b0),
($89,$69,$97,$4a,$0c,$96,$77,$7e,$65,$b9,$f1,$09,$c5,$6e,$c6,$84),
($18,$f0,$7d,$ec,$3a,$dc,$4d,$20,$79,$ee,$5f,$3e,$d7,$cb,$39,$48));
//* System parameter */
FK:array [0..3] of Cardinal = ($a3b1bac6,$56aa3350,$677d9197,$b27022dc);
//* fixed parameter */
CK:array [0..31] of Cardinal= (
$00070e15,$1c232a31,$383f464d,$545b6269,$70777e85,$8c939aa1,$a8afb6bd,$c4cbd2d9,
$e0e7eef5,$fc030a11,$181f262d,$343b4249,$50575e65,$6c737a81,$888f969d,$a4abb2b9,
$c0c7ced5,$dce3eaf1,$f8ff060d,$141b2229,$30373e45,$4c535a61,$686f767d,$848b9299,
$a0a7aeb5,$bcc3cad1,$d8dfe6ed,$f4fb0209,$10171e25,$2c333a41,$484f565d,$646b7279);
type
pTsm4_context = ^Tsm4_context; //SM4 context structure
Tsm4_context = packed record
mode:Integer; //*!< encrypt/decrypt */
sk:array [0..31] of Cardinal; //*!< SM4 subkeys */:
end;
procedure sm4_setkey_enc(ctx:pTsm4_context;key:array of byte); //SM4 key schedule (128-bit, encryption)
procedure sm4_setkey_dec(ctx:pTsm4_context;key:array of byte); //SM4 key schedule (128-bit, decryption)
procedure sm4_crypt_ecb(ctx:pTsm4_context;mode,length:Integer;input,output:PByte); //SM4-ECB block encryption/decryption
procedure sm4_crypt_cbc(ctx:pTsm4_context;mode,length:Integer;iv:array of Byte;input,output:PByte); //SM4-CBC buffer encryption/decryption
//procedure GET_ULONG_BE(var n:Cardinal;b:PByte;i:byte); //32-bit integer manipulation macros (big endian)
//procedure PUT_ULONG_BE(n:Cardinal;b:PByte;i:byte);
implementation
procedure iSWAP(var a,b:Cardinal);
var t: Cardinal;
begin
t:=a;
a:=b;
b:=t;
end;
procedure GET_ULONG_BE(var n:Cardinal;b:PByte;i:byte); //32-bit integer manipulation macros (big endian)
begin
n := (Cardinal((b+i)^ and $ff) shl 24)
or (Cardinal((b+i+1)^ and $ff) shl 16)
or (Cardinal((b+i+2)^ and $ff) shl 8)
or Cardinal((b+i+3)^ and $ff);
end;
procedure PUT_ULONG_BE(n:Cardinal;b:PByte;i:byte);
begin
(b+i)^ := byte((n shr 24) and $ff);
(b+i+1)^ := byte((n shr 16) and $ff);
(b+i+2)^ := byte((n shr 8) and $ff);
(b+i+3)^ := byte(n and $ff);
end;
function rotl(const Value: Cardinal; ShiftValue: Byte): Cardinal; //rotate shift left marco definition
begin
Result := (Value shr (8 * 32-ShiftValue)) or ((Value and $FFFFFFFF) Shl ShiftValue);
end;
function sm4Sbox(inch:Byte):Byte; //look up in SboxTable and get the related value.
var retVal:Byte; pTable :PByte;
begin
pTable := @SboxTable;
retVal := pTable[inch];
Result := retVal;
end;
function sm4Lt(ka:Cardinal):Cardinal; //"T algorithm" == "L algorithm" + "t algorithm". c is calculated with line algorithm "L" and nonline algorithm "t"
var bb,c:Cardinal; a,b:Array of Byte;
begin
bb := 0;
c := 0;
SetLength(a,4);
SetLength(b,4);
PUT_ULONG_BE(ka,@a[0],0);
b[0] := sm4Sbox(a[0]);
b[1] := sm4Sbox(a[1]);
b[2] := sm4Sbox(a[2]);
b[3] := sm4Sbox(a[3]);
GET_ULONG_BE(bb,@b[0],0);
c := bb xor (ROTL(bb, 2)) xor (ROTL(bb, 10)) xor (ROTL(bb, 18)) xor (ROTL(bb, 24));
Result := c;
end;
function sm4F(x0,x1,x2,x3,rk:Cardinal):Cardinal; //Calculating and getting encryption/decryption contents. rk: encryption/decryption key;
begin
Result := x0 xor sm4Lt(x1 xor x2 xor x3 xor rk);
end;
function sm4CalciRK(ka:Cardinal):Cardinal; //Calculating round encryption key.
var bb,rk:Cardinal; a,b:Array of Byte;
begin
bb := 0;
rk := 0;
SetLength(a,4);
SetLength(b,4);
PUT_ULONG_BE(ka,@a[0],0);
b[0] := sm4Sbox(a[0]);
b[1] := sm4Sbox(a[1]);
b[2] := sm4Sbox(a[2]);
b[3] := sm4Sbox(a[3]);
GET_ULONG_BE(bb,@b[0],0);
rk := bb xor (ROTL(bb, 13)) xor (ROTL(bb, 23));
Result := rk;
end;
procedure sm4_setkey(var SK :array of Cardinal; key :array of byte);
var i:Cardinal; MK,k:Array of Cardinal;
begin
SetLength(MK,4);
SetLength(k,36);
i := 0;
GET_ULONG_BE( MK[0], @key[0], 0 );
GET_ULONG_BE( MK[1], @key[0], 4 );
GET_ULONG_BE( MK[2], @key[0], 8 );
GET_ULONG_BE( MK[3], @key[0], 12 );
k[0] := MK[0] xor FK[0];
k[1] := MK[1] xor FK[1];
k[2] := MK[2] xor FK[2];
k[3] := MK[3] xor FK[3];
for i:= 0 to 31 do
begin
k[i+4] := k[i] xor (sm4CalciRK(k[i+1] xor k[i+2] xor k[i+3] xor CK[i]));
SK[i] := k[i+4];
end;
end;
procedure sm4_one_round( sk:array of Cardinal;input,output:PByte); //SM4 standard one round processing
var i:Cardinal; ulbuf:Array of Cardinal;
begin
i := 0;
SetLength(ulbuf,36);
fillchar(ulbuf[0], sizeof(ulbuf),0);
GET_ULONG_BE( ulbuf[0], input, 0 );
GET_ULONG_BE( ulbuf[1], input, 4 );
GET_ULONG_BE( ulbuf[2], input, 8 );
GET_ULONG_BE( ulbuf[3], input, 12 );
for i:= 0 to 31 do
begin
ulbuf[i+4] := sm4F(ulbuf[i], ulbuf[i+1], ulbuf[i+2], ulbuf[i+3], sk[i]);
end;
PUT_ULONG_BE(ulbuf[35],output,0);
PUT_ULONG_BE(ulbuf[34],output,4);
PUT_ULONG_BE(ulbuf[33],output,8);
PUT_ULONG_BE(ulbuf[32],output,12);
end;
procedure sm4_setkey_enc(ctx:pTsm4_context;key:array of byte); //SM4 key schedule (128-bit, encryption)
begin
ctx.mode := SM4_ENCRYPT;
sm4_setkey( ctx.sk, key );
end;
procedure sm4_setkey_dec(ctx:pTsm4_context;key:array of byte); //SM4 key schedule (128-bit, decryption)
var i:Integer;
begin
ctx.mode := SM4_ENCRYPT;
sm4_setkey( ctx.sk, key );
for i := 0 to 15 do
begin
iSWAP( ctx.sk[ i ], ctx.sk[31-i] );
end;
end;
procedure sm4_crypt_ecb(ctx:pTsm4_context;mode,length:Integer;input,output:PByte); //SM4-ECB block encryption/decryption
begin
while( length > 0 ) do
begin
sm4_one_round( ctx.sk, input, output );
Inc(input,16);
Inc(output,16);
Dec(length,16);
end;
end;
procedure sm4_crypt_cbc(ctx:pTsm4_context;mode,length:Integer;iv:array of Byte;input,output:PByte); //SM4-CBC buffer encryption/decryption
var i:Integer;temp :array of Byte;
begin
SetLength(temp,36);
if( mode = SM4_ENCRYPT) then
begin
while( length > 0 ) do
begin
for i := 0 to 15 do
output[i] := byte( input[i] xor iv[i]);
sm4_one_round( ctx.sk, output, output );
Move(output^,iv,16);
Inc(input,16);
Inc(output,16);
Dec(length,16);
end;
end
else //* SM4_DECRYPT */
begin
while( length > 0 ) do
begin
Move(input^,temp,16);
sm4_one_round( ctx.sk, input, output );
for i := 0 to 15 do
output[i] := byte( output[i] xor iv[i] );
Move(temp,iv,16);
Inc(input,16);
Inc(output,16);
Dec(length,16);
end;
end;
end;
end.
国密SM4加解密算法-DELPHI原码
5星 · 超过95%的资源 需积分: 50 72 浏览量
2020-03-24
15:49:17
上传
评论
收藏 4KB RAR 举报
jimmyesh
- 粉丝: 0
- 资源: 4
最新资源
- 课程设计-基于SpringBoot + Mybatis+python爬虫NBA球员数据爬取可视化+源代码+文档+sql+效果图
- 软件品质管理系列二项目策划规范.doc
- 基于TensorFlow+PyQt+GUI的酒店评论情感分析,支持分析本地数据文件和网络爬取数据分析+源代码+文档说明+安装教程
- 软件定义无线电中的模拟电路测试技术.pptx
- 软件开发协议(作为技术开发合同附件).doc
- 软件开发和咨询行业技术趋势分析.pptx
- 软件测试题详解及答案.doc
- 软件漏洞生命周期管理策略.pptx
- 毕业设计-基于Python实现的的简易气温爬虫,可以爬取全国各市的近7日气温数据
- 软件系统测试报告(实用版).doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈