123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449(**************************************************************************)(* *)(* Copyright 2016-2018 OCamlPro *)(* *)(* All rights reserved. This file is distributed under the terms of the *)(* GNU Lesser General Public License version 2.1, with the special *)(* exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)moduletypeConvSig=sigtypetvalbytes:intvaltoggle_big_endian:t->tendmoduletypeBufSig=sigmoduleConv:ConvSigtypetvalunsafe_get:t->int->Conv.tvalunsafe_set:t->int->Conv.t->unitendmoduletypeInputSig=sigtypesrctypettypechunktypeeltvalinit:blocksize:int->src->tvalclose:t->unitvalbyte_size:t->int(** padded with 0, getting chunks after the end of input is allowed *)valget_chunk:t->int->chunkvalget:chunk->int->elt(** only allowed after the end of input *)valset:chunk->int->elt->unit(** only allowed after the end of input*)valset_byte:chunk->int->char->unitendmoduleConv32=structtypet=int32letbytes=4externalswap:t->t="%bswap_int32"lettoggle_big_endian=ifSys.big_endianthenfunx->xelseswapendmoduleConv64=structtypet=int64letbytes=8externalswap:t->t="%bswap_int64"lettoggle_big_endian=ifSys.big_endianthenfunx->xelseswapendmoduleB=BigarraymoduleA=B.Array1typebigstring=(char,B.int8_unsigned_elt,B.c_layout)A.tmoduleBuf_Bigstring32=structmoduleConv=Conv32typet=bigstringexternalunsafe_get:t->int->Conv.t="%caml_bigstring_get32u"externalunsafe_set:t->int->Conv.t->unit="%caml_bigstring_set32u"endmoduleBuf_Bigstring64=structmoduleConv=Conv64typet=bigstringexternalunsafe_get:t->int->Conv.t="%caml_bigstring_get64u"externalunsafe_set:t->int->Conv.t->unit="%caml_bigstring_set64u"endmoduleBuf_String32=structmoduleConv=Conv32typet=Bytes.texternalunsafe_get:t->int->Conv.t="%caml_string_get32u"externalunsafe_set:t->int->Conv.t->unit="%caml_string_set32u"endmoduleBuf_String64=structmoduleConv=Conv64typet=Bytes.texternalunsafe_get:t->int->Conv.t="%caml_string_get64u"externalunsafe_set:t->int->Conv.t->unit="%caml_string_set64u"endmoduleInput_file(Buf:BufSigwithtypet=bigstring)=structtypesrc=string(* filename *)typet={fd:Unix.file_descr;blocksize:int;buf:Buf.t;}typechunk=Buf.ttypeelt=Buf.Conv.tletinit~blocksizesrc=letfd=Unix.openfilesrc[Unix.O_RDONLY]0inletbuf=B.(array1_of_genarray(OpamCompat.Unix.map_filefdB.charc_layoutfalse[|-1|]))in{fd;blocksize;buf}letclose{fd;_}=Unix.closefdletbyte_size{buf;_}=A.dimbufletget_chunk{blocksize;buf;_}i=letlen=A.dimbufinletblock_bytes=blocksize*Buf.Conv.bytesinif(i+1)*block_bytes<=lenthenA.subbuf(i*block_bytes)(block_bytes)elseletba=A.createB.charB.c_layout(block_bytes)inA.fillba'\x00';ifi*block_bytes<lenthenA.blit(A.subbuf(i*block_bytes)(lenmodblock_bytes))(A.subba0(lenmodblock_bytes));baletgetchunki=Buf.Conv.toggle_big_endian(Buf.unsafe_getchunk(i*Buf.Conv.bytes))letsetchunkix=Buf.unsafe_setchunk(i*Buf.Conv.bytes)(Buf.Conv.toggle_big_endianx)letset_bytechunkic=A.unsafe_setchunkicendmoduleInput_string(Buf:BufSigwithtypet=Bytes.t)=structtypesrc=Bytes.ttypet={blocksize:int;buf:Bytes.t;}typechunk={offset:int;b:Bytes.t;}typeelt=Buf.Conv.tletinit~blocksizebuf={blocksize;buf}letclose_=()letbyte_size{buf;_}=Bytes.lengthbufletget_chunk{blocksize;buf}i=letlen=Bytes.lengthbufinletblock_bytes=blocksize*Buf.Conv.bytesinif(i+1)*block_bytes<=lenthen{offset=i*block_bytes;b=buf}elseletb=Bytes.makeblock_bytes'\x00'inifi*block_bytes<lenthenBytes.blitbuf(i*block_bytes)b0(lenmodblock_bytes);{offset=0;b}letget{offset;b}i=Buf.Conv.toggle_big_endian(Buf.unsafe_getb(offset+i*Buf.Conv.bytes))letset{offset;b}ix=Buf.unsafe_setb(offset+i*Buf.Conv.bytes)(Buf.Conv.toggle_big_endianx)letset_byte{offset;b}ic=Bytes.unsafe_setb(offset+i)cendmoduleMake_SHA256(I:InputSigwithtypeelt=int32)=structopenInt32letk=[|0x428a2f98l;0x71374491l;0xb5c0fbcfl;0xe9b5dba5l;0x3956c25bl;0x59f111f1l;0x923f82a4l;0xab1c5ed5l;0xd807aa98l;0x12835b01l;0x243185bel;0x550c7dc3l;0x72be5d74l;0x80deb1fel;0x9bdc06a7l;0xc19bf174l;0xe49b69c1l;0xefbe4786l;0x0fc19dc6l;0x240ca1ccl;0x2de92c6fl;0x4a7484aal;0x5cb0a9dcl;0x76f988dal;0x983e5152l;0xa831c66dl;0xb00327c8l;0xbf597fc7l;0xc6e00bf3l;0xd5a79147l;0x06ca6351l;0x14292967l;0x27b70a85l;0x2e1b2138l;0x4d2c6dfcl;0x53380d13l;0x650a7354l;0x766a0abbl;0x81c2c92el;0x92722c85l;0xa2bfe8a1l;0xa81a664bl;0xc24b8b70l;0xc76c51a3l;0xd192e819l;0xd6990624l;0xf40e3585l;0x106aa070l;0x19a4c116l;0x1e376c08l;0x2748774cl;0x34b0bcb5l;0x391c0cb3l;0x4ed8aa4al;0x5b9cca4fl;0x682e6ff3l;0x748f82eel;0x78a5636fl;0x84c87814l;0x8cc70208l;0x90befffal;0xa4506cebl;0xbef9a3f7l;0xc67178f2l;|]letchxyz=logxor(logandxy)(logand(lognotx)z)letmajxyz=logxor(logandxy)(logxor(logandxz)(logandyz))letsum0x=logxor(logor(shift_right_logicalx2)(shift_leftx(32-2)))(logxor(logor(shift_right_logicalx13)(shift_leftx(32-13)))(logor(shift_right_logicalx22)(shift_leftx(32-22))))letsum1x=logxor(logor(shift_right_logicalx6)(shift_leftx(32-6)))(logxor(logor(shift_right_logicalx11)(shift_leftx(32-11)))(logor(shift_right_logicalx25)(shift_leftx(32-25))))letlsig0x=logxor(logor(shift_right_logicalx7)(shift_leftx(32-7)))(logxor(logor(shift_right_logicalx18)(shift_leftx(32-18)))(logor(shift_right_logicalx3)(shift_right_logicalx3)))letlsig1x=logxor(logor(shift_right_logicalx17)(shift_leftx(32-17)))(logxor(logor(shift_right_logicalx19)(shift_leftx(32-19)))(logor(shift_right_logicalx10)(shift_right_logicalx10)))letsha_init=(0x6a09e667l,0xbb67ae85l,0x3c6ef372l,0xa54ff53al,0x510e527fl,0x9b05688cl,0x1f83d9abl,0x5be0cd19l)lethash_block=letwarr=Array.make640linfunhhblock->fort=0to15dowarr.(t)<-I.getblocktdone;fort=16to63dowarr.(t)<-add(add(lsig1warr.(t-2))warr.(t-7))(add(lsig0warr.(t-15))warr.(t-16))done;letrecstirt(a,b,c,d,e,f,g,h)=ift>=64thenleta',b',c',d',e',f',g',h'=hhinaddaa',addbb',addcc',adddd',addee',addff',addgg',addhh'elselett1=add(addh(sum1e))(add(add(chefg)k.(t))warr.(t))inlett2=add(sum0a)(majabc)instir(t+1)(addt1t2,a,b,c,adddt1,e,f,g)instir0hhletblocksize=16lethashsrc=letbs=I.init~blocksizesrcinletnbytes=I.byte_sizebsinletblocks=nbytes/(blocksize*4)inletrem=nbytesmod(blocksize*4)inleth=refsha_initinfori=0toblocks-1doh:=hash_block!h(I.get_chunkbsi)done;letlastblock=I.get_chunkbsblocksinI.set_bytelastblockrem'\x80';letlastblock=ifrem<=55thenlastblockelse(h:=hash_block!hlastblock;I.get_chunkbs(blocks+1))inletbitsz=Int64.mul8L(Int64.of_intnbytes)inI.setlastblock14Int64.(to_int32(shift_right_logicalbitsz32));I.setlastblock15Int64.(to_int32(logand0xffffffffLbitsz));let(a,b,c,d,e,f,g,h)=hash_block!hlastblockinI.closebs;Printf.sprintf"%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx"abcdefghendmoduleMake_SHA512(I:InputSigwithtypeelt=int64)=structopenInt64letk=[|0x428a2f98d728ae22L;0x7137449123ef65cdL;0xb5c0fbcfec4d3b2fL;0xe9b5dba58189dbbcL;0x3956c25bf348b538L;0x59f111f1b605d019L;0x923f82a4af194f9bL;0xab1c5ed5da6d8118L;0xd807aa98a3030242L;0x12835b0145706fbeL;0x243185be4ee4b28cL;0x550c7dc3d5ffb4e2L;0x72be5d74f27b896fL;0x80deb1fe3b1696b1L;0x9bdc06a725c71235L;0xc19bf174cf692694L;0xe49b69c19ef14ad2L;0xefbe4786384f25e3L;0x0fc19dc68b8cd5b5L;0x240ca1cc77ac9c65L;0x2de92c6f592b0275L;0x4a7484aa6ea6e483L;0x5cb0a9dcbd41fbd4L;0x76f988da831153b5L;0x983e5152ee66dfabL;0xa831c66d2db43210L;0xb00327c898fb213fL;0xbf597fc7beef0ee4L;0xc6e00bf33da88fc2L;0xd5a79147930aa725L;0x06ca6351e003826fL;0x142929670a0e6e70L;0x27b70a8546d22ffcL;0x2e1b21385c26c926L;0x4d2c6dfc5ac42aedL;0x53380d139d95b3dfL;0x650a73548baf63deL;0x766a0abb3c77b2a8L;0x81c2c92e47edaee6L;0x92722c851482353bL;0xa2bfe8a14cf10364L;0xa81a664bbc423001L;0xc24b8b70d0f89791L;0xc76c51a30654be30L;0xd192e819d6ef5218L;0xd69906245565a910L;0xf40e35855771202aL;0x106aa07032bbd1b8L;0x19a4c116b8d2d0c8L;0x1e376c085141ab53L;0x2748774cdf8eeb99L;0x34b0bcb5e19b48a8L;0x391c0cb3c5c95a63L;0x4ed8aa4ae3418acbL;0x5b9cca4f7763e373L;0x682e6ff3d6b2b8a3L;0x748f82ee5defb2fcL;0x78a5636f43172f60L;0x84c87814a1f0ab72L;0x8cc702081a6439ecL;0x90befffa23631e28L;0xa4506cebde82bde9L;0xbef9a3f7b2c67915L;0xc67178f2e372532bL;0xca273eceea26619cL;0xd186b8c721c0c207L;0xeada7dd6cde0eb1eL;0xf57d4f7fee6ed178L;0x06f067aa72176fbaL;0x0a637dc5a2c898a6L;0x113f9804bef90daeL;0x1b710b35131c471bL;0x28db77f523047d84L;0x32caab7b40c72493L;0x3c9ebe0a15c9bebcL;0x431d67c49c100d4cL;0x4cc5d4becb3e42b6L;0x597f299cfc657e2aL;0x5fcb6fab3ad6faecL;0x6c44198c4a475817L;|]letrotatexn=logor(shift_right_logicalxn)(shift_leftx(64-n))letchxyz=logxor(logandxy)(logand(lognotx)z)letmajxyz=logxor(logandxy)(logxor(logandxz)(logandyz))letsum0x=logxor(rotatex28)(logxor(rotatex34)(rotatex39))letsum1x=logxor(rotatex14)(logxor(rotatex18)(rotatex41))letlsig0x=logxor(rotatex1)(logxor(rotatex8)(shift_right_logicalx7))letlsig1x=logxor(rotatex19)(logxor(rotatex61)(shift_right_logicalx6))letsha_init=(0x6a09e667f3bcc908L,0xbb67ae8584caa73bL,0x3c6ef372fe94f82bL,0xa54ff53a5f1d36f1L,0x510e527fade682d1L,0x9b05688c2b3e6c1fL,0x1f83d9abfb41bd6bL,0x5be0cd19137e2179L)lethash_block=letwarr=Array.make800Linfunhhblock->fort=0to15dowarr.(t)<-I.getblocktdone;fort=16to79dowarr.(t)<-add(add(lsig1warr.(t-2))warr.(t-7))(add(lsig0warr.(t-15))warr.(t-16))done;letrecstirt(a,b,c,d,e,f,g,h)=ift>=80thenleta',b',c',d',e',f',g',h'=hhinaddaa',addbb',addcc',adddd',addee',addff',addgg',addhh'elselett1=add(addh(sum1e))(add(add(chefg)k.(t))warr.(t))inlett2=add(sum0a)(majabc)instir(t+1)(addt1t2,a,b,c,adddt1,e,f,g)instir0hhletblocksize=16lethashsrc=letbs=I.init~blocksizesrcinletnbytes=I.byte_sizebsinletblocks=nbytes/(blocksize*8)inletrem=nbytesmod(blocksize*8)inleth=refsha_initinfori=0toblocks-1doh:=hash_block!h(I.get_chunkbsi)done;letlastblock=I.get_chunkbsblocksinI.set_bytelastblockrem'\x80';letlastblock=ifrem<=111thenlastblockelse(h:=hash_block!hlastblock;I.get_chunkbs(blocks+1))in(* We assume sz fits in 61 bits... *)letbitsz=Int64.mul8L(Int64.of_intnbytes)inI.setlastblock15bitsz;let(a,b,c,d,e,f,g,h)=hash_block!hlastblockinI.closebs;Printf.sprintf"%016Lx%016Lx%016Lx%016Lx%016Lx%016Lx%016Lx%016Lx"abcdefghendmoduleSHA256_file=Make_SHA256(Input_file(Buf_Bigstring32))moduleSHA512_file=Make_SHA512(Input_file(Buf_Bigstring64))moduleSHA256_string=Make_SHA256(Input_string(Buf_String32))moduleSHA512_string=Make_SHA512(Input_string(Buf_String64))letsha256_file=SHA256_file.hashletsha512_file=SHA512_file.hashlethash_file=function|`SHA256->sha256_file|`SHA512->sha512_fileletsha256_bytes=SHA256_string.hashletsha512_bytes=SHA512_string.hashlethash_bytes=function|`SHA256->sha256_bytes|`SHA512->sha512_bytesletsha256=sha256_fileletsha512=sha512_filelethash=hash_file