
Libsodium 1.0.0 released - jedisct1
http://www.libsodium.org/doc/
======
lifeisstillgood
I was reading around the zeroMQ implementation of secure messaging that uses
this library. It seemed sensible enough (plaintext handshake, exchange session
keys and hashes to verify long term keys). But it was entirely couched in "I
am not a cryptographer" and "strawman only" caveats.

I appreciate the dangers of thinking "encryption cures all other bad
decisions" but it would be useful to have a spectrum of security we can talk
about.

I would love to see something like Big O notation for security - where we are
95% confident that the implementation has closed off vulnerabilities "on the
order of published exploits, on the order of passive sniffing inside network,
on the order of State level actor targeting your data"

I just wonder if we ever can say "hell yes this will do" as opposed to "well
even Fort Knox might have a vulnerable point"

Edit: perhaps I mean "design patterns for security layers"

------
ZoFreX
The only part of this I care about right now is the random number generation.
It looks good. Pity there's no way to get a float though, for a drop-in drand
replacement.

~~~
TillE
Generate 8 random bytes, shove them in an unsigned 64-bit int, then divide
that number by 2^64 - 1. I assume that's what any function which returns a
random value between 0.0 and 1.0 is actually doing.

~~~
mjevans
It would probably be faster to directly 'hack' a raw IEEE 754 floating number:

[http://en.wikipedia.org/wiki/IEEE_754-1985](http://en.wikipedia.org/wiki/IEEE_754-1985)

The helpful Examples section already contains the numbers 0 and 1.

Let us assume that the output is supposed to be between 0 and 1; it seems that
0 should be inclusive and 1 exclusive for the most balanced 'quick' output.

Those two numbers have the leading binary format:

0 (8 or 11 bits exponent) (23 or 52 bits fraction) For either 32 or 64 bit
floats.

Thus for a float (32 bit):

0 0 (7 bits) (23 bits) 30 bits of randomness are necessary, HOWEVER 0 01111111
is already one when the fraction is all 0s. The easiest solution I can see is
to evenly drop some precision:

A reference for the casting procedure:
[http://en.wikipedia.org/wiki/Fast_inverse_square_root#Overvi...](http://en.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code)

Pseudo:

    
    
        uint32 randomNumber;
        ... set the random somehow, maybe rand() maybe /dev/urandom etc ...
        randomNumber &= 0x3F7FFFFF;
        return * (float *) &randomNumber;

~~~
ZoFreX
There's a really big problem with dumping random bytes straight into a float,
which is that you'll end up with a distribution that, while random, is not
linear - i.e. the chance of it being between 0 and 0.5 will not be the same as
the chance of it being between 0.5 and 1.0. This is because the gaps between
representable numbers increases as the magnitude increases, i.e. there are
"more numbers" between 0 and 1 than 100 and 101. The best technique I've found
(so far) is to dump the bytes into an int, and divide.

~~~
gjm11
If you put 0 (i.e., plus) in the sign bit, and 1023 (i.e., zero) in the
exponent field, and 52 random bits in the fraction field, of an IEEE double,
then you get a number between 1 (inclusive) and 2 (exclusive); the
representable numbers in that range are evenly spaced, and if your random bits
are good then they are all equally likely, so you've got a uniform random
number between 1 and 2. Subtract 1 if you want a uniform random number between
0 and 1 (this doesn't lose information; if a number between 1 and 2 is
representable, subtracting 1 yields a representable number).

If your machine happens to work the same way as mine, the following will do it
(unportable, untested, yadda yadda):

    
    
        double randomDouble() {
          uint64_t bits = random64bits();
          bits &= ~(3ull<<62); // clear sign and MSB of expt
          bits |= (1023ull<<52); // rest of exponent is 1-bits
          return (*(double*)&bits) - 1;
        }

~~~
ZoFreX
Interesting, I'll test this. Thanks!

Btw, what is the advantage of this over dividing? Is it faster, does it give
better distribution?

~~~
lmm
It should be faster than dividing. It will give you a uniform distribution
over some (but not all) of the representable values between 0.0 and 1.0 (there
are as many representable values between e.g. 0.25 and 0.5 as there are
between 0.5 and 1.0, so a uniform distribution over representable values
probably isn't what you want), which is probably as good as you can do.

------
kefka
Can someone much smarter than I tell me if this is safe to use? Or better yet,
when a time period has passed to consider it safe to use?

~~~
tptacek
It's better if you don't build crypto directly into your application at all,
because you can still screw things up even if you build on Nacl. But with that
said: Sodium/Nacl is better than virtually any of your other options for
working directly with cryptography.

~~~
ary
I'm curious to know what you'd recommend for people who are looking to build
applications around novel network protocols that aren't interested in the the
certificate authority aspect of TLS?

~~~
tptacek
There's no reason you have to use CAs to authenticate TLS. Plenty of
enterprise tools keep whitelists of certificate hashes instead.

