123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Sha512.mli *)let(+:)=Int64.addlet(^:)=Int64.logxorlet(&:)=Int64.logandletrotr(x:int64)(n:int):int64=Int64.logor(Int64.shift_right_logicalxn)(Int64.shift_leftx(64-n))letk=[|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|](* a 1 bit, zeros, the length in bits on 128 (its high 64 bits zero
* here: messages under 2 exabytes) *)letpad(s:string):Bytes.t=letn=String.lengthsinlettotal=((n+16)/128*128)+128inletb=Bytes.maketotal'\000'inBytes.blit_strings0b0n;Bytes.setbn'\x80';letbits=Int64.mul(Int64.of_intn)8Linfori=0to7doBytes.setb(total-1-i)(Char.chr(Int64.to_int(Int64.logand(Int64.shift_right_logicalbits(8*i))0xffL)))done;bletword(b:Bytes.t)(i:int):int64=letr=ref0Linfork=0to7dor:=Int64.logor(Int64.shift_left!r8)(Int64.of_int(Char.code(Bytes.getb(i+k))))done;!rletcompress(h:int64array)(b:Bytes.t)(block:int):unit=letw=Array.make800Linfori=0to15dow.(i)<-wordb((block*128)+(i*8))done;fori=16to79dolets0=rotrw.(i-15)1^:rotrw.(i-15)8^:Int64.shift_right_logicalw.(i-15)7inlets1=rotrw.(i-2)19^:rotrw.(i-2)61^:Int64.shift_right_logicalw.(i-2)6inw.(i)<-w.(i-16)+:s0+:w.(i-7)+:s1done;leta=refh.(0)andb'=refh.(1)andc=refh.(2)andd=refh.(3)inlete=refh.(4)andf=refh.(5)andg=refh.(6)andhh=refh.(7)infori=0to79dolets1=rotr!e14^:rotr!e18^:rotr!e41inletch=(!e&:!f)^:(Int64.lognot!e&:!g)inlett1=!hh+:s1+:ch+:k.(i)+:w.(i)inlets0=rotr!a28^:rotr!a34^:rotr!a39inletmaj=(!a&:!b')^:(!a&:!c)^:(!b'&:!c)inhh:=!g;g:=!f;f:=!e;e:=!d+:t1;d:=!c;c:=!b';b':=!a;a:=t1+:s0+:majdone;List.iteri(funiv->h.(i)<-h.(i)+:v)[!a;!b';!c;!d;!e;!f;!g;!hh]letrun(h:int64array)(s:string)(bytes:int):string=letb=padsinforblock=0to(Bytes.lengthb/128)-1docompresshbblockdone;String.initbytes(funi->Char.chr(Int64.to_int(Int64.logand(Int64.shift_right_logicalh.(i/8)(56-(8*(imod8))))0xffL)))letdigest(s:string):string=run[|0x6a09e667f3bcc908L;0xbb67ae8584caa73bL;0x3c6ef372fe94f82bL;0xa54ff53a5f1d36f1L;0x510e527fade682d1L;0x9b05688c2b3e6c1fL;0x1f83d9abfb41bd6bL;0x5be0cd19137e2179L|]s64letdigest384(s:string):string=run[|0xcbbb9d5dc1059ed8L;0x629a292a367cd507L;0x9159015a3070dd17L;0x152fecd8f70e5939L;0x67332667ffc00b31L;0x8eb44a8768581511L;0xdb0c2e0d64f98fa7L;0x47b5481dbefa4fa4L|]s48