from Hacker News

Librandombytes – a public domain library for generating randomness

by tkhattra on 1/26/23, 6:46 PM with 77 comments

  • by josephg on 1/27/23, 7:09 AM

    How does this compare to what you get from one of the csprngs in rust's rand crate? I'm not sure when I'd use this.

    https://rust-random.github.io/book/guide-rngs.html#cryptogra...

  • by jcrites on 1/26/23, 9:54 PM

    Are there any methods of generating randomness on common platforms — Linux (raw or VM), Windows, MacOS — that are suitable for use as a cryptographic one-time pad?

    The definition of this library function seems to suggest that it’s suitable:

    > librandombytes aims for the following stringent randomness goal: no feasible computation will ever be able to tell the difference between the output bytes and true randomness (independent uniformly distributed random bytes).

    However my understanding is that PRNGs are not a suitable source of randomness for one time pads; that this would reduce OTP encryption to being something like an ad hoc stream cipher.

    So some implementations that might look random wouldn’t actually provide a suitable bitstream for this purpose: the bits in the output would be correlated, if in a complex, cryptographically obscure way. (But bits in a one-find pad should all be entirely random and uncorrelated.)

    Is that accurate?

    Do modern PCs have an efficient way to produce meaningful amounts of true stochastic random data suitable for use with OTP encryption (such as the RDRAND instruction)? What are some good abstractions for producing a stream of random data suitable for use with OTP cryptography?

    Edit: this is a question for the sake of curiosity. I realize that practical systems have many threat vectors and that OTP is not a panacea, or even necessarily an improvement.

  • by dogeprotocol on 1/27/23, 9:12 AM

    Can anyone recommend between Librandombytes and libsodium ramdombytes?

    https://github.com/jedisct1/libsodium/tree/master/src/libsod...

  • by benj111 on 1/26/23, 10:10 PM

    When are we going to get a distributed peer to peer randomness service.

    I could roll a die in return for $random crypto currency.

    Obviously the amount could vary depending on the amount of randomness. So me thinking of a random number would get less than a die roll which would get less than this comment.

  • by throwaway81523 on 1/27/23, 2:45 AM

    This is a randomness distillation function that gets entropy from a system source like linux getrandom() or the OpenSSL RNG. It's nice but it is purely computational. It doesn't harvest entropy on its own, if that is what you were hoping.
  • by olliej on 1/27/23, 4:15 AM

    arc4random() has existed to produce cryptographically random values for well over a decade (and despite the name, on Mac at least is not rc4 based and I assume Linux is the same). Additionally windows and Darwin/xnu have API to get large arrays of random values and I again will just assume Linux does too. This library should not be doing anything other than wrapping the specific api provided by the host platform.
  • by 1vuio0pswjnm7 on 1/27/23, 5:26 AM

    Small program to generate random bytes to stdout, using original 2008 randombytes() function that presumably inspired librandombytes.

    Usage:

        a.out number_of_bytes
    
    For example,

       a.out 128 > data
       od -tx1 -An < data
    
    Taken from public domain source code by djb and jmojzis. Tested on Void Linux with musl.

        #include <stdlib.h> 
        #include <unistd.h> 
        #include <sys/types.h> 
        #include <fcntl.h> 
        #include <poll.h> 
        #include <errno.h> 
        #include <sys/stat.h> 
       
       int strtonum(long long *,const char *);
       int strtonum(long long *r,const char *buf){
           char *bufpos=(char *)buf;
           int flagsign=0;
           long long i;
           unsigned long long c,ret=0;
           if (!buf) goto failed;
           switch(buf[0]){
               case 0:   goto failed;break;
               case '+': ++bufpos;break;
               case '-': flagsign=1;++bufpos;break;
               default:  break;
           }
           for(i=0;bufpos[i];++i){
               c=bufpos[i]-'0';
               if(c<0||c>9)break;
               c+=10*(ret);
               if(ret>c)goto failed; 
               ret=c;
           }
           if(i==0)goto failed; 
           if(flagsign){*r=-ret;if(*r>0)goto failed;}
           else{*r=ret;if(*r<0)goto failed;}
           return 1;
       failed:
           *r=0;
           errno=EINVAL;
           return 0;
       }
       
       int writeall(int,const void *,long long);
       int writeall(int fd,const void *xv,long long xlen)
       {
         const unsigned char *x=xv;
         long long w;
         while(xlen>0){
           w=xlen;
           if(w>1048576)w=1048576;
           w=write(fd,x,w);
           if(w<0){
             if(errno==EINTR||errno==EAGAIN||errno==EWOULDBLOCK){
               struct pollfd p;p.fd=fd;p.events=POLLOUT|POLLERR;
               poll(&p,1,-1);continue;
             }
             return -1;
           }
           x += w;
           xlen -= w;
         }
         return 0;
       }
       
       void randombytes(unsigned char *,unsigned long long);
       /* it's really stupid that there isn't a syscall for this */
       static int fd = -1;
       void randombytes(unsigned char *x,unsigned long long xlen)
       {
         int i;
         if(fd==-1){
           for(;;){
             fd=open("/dev/urandom",O_RDONLY);
             if(fd!=-1)break;
             sleep(1);
           }
         }
         while(xlen>0){
           if(xlen<1048576)i=xlen;else i=1048576;
           i=read(fd,x,i);
           if(i<1){sleep(1);continue;}
           x+=i;xlen-=i;
         }
       }
       
       int fsyncfd(int); 
       int fsyncfd(int fd){
           struct stat st;
           if(fstat(fd,&st)==0&&S_ISREG(st.st_mode)){
           if(fsync(fd)==-1)return -1;}
           return 0;
       }
       
       void byte_zero(void *,long long);
       void byte_zero(void *yv,long long ylen){
           long long i;char *y=yv;
           for(i=0;i<ylen;++i)y[i]=0;
       }
       
       static unsigned char buf[4096];
       int main(int argc,char **argv){
           long long i,l;
           if(!strtonum(&l,argv[1])||l<0)exit(0);
           byte_zero(buf,sizeof buf);
           while(l>0){
               i=l;
               if(i>sizeof buf)i=sizeof buf;
               randombytes(buf,i);
               if(writeall(1,buf,i)==-1)exit(0);
               l-=i;
           }
           if(fsyncfd(1)==-1)exit(0);
           exit(0);
       }
  • by remram on 1/26/23, 9:06 PM

    Is there an actual license file somewhere? Not only is the title of the page not necessarily authoritative enough, but public-domain dedication is not a thing in many countries, which is why CC-0 exists.