Annotation of embedaddon/ntp/lib/isc/lfsr.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
        !             3:  * Copyright (C) 1999-2002  Internet Software Consortium.
        !             4:  *
        !             5:  * Permission to use, copy, modify, and/or distribute this software for any
        !             6:  * purpose with or without fee is hereby granted, provided that the above
        !             7:  * copyright notice and this permission notice appear in all copies.
        !             8:  *
        !             9:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
        !            10:  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
        !            11:  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
        !            12:  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
        !            13:  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
        !            14:  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
        !            15:  * PERFORMANCE OF THIS SOFTWARE.
        !            16:  */
        !            17: 
        !            18: /* $Id: lfsr.c,v 1.20 2007/06/19 23:47:17 tbox Exp $ */
        !            19: 
        !            20: /*! \file */
        !            21: 
        !            22: #include <config.h>
        !            23: 
        !            24: #include <stddef.h>
        !            25: #include <stdlib.h>
        !            26: 
        !            27: #include <isc/assertions.h>
        !            28: #include <isc/lfsr.h>
        !            29: #include <isc/util.h>
        !            30: 
        !            31: #define VALID_LFSR(x)  (x != NULL)
        !            32: 
        !            33: void
        !            34: isc_lfsr_init(isc_lfsr_t *lfsr, isc_uint32_t state, unsigned int bits,
        !            35:              isc_uint32_t tap, unsigned int count,
        !            36:              isc_lfsrreseed_t reseed, void *arg)
        !            37: {
        !            38:        REQUIRE(VALID_LFSR(lfsr));
        !            39:        REQUIRE(8 <= bits && bits <= 32);
        !            40:        REQUIRE(tap != 0);
        !            41: 
        !            42:        lfsr->state = state;
        !            43:        lfsr->bits = bits;
        !            44:        lfsr->tap = tap;
        !            45:        lfsr->count = count;
        !            46:        lfsr->reseed = reseed;
        !            47:        lfsr->arg = arg;
        !            48: 
        !            49:        if (count == 0 && reseed != NULL)
        !            50:                reseed(lfsr, arg);
        !            51:        if (lfsr->state == 0)
        !            52:                lfsr->state = 0xffffffffU >> (32 - lfsr->bits);
        !            53: }
        !            54: 
        !            55: /*!
        !            56:  * Return the next state of the lfsr.
        !            57:  */
        !            58: static inline isc_uint32_t
        !            59: lfsr_generate(isc_lfsr_t *lfsr)
        !            60: {
        !            61: 
        !            62:        /*
        !            63:         * If the previous state is zero, we must fill it with something
        !            64:         * here, or we will begin to generate an extremely predictable output.
        !            65:         *
        !            66:         * First, give the reseed function a crack at it.  If the state is
        !            67:         * still 0, set it to all ones.
        !            68:         */
        !            69:        if (lfsr->state == 0) {
        !            70:                if (lfsr->reseed != NULL)
        !            71:                        lfsr->reseed(lfsr, lfsr->arg);
        !            72:                if (lfsr->state == 0)
        !            73:                        lfsr->state = 0xffffffffU >> (32 - lfsr->bits);
        !            74:        }
        !            75: 
        !            76:        if (lfsr->state & 0x01) {
        !            77:                lfsr->state = (lfsr->state >> 1) ^ lfsr->tap;
        !            78:                return (1);
        !            79:        } else {
        !            80:                lfsr->state >>= 1;
        !            81:                return (0);
        !            82:        }
        !            83: }
        !            84: 
        !            85: void
        !            86: isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count)
        !            87: {
        !            88:        unsigned char *p;
        !            89:        unsigned int bit;
        !            90:        unsigned int byte;
        !            91: 
        !            92:        REQUIRE(VALID_LFSR(lfsr));
        !            93:        REQUIRE(data != NULL);
        !            94:        REQUIRE(count > 0);
        !            95: 
        !            96:        p = data;
        !            97:        byte = count;
        !            98: 
        !            99:        while (byte--) {
        !           100:                *p = 0;
        !           101:                for (bit = 0; bit < 7; bit++) {
        !           102:                        *p |= lfsr_generate(lfsr);
        !           103:                        *p <<= 1;
        !           104:                }
        !           105:                *p |= lfsr_generate(lfsr);
        !           106:                p++;
        !           107:        }
        !           108: 
        !           109:        if (lfsr->count != 0 && lfsr->reseed != NULL) {
        !           110:                if (lfsr->count <= count * 8)
        !           111:                        lfsr->reseed(lfsr, lfsr->arg);
        !           112:                else
        !           113:                        lfsr->count -= (count * 8);
        !           114:        }
        !           115: }
        !           116: 
        !           117: static inline isc_uint32_t
        !           118: lfsr_skipgenerate(isc_lfsr_t *lfsr, unsigned int skip)
        !           119: {
        !           120:        while (skip--)
        !           121:                (void)lfsr_generate(lfsr);
        !           122: 
        !           123:        (void)lfsr_generate(lfsr);
        !           124: 
        !           125:        return (lfsr->state);
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * Skip "skip" states in "lfsr".
        !           130:  */
        !           131: void
        !           132: isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip)
        !           133: {
        !           134:        REQUIRE(VALID_LFSR(lfsr));
        !           135: 
        !           136:        while (skip--)
        !           137:                (void)lfsr_generate(lfsr);
        !           138: }
        !           139: 
        !           140: /*
        !           141:  * Skip states in lfsr1 and lfsr2 using the other's current state.
        !           142:  * Return the final state of lfsr1 ^ lfsr2.
        !           143:  */
        !           144: isc_uint32_t
        !           145: isc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2)
        !           146: {
        !           147:        isc_uint32_t state1, state2;
        !           148:        isc_uint32_t skip1, skip2;
        !           149: 
        !           150:        REQUIRE(VALID_LFSR(lfsr1));
        !           151:        REQUIRE(VALID_LFSR(lfsr2));
        !           152: 
        !           153:        skip1 = lfsr1->state & 0x01;
        !           154:        skip2 = lfsr2->state & 0x01;
        !           155: 
        !           156:        /* cross-skip. */
        !           157:        state1 = lfsr_skipgenerate(lfsr1, skip2);
        !           158:        state2 = lfsr_skipgenerate(lfsr2, skip1);
        !           159: 
        !           160:        return (state1 ^ state2);
        !           161: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>