// // Copyright (c) 2003-2006 Robin J Carey. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions, and the following disclaimer, // without modification, immediately at the beginning of the file. // 2. The name of the author may not be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. // // # ifndef OOO__L15P_h__OOO # define OOO__L15P_h__OOO // ``ISO C89''/``ANSI C'' // # include // For: size_t typedef unsigned int LValueType; static const size_t L15_DIGEST_BYTELEN = 32; // ``ANSI C++'' // class L15P { private: LValueType x, y, z; const LValueType start_x; static const size_t stateSize = 256; LValueType state [ stateSize ]; LValueType MOD (const LValueType in) { return (in % stateSize); } void Swap (const LValueType pos1, const LValueType pos2) { const LValueType save1 = state [ pos1 ]; state [ pos1 ] = state [ pos2 ]; state [ pos2 ] = save1; } void InitState (void) { for (size_t i = 0; i < stateSize; ++i) { state [ i ] = i; } } void KSA (const LValueType * const key, const size_t keyLen) { # define L_SCHEDULE(xx, yy) \ \ for (size_t i = 0; i < stateSize; ++i) { \ Swap (i, MOD((yy) += (state [ i ] + (xx)))); \ } LValueType stateIndex = 0; L_SCHEDULE(keyLen, stateIndex); for (size_t keyIndex = 0; keyIndex < keyLen; ++keyIndex) { L_SCHEDULE(key [ keyIndex ], stateIndex); } } void Discard (const LValueType numCalls) { for (LValueType i = 0; i < numCalls; ++i) { (void) Output (); } } public: // For digital-fingerprint usage (where there is no initial "key"). L15P (void) : x (0), y (0), start_x (x) { InitState (); } L15P (const LValueType * const key, const size_t keyLen) : x (0), y (0), start_x (x) { InitState (); KSA (key, keyLen); Discard (Output ()); // Makes x/y unknown values. } ~L15P (void) { // Clear memory. InitState (); x = y = z = 0; } LValueType Output (void) { Swap (state [ MOD(x) ], MOD(y)); z = (state [ MOD(x++) ] + state [ MOD(y--) ]); if (MOD(x) == start_x) { --y; } return state [ MOD(z) ]; } // For semantically correct digital-fingerprint usage: void Update (const LValueType * const data, const size_t dataLen) { KSA (data, dataLen); } // For digital-fingerprint usage (produce fingerprint): void Final (LValueType * const digest) { for (size_t i = 0; i < L15_DIGEST_BYTELEN; ++i) { digest [ i ] = Output (); } } void Vector (const LValueType * const key, const size_t keyLen) { KSA (key, keyLen); } size_t QueryStateSize (void) const { return stateSize; } }; # endif // !OOO__L15P_h__OOO