Show
Ignore:
Timestamp:
12/27/11 19:48:29 (5 months ago)
Author:
tg
Message:

another long overdue update from MirBSD

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/freewrt/toolchain/uClibc/files/arc4random.c

    r3909 r3977  
    11static const char __vcsid[] = "@(#) MirOS contributed arc4random.c (old)" 
    2     "\n @(#)rcsid_master: $MirOS: contrib/code/Snippets/arc4random.c,v 1.24 2009/11/29 18:24:21 tg Exp $" 
     2    "\n @(#)rcsid_master: $MirOS: contrib/code/Snippets/arc4random.c,v 1.28 2010/09/12 12:24:27 tg Exp $" 
    33    ; 
    44 
     
    3333 
    3434/*- 
    35  * Copyright (c) 2008, 2009 
     35 * Copyright (c) 2008, 2009, 2010 
    3636 *      Thorsten Glaser <tg@mirbsd.org> 
    3737 * This is arc4random(3) made more portable, 
     
    167167                arc4_ctx.s[arc4_ctx.j] = si; 
    168168        } 
     169        arc4_ctx.i++; 
    169170        arc4_ctx.j = arc4_ctx.i; 
    170171} 
     
    278279        while (n--) 
    279280                arc4_getbyte(); 
    280         while (n < sizeof(tb)) 
    281                 tb[n++] = arc4_getbyte(); 
     281        while (++n < sizeof(tb)) 
     282                tb[n] = arc4_getbyte(); 
    282283        if (arc4_writeback(tb, sizeof(tb), 0)) 
    283284                arc4_getbyte(); 
     
    567568} 
    568569 
     570/*- 
     571 * Written by Damien Miller. 
     572 * With simplifications by Jinmei Tatuya. 
     573 */ 
     574 
    569575/* 
    570  * Calculate a uniformly distributed random number less than upper_bound 
    571  * avoiding "modulo bias". 
     576 * Calculate a uniformly distributed random number less than 
     577 * upper_bound avoiding "modulo bias". 
    572578 * 
    573  * Uniformity is achieved by generating new random numbers until the one 
    574  * returned is outside the range [0, 2**32 % upper_bound).  This 
    575  * guarantees the selected random number will be inside 
    576  * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) 
    577  * after reduction modulo upper_bound. 
     579 * Uniformity is achieved by generating new random numbers 
     580 * until the one returned is outside the range 
     581 * [0, 2^32 % upper_bound[. This guarantees the selected 
     582 * random number will be inside the range 
     583 * [2^32 % upper_bound, 2^32[ which maps back to 
     584 * [0, upper_bound[ after reduction modulo upper_bound. 
    578585 */ 
    579 u_int32_t 
    580 arc4random_uniform(u_int32_t upper_bound) 
    581 { 
    582         u_int32_t r, min; 
     586uint32_t 
     587arc4random_uniform(uint32_t upper_bound) 
     588{ 
     589        uint32_t r, min; 
    583590 
    584591        if (upper_bound < 2) 
    585592                return (0); 
    586593 
    587 #if defined(ULONG_MAX) && (ULONG_MAX > 0xffffffffUL) 
     594#if defined(ULONG_MAX) && (ULONG_MAX > 0xFFFFFFFFUL) 
    588595        min = 0x100000000UL % upper_bound; 
    589596#else 
    590         /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ 
    591         if (upper_bound > 0x80000000
    592                 min = 1 + ~upper_bound;                /* 2**32 - upper_bound */ 
    593         else { 
    594                /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ 
    595                 min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; 
    596         } 
     597        /* calculate (2^32 % upper_bound) avoiding 64-bit math */ 
     598        if (upper_bound > 0x80000000U
     599                /* 2^32 - upper_bound (only one "value area") */ 
     600               min = 1 + ~upper_bound; 
     601        else 
     602                /* ((2^32 - x) % x) == (2^32 % x) when x <= 2^31 */ 
     603               min = (0xFFFFFFFFU - upper_bound + 1) % upper_bound; 
    597604#endif 
    598605 
     
    601608         * p > 0.5 (worst case, usually far better) of selecting a 
    602609         * number inside the range we need, so it should rarely need 
    603          * to re-roll
     610         * to re-roll (at all)
    604611         */ 
    605         if (!rs_initialized || arc4_stir_pid != getpid()) 
     612        arc4_count -= 4; 
     613        if (!rs_initialized || arc4_stir_pid != getpid() || arc4_count <= 0) 
    606614                arc4random_stir(); 
    607615        if (arc4_getbyte() & 1) 
    608616                (void)arc4_getbyte(); 
    609         for (;;) { 
    610                 arc4_count -= 4; 
    611                 if (arc4_count <= 0) 
    612                         arc4random_stir(); 
     617        do { 
    613618                r = arc4_getword(); 
    614                 if (r >= min) 
    615                         break; 
    616         } 
     619        } while (r < min); 
    617620 
    618621        return (r % upper_bound);