123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)(* Tezos Protocol Implementation - Random number generation *)typeseed=BofState_hash.ttypet=TofState_hash.ttypesequence=SofState_hash.ttypenonce=bytesletnonce_encoding=Data_encoding.Fixed.bytesConstants_repr.nonce_lengthletinitial_seed="Laissez-faire les proprietaires."letzero_bytes=Bytes.makeNonce_hash.size'\000'letstate_hash_encoding=letopenData_encodinginconvState_hash.to_bytesState_hash.of_bytes_exn(Fixed.bytesNonce_hash.size)letseed_encoding=letopenData_encodinginconv(fun(Bb)->b)(funb->Bb)state_hash_encodingletempty=B(State_hash.hash_string[initial_seed])letnonce(Bstate)nonce=B(State_hash.hash_bytes[State_hash.to_bytesstate;nonce])letinitialize_new(Bstate)append=T(State_hash.hash_bytes(State_hash.to_bytesstate::zero_bytes::append))letxor_higher_bitsib=lethigher=TzEndian.get_int32b0inletr=Int32.logxorhigheriinletres=Bytes.copybinTzEndian.set_int32res0r;resletsequence(Tstate)n=State_hash.to_bytesstate|>xor_higher_bitsn|>funb->S(State_hash.hash_bytes[b])lettake(Sstate)=letb=State_hash.to_bytesstateinleth=State_hash.hash_bytes[b]in(State_hash.to_bytesh,Sh)lettake_int32sbound=ifCompare.Int32.(bound<=0l)theninvalid_arg"Seed_repr.take_int32"(* FIXME *)elseletrecloops=let(bytes,s)=takesinletr=Int32.abs(TzEndian.get_int32bytes0)inletdrop_if_over=Int32.subInt32.max_int(Int32.remInt32.max_intbound)inifCompare.Int32.(r>=drop_if_over)thenloopselseletv=Int32.remrboundin(v,s)inloopstypeerror+=Unexpected_nonce_length(* `Permanent *)let()=register_error_kind`Permanent~id:"unexpected_nonce_length"~title:"Unexpected nonce length"~description:"Nonce length is incorrect."~pp:(funppf()->Format.fprintfppf"Nonce length is not %i bytes long as it should."Constants_repr.nonce_length)Data_encoding.empty(functionUnexpected_nonce_length->Some()|_->None)(fun()->Unexpected_nonce_length)letmake_noncenonce=ifCompare.Int.(Bytes.lengthnonce<>Constants_repr.nonce_length)thenerrorUnexpected_nonce_lengthelseoknoncelethashnonce=Nonce_hash.hash_bytes[nonce]letcheck_hashnoncehash=Compare.Int.(Bytes.lengthnonce=Constants_repr.nonce_length)&&Nonce_hash.equal(Nonce_hash.hash_bytes[nonce])hashletnonce_hash_key_part=Nonce_hash.to_pathletinitial_nonce_0=zero_bytesletinitial_nonce_hash_0=hashinitial_nonce_0letdeterministic_seedseed=nonceseedzero_bytesletinitial_seedsn=let[@coq_struct"i"]recloopaccelti=ifCompare.Int.(i=1)thenList.rev(elt::acc)elseloop(elt::acc)(deterministic_seedelt)(i-1)inloop[](B(State_hash.hash_bytes[]))n