123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163(*
* This ml file is an implementation of the Threefry algorithm as described in
*
* "Parallel Random Numbers: As Easy as 1, 2, 3,
* Salmon, Moraes, Dror & Shaw, SC11, Seattle, Washington, USA, 2011, ACM "
*
* using the implementation at (as of 2021)
* https://github.com/DEShawResearch/random123
*
* The original Threefry header file this is taken from is
* random123/include/Random123/threefry.h
* of that same project and carries the following notice:
*
* /*
* Copyright 2010-2011, D. E. Shaw Research.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of D. E. Shaw Research nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* */
*
* /** \cond HIDDEN_FROM_DOXYGEN */
* /* Significant parts of this file were copied from
* from:
* Skein_FinalRnd/ReferenceImplementation/skein.h
* Skein_FinalRnd/ReferenceImplementation/skein_block.c
*
* in http://csrc.nist.gov/groups/ST/hash/sha-3/Round3/documents/Skein_FinalRnd.zip
*
* This file has been modified so that it may no longer perform its originally
* intended function. If you're looking for a Skein or Threefish source code,
* please consult the original file.
*
* The original file had the following header:
* **************************************************************************
* **
* ** Interface declarations and internal definitions for Skein hashing.
* **
* ** Source code author: Doug Whiting, 2008.
* **
* ** This algorithm and source code is released to the public domain.
* **
* ***************************************************************************
*
* */
* *)openTypesletdefault_rounds=20letdefault_upper=Unsigned.UInt32.(shift_leftone30|>to_int)letdefault_upper_float=float_of_intdefault_uppermoduleMake(Num:NUM)(R:RNG_MAKERwithtypedigits=Num.digits):GEN=structmoduleRng=R.Make(Num)typet=(Num.digits,Num.word)Num.tarrayletof_int_arrayarr=if(Num.digits<>Array.lengtharr)thenraise@@Invalid_argument(Printf.sprintf"Need %d digit ctr/key"Num.digits)elseArray.mapNum.of_intarrletto_int_array=Array.mapNum.to_intletof_string_arrayarr=if(Num.digits<>Array.lengtharr)thenraise@@Invalid_argument(Printf.sprintf"Need %d digit ctr/key"Num.digits)elseArray.mapNum.of_stringarrletto_string_array=Array.mapNum.to_stringletrecctr~equaldigitopsentinalt=letn=Array.lengthtinifdigit==nthen()else(letd=opt.(digit)inmatch(equalsentinald)with|false->t.(digit)<-d;|true->t.(digit)<-d;ctr~equal(digit+1)opsentinalt)letsucct=ctr~equal:Num.equal0Num.succNum.zerot;tletpredt=ctr~equal:Num.equal0Num.predNum.max_intt;tletrand?(rounds=default_rounds)~key~ctr()=Rng.rand_R~of_int:Num.of_int~rounds~key~ctrletlimitn=Num.(submax_int(remmax_intn))letunbiased~key~ctrupperr=letu=Num.of_intupperintry(* find first rand less than limit
* and do the remainder with that number
* error if no number is found *)Array.to_listr|>List.filter(funx->x<=limitu)|>List.map(funx->Num.remxu)|>Array.of_listwith|Invalid_argument_->letto_strctr=Printf.sprintf"{%s}"@@String.concat","(Array.to_list@@to_string_arrayctr)inlet()=Logs.warn(funm->m"Bad key/ctr pair ( %s / %s) for given ~upper:%d"(to_strkey)(to_strctr)upper)in[||]letuniform?(upper=default_upper)?(rounds=default_rounds)~key~ctr()=unbiased~key~ctrupper@@rand~rounds~key~ctr()|>to_int_arrayletuniform01?(rounds=default_rounds)~key~ctr()=letarr=unbiased~key~ctrdefault_upper@@rand~rounds~key~ctr()inArray.map(funx->letf=Num.to_intx|>float_of_intinf/.default_upper_float)arrletdraw_from~rand~uniform01~uniform~(key:t)~(ctr:t)=function|Rand->rand?rounds:None~key~ctr()|>to_string_array|Uniform01->uniform01?rounds:None~key~ctr()|>Array.mapstring_of_float|Uniformupper->uniform?upper:(Someupper)?rounds:None~key~ctr()|>Array.mapstring_of_intletdigits=Num.digitsletnum_equal_zero=Num.equalNum.zeroletis_zero=Array.for_allnum_equal_zeroendmoduleGen_2_32=Make(Num_uint32_2)(Rng_threefry_2_digits)moduleGen_4_32=Make(Num_uint32_4)(Rng_threefry_4_digits)moduleGen_2_64=Make(Num_uint64_2)(Rng_threefry_2_digits)moduleGen_4_64=Make(Num_uint64_4)(Rng_threefry_4_digits)