Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file kuznechik.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200(* Utils and types *)open!Coreletgf_mul(a:int)(b:int)=Bigarray.Array1.unsafe_getGf_mul_table.gf_mul_table((a*256)+b)(* X Transition *)letx_trans(a:intarray)(b:intarray):intarray=Array.map2_exnab~f:(funa_elb_el->a_ellxorb_el)(* S Transition and Inverse S Transition*)letpi_table:intarray=[|0xFC;0xEE;0xDD;0x11;0xCF;0x6E;0x31;0x16;0xFB;0xC4;0xFA;0xDA;0x23;0xC5;0x04;0x4D;0xE9;0x77;0xF0;0xDB;0x93;0x2E;0x99;0xBA;0x17;0x36;0xF1;0xBB;0x14;0xCD;0x5F;0xC1;0xF9;0x18;0x65;0x5A;0xE2;0x5C;0xEF;0x21;0x81;0x1C;0x3C;0x42;0x8B;0x01;0x8E;0x4F;0x05;0x84;0x02;0xAE;0xE3;0x6A;0x8F;0xA0;0x06;0x0B;0xED;0x98;0x7F;0xD4;0xD3;0x1F;0xEB;0x34;0x2C;0x51;0xEA;0xC8;0x48;0xAB;0xF2;0x2A;0x68;0xA2;0xFD;0x3A;0xCE;0xCC;0xB5;0x70;0x0E;0x56;0x08;0x0C;0x76;0x12;0xBF;0x72;0x13;0x47;0x9C;0xB7;0x5D;0x87;0x15;0xA1;0x96;0x29;0x10;0x7B;0x9A;0xC7;0xF3;0x91;0x78;0x6F;0x9D;0x9E;0xB2;0xB1;0x32;0x75;0x19;0x3D;0xFF;0x35;0x8A;0x7E;0x6D;0x54;0xC6;0x80;0xC3;0xBD;0x0D;0x57;0xDF;0xF5;0x24;0xA9;0x3E;0xA8;0x43;0xC9;0xD7;0x79;0xD6;0xF6;0x7C;0x22;0xB9;0x03;0xE0;0x0F;0xEC;0xDE;0x7A;0x94;0xB0;0xBC;0xDC;0xE8;0x28;0x50;0x4E;0x33;0x0A;0x4A;0xA7;0x97;0x60;0x73;0x1E;0x00;0x62;0x44;0x1A;0xB8;0x38;0x82;0x64;0x9F;0x26;0x41;0xAD;0x45;0x46;0x92;0x27;0x5E;0x55;0x2F;0x8C;0xA3;0xA5;0x7D;0x69;0xD5;0x95;0x3B;0x07;0x58;0xB3;0x40;0x86;0xAC;0x1D;0xF7;0x30;0x37;0x6B;0xE4;0x88;0xD9;0xE7;0x89;0xE1;0x1B;0x83;0x49;0x4C;0x3F;0xF8;0xFE;0x8D;0x53;0xAA;0x90;0xCA;0xD8;0x85;0x61;0x20;0x71;0x67;0xA4;0x2D;0x2B;0x09;0x5B;0xCB;0x9B;0x25;0xD0;0xBE;0xE5;0x6C;0x52;0x59;0xA6;0x74;0xD2;0xE6;0xF4;0xB4;0xC0;0xD1;0x66;0xAF;0xC2;0x39;0x4B;0x63;0xB6|][@@ocamlformat"disable"]letpi_inv_table:intarray=[|0xA5;0x2D;0x32;0x8F;0x0E;0x30;0x38;0xC0;0x54;0xE6;0x9E;0x39;0x55;0x7E;0x52;0x91;0x64;0x03;0x57;0x5A;0x1C;0x60;0x07;0x18;0x21;0x72;0xA8;0xD1;0x29;0xC6;0xA4;0x3F;0xE0;0x27;0x8D;0x0C;0x82;0xEA;0xAE;0xB4;0x9A;0x63;0x49;0xE5;0x42;0xE4;0x15;0xB7;0xC8;0x06;0x70;0x9D;0x41;0x75;0x19;0xC9;0xAA;0xFC;0x4D;0xBF;0x2A;0x73;0x84;0xD5;0xC3;0xAF;0x2B;0x86;0xA7;0xB1;0xB2;0x5B;0x46;0xD3;0x9F;0xFD;0xD4;0x0F;0x9C;0x2F;0x9B;0x43;0xEF;0xD9;0x79;0xB6;0x53;0x7F;0xC1;0xF0;0x23;0xE7;0x25;0x5E;0xB5;0x1E;0xA2;0xDF;0xA6;0xFE;0xAC;0x22;0xF9;0xE2;0x4A;0xBC;0x35;0xCA;0xEE;0x78;0x05;0x6B;0x51;0xE1;0x59;0xA3;0xF2;0x71;0x56;0x11;0x6A;0x89;0x94;0x65;0x8C;0xBB;0x77;0x3C;0x7B;0x28;0xAB;0xD2;0x31;0xDE;0xC4;0x5F;0xCC;0xCF;0x76;0x2C;0xB8;0xD8;0x2E;0x36;0xDB;0x69;0xB3;0x14;0x95;0xBE;0x62;0xA1;0x3B;0x16;0x66;0xE9;0x5C;0x6C;0x6D;0xAD;0x37;0x61;0x4B;0xB9;0xE3;0xBA;0xF1;0xA0;0x85;0x83;0xDA;0x47;0xC5;0xB0;0x33;0xFA;0x96;0x6F;0x6E;0xC2;0xF6;0x50;0xFF;0x5D;0xA9;0x8E;0x17;0x1B;0x97;0x7D;0xEC;0x58;0xF7;0x1F;0xFB;0x7C;0x09;0x0D;0x7A;0x67;0x45;0x87;0xDC;0xE8;0x4F;0x1D;0x4E;0x04;0xEB;0xF8;0xF3;0x3E;0x3D;0xBD;0x8A;0x88;0xDD;0xCD;0x0B;0x13;0x98;0x02;0x93;0x80;0x90;0xD0;0x24;0x34;0xCB;0xED;0xF4;0xCE;0x99;0x10;0x44;0x40;0x92;0x3A;0x01;0x26;0x12;0x1A;0x48;0x68;0xF5;0x81;0x8B;0xC7;0xD6;0x20;0x0A;0x08;0x00;0x4C;0xD7;0x74|][@@ocamlformat"disable"]lets_generic_trans(l:intarray)(a:intarray):intarray=a|>Array.map~f:(funx->Array.unsafe_getlx)lets_trans:intarray->intarray=s_generic_transpi_tablelets_inv_trans:intarray->intarray=s_generic_transpi_inv_table(* L Transition and Inverse L Transition*)letl_vec:intarray=[|148;32;133;16;194;192;1;251;1;192;194;16;133;32;148;1|]letr_trans(a:intarray):intarray=letnew_val=matchArray.folda~init:(0,0)~f:(fun(v,i)c->(gf_mulc(Array.unsafe_getl_veci)lxorv,i+1))with|v,_->vinArray.unsafe_blit~src:a~src_pos:0~dst:a~dst_pos:1~len:15;Array.unsafe_seta0new_val;aletr_inv_trans(a:intarray):intarray=letnew_val=matchArray.fold(Array.suba~pos:1~len:15)~init:(Array.unsafe_geta0,0)~f:(fun(v,i)c->(gf_mulc(Array.unsafe_getl_veci)lxorv,i+1))with|v,_->vinArray.unsafe_blit~src:a~src_pos:1~dst:a~dst_pos:0~len:15;Array.unsafe_seta15new_val;aletrec_l_generic_trans_inner(f:intarray->intarray)(a:intarray)(i:int):intarray=matchiwith0->a|_->_l_generic_trans_innerf(fa)(i-1)letl_generic_trans(f:intarray->intarray)(a:intarray):intarray=_l_generic_trans_innerfa16letl_trans:intarray->intarray=l_generic_transr_transletl_inv_trans:intarray->intarray=l_generic_transr_inv_trans(* Round constants computation *)letround_constants:intarrayarray=Array.sub~pos:1~len:32(Array.init33~f:(funi->Array.append(Array.create~len:150)(Array.create~len:1i)|>l_trans))(* Key extension *)letf_trans(k1:intarray)(k2:intarray)(iter_const:intarray):intarray*intarray=(k1|>x_transiter_const|>s_trans|>l_trans|>x_transk2,k1)letmake_iter_keys(k1:intarray)(k2:intarray)(round_const:intarrayarray):intarrayarray=Sequence.take(Sequence.append(Sequence.singleton((k1,k2),0))(Sequence.unfold~init:((k1,k2),0)~f:(fun((ik1,ik2),i)->letnew_val=(f_transik1ik2(Array.getround_consti),i+1)inOption.some(new_val,new_val)))|>Sequence.filter~f:(fun(_,i)->imod8=0))5|>Sequence.map~f:(fun((ik1,ik2),_)->[ik1;ik2])|>Sequence.to_list|>List.concat|>Array.of_list(* Encrypt and Decrypt *)moduleCipher=structtypet={key:intarray;ik:intarrayarray}letmake(key:intarray):t={key;ik=make_iter_keys(Array.subkey~pos:0~len:16)(Array.subkey~pos:16~len:16)round_constants}letrec_encrypt_block_inner(ik:intarrayarray)(x:intarray)(i:int):intarray=matchiwith|9->x|_->_encrypt_block_innerik(x|>x_transik.(i)|>s_trans|>l_trans)(i+1)letencrypt_block(cipher:t)(msg:intarray):intarray=_encrypt_block_innercipher.ikmsg0|>x_transcipher.ik.(9)letrec_decrypt_block_inner(ik:intarrayarray)(x:intarray)(i:int):intarray=matchiwith|9->x|_->_decrypt_block_innerik(x|>l_inv_trans|>s_inv_trans|>x_transik.(8-i))(i+1)letdecrypt_block(cipher:t)(msg:intarray):intarray=_decrypt_block_innercipher.ik(msg|>x_transcipher.ik.(9))0end