Re: randomness (crypto?) code example wanted please?
Kamil Rytarowski <[email protected]> Sun, 25 Jun 2017 13:53:02 +0200
| Newsgroups | gmane.os.netbsd.devel.crypto,gmane.os.netbsd.devel.userlevel |
|---|---|
| Message-ID | <[email protected]> |
This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --aKWQFNBslk0RXsKqBPaLGF6tu84OQEtN2 Content-Type: multipart/mixed; boundary="NtutoPrklPauoofIgeIP1nMISX8cjMpE2"; protected-headers="v1" From: Kamil Rytarowski <[email protected]> To: Robert Elz <[email protected]>, [email protected], [email protected] Message-ID: <[email protected]> Subject: Re: randomness (crypto?) code example wanted please? References: <[email protected]> In-Reply-To: <[email protected]> --NtutoPrklPauoofIgeIP1nMISX8cjMpE2 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: quoted-printable On 25.06.2017 10:21, Robert Elz wrote: > Hi, >=20 > I am (sometime not to far away) planning to add $RANDOM to > the NetBSD shell (for !SMALL shells so not for install media) - part > of keeping up with the Jones's, as just about every other shell has it,= > even our /bin/ksh. >=20 > Its default will be to return random values 15 bite wide (0..32767) > just because that is what everyone else does (from ancient history) > but I will also add a mechanism to allow the user to select how > many bits to return (probably a "RANDOM_BITS" variable, which would > default to 15 if not set, unless someone has a better suggestion.) >=20 > What I am lacking at the minute is a method to produce good random > numbers (in the 15 bit, or any other, range), so I am seeking advice > (in the form of code fragments, either in the form of code in e-mail, > or a pointer to where in the NetBSD src tree I can find a good example.= ) >=20 > I'd prefer not references off into pkgsrc land, or even worse, www, > but if that's all that is possible... What's more, this really needs > to use only what is available in libc to avoid requiring linking > against more libraries, and slowing sh startup time. >=20 > Since this is for in-tree code I will not be copying, or using, anythin= g > GPL'd or similarly restricted. >=20 > The definition of RANDOM is that users can assign to it to set the > seed, so we need a method whereby if an integer of some arbitrary > number of bits is assigned by the user/script we can use that to > generate a repeatable sequence of "random" numbers. (Remember the she= ll > works with char *'s so the "integer" here is just a string of digits, > it has no inherent max value, though we can limit what we use any way w= e like.) >=20 > I am planning to extend that so that if a null string is assigned to > RANDOM (which will be its initial value at sh start) then the seed > gets fetched from /dev/urandom (or /dev/random if someone can convince > me why that would be better.) Suggestions on how many bits to read > from there in order to make whatever randomness algorithm you suggest > work well are also needed. (As you will see below, sh (my internal ve= rsion) > currently just sets the seed to 0 - but that is explicit in the current= code, > not a side effect.) (Note all this happens when $RANDOM is expanded, i= f > it has been assigned a value by the script, before being referenced, > /dev/*random will not be used, unless later, RANDOM=3D'' is executed, > and then $RANDOM referenced.) >=20 > We can also look for a leading 0x (or some other indicator, like ',' or= ':' > chars in the value) and interpret the seed value any way that is useful= > in that case. >=20 > Note: I will only be implementing one algorithm, not dozens with some > way for the user to select! >=20 > I have implemented the underlying mechanism in the shell to make all th= is > happen, but as you will see when I show some examples below, the curren= t > code will not pass anyone's idea of what is a random number... (it wil= l > never be released in this form). [Ugh: that sounds grandiose - it is > just a few lines of code, took far less time than writing this message,= > and is so simple it worked first time.] >=20 > So, please help. >=20 > But if your answer will be: "Just use rand(3) - it returns 15 bit value= s" > then don't bother sending it, thanks all the same. >=20 > Alternatively, if your answer is "random(3) is good enough for this" th= en > there is no need to send code (or pointers to code) - I know how to use= > random(3) (I just haven't yet, as I suspect that would be wasted effort= , > I have a feeling I will be told to use something better). If this is > the answer however, please suggest how big the state table should be, a= nd > whether, after shell startup, it ever needs to be reinitialised, and if= > so when? (Whenever the seed is explicitly set? Every hour? Every 100 = refs?) >=20 > In any case, if you plan on replying only to tech-crypto, please explic= itly > cc me, I'm not on that list (if you also reply to tech-userlevel, then = there > is no need to include me, I will see those replies, but there is also n= o > harm done including my addr as well, duplicate messages do not bother m= e.) >=20 > Thanks, >=20 > kre >=20 > And now, here, from initial shell startup state, is a demo of the > current implementation: >=20 > $ for f in a b c d; do printf '%s ' ${RANDOM}; done; printf '\n' > 1 2 3 4=20 > $ RANDOM=3D100 > $ for f in a b c d; do printf '%s ' ${RANDOM}; done; printf '\n' > 101 102 103 104=20 > $ RANDOM=3D$(date +%s) > $ for f in a b c d; do printf '%s ' ${RANDOM}; done; printf '\n' > 25913 25914 25915 25916=20 > $ RANDOM=3D > $ for f in a b c d; do printf '%s ' ${RANDOM}; done; printf '\n' > 1 2 3 4=20 > $ RANDOM=3D32766 > $ for f in a b c d; do printf '%s ' ${RANDOM}; done; printf '\n' > 32767 0 1 2=20 >=20 > I suspect you can all guess the current "randomness" algorithm! >=20 There is a libc function for this kind of tasks: arc4random_uniform(3). I was evaluation at some point whether this could be done differently, with a dedicated userland random(1) program, that would be standalone and independent from a shell. It could accept arguments of type of randomness, ranges etc. Portable programs would use this external utility. I would certainly depend on it in a case of a portable shell scripts, on the other hand there is Perl/Python that would ship it natively.. I was trying to generate these numbers in a shell with awk(1), but this approach was imperfect. --NtutoPrklPauoofIgeIP1nMISX8cjMpE2-- --aKWQFNBslk0RXsKqBPaLGF6tu84OQEtN2 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJZT6QnAAoJEEuzCOmwLnZsRQoP/Ag/FB4jSd1WgVxXX6OYNKHA PQ5bNrwO3UiC46o8phdQmhix8sI3neTbic4k6y+9C2vFLFBYvfnzCqGJnrri4+sT 2xiY18ojhqv2z1zfLonVXx5YewBm0Fe0fOtVMsWyE+ib0BoMsDVVDgKr67J7HyjK fETbyYyNBR+pKO2DdcvVHZDorp7fvmD7wZwK7ZYfxLwIlL/zeAiCpvTPj1ryZ67L vdPEq75iFEgCLfCXQUxXMaCBBLLkIWRlVgYjrYXNlAYTf1Tvtbv0eQ/21VBMCgTK EO44IAL58J4VZPynuNcsreLkm2nFv+pkh7Z4dqWucwtXGZR37Ua5lB1B8+wMlv94 HIRqS0GIBSgFozLZslN92yItL3xbOiNbj6UPjhARUMsZvZkwrPn5hges/SMfNxE9 fjX0hTwzRasssVYyrddm9xMpfxKnUPV5gXXLqKfVBP3aLur5L1JSnEo0dyCSMsCI tbna+yt4fUhgbON1yiJ1BMxcKh3IOcMXB+x0X+C+hucbrgHd2d6VLn0XJrPbR+H3 yGK2OP0o/X+/D9R1TM7zCO0vdPtjUDL2v2zmY1H2VE4kCZaONC9p/e2cg3wPa94f Y/d8jNCcpH6SBNWxa+tP7WJ5hiv1VcHngQo91HE3hvHE03WoBi75GmQ/XkZol/wW PUqbUhaGQ8X+WqAjnyik =Upbz -----END PGP SIGNATURE----- --aKWQFNBslk0RXsKqBPaLGF6tu84OQEtN2--