|                                                                                     | 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 | // MANGLER.CPP
//
// Copyright (C) 2004-2020 MicroNeil Research Corporation.
//
// This software is released under the MIT license. See LICENSE.TXT.
//
// Derived from Version 1 of Mangler Encryption Algorythm, 1984.
// Derived from Version 2 of Mangler Encryption Algorythm, 1998.
//
// Mangler encryption engine object.
// Using new optimized chaos driver for uniformity experiments.
// Important in this experiment is proof of highest possible entropy.
#include "mangler.hpp"
namespace codedweller {
unsigned char Mangler::ChaosDriver(void) {          // Return the current
  return Fill[Fill[Position]^Fill[Position^0xff]];  // chaos engine output
  }                                                 // value.
// As of version 3 the output of the chaos driver was strengthened for
// cryptography and to increase the sensitivity of the output for use
// as a random number generator. In version 2, the software would simply
// return the fill value at the engine's current position. In the new
// version two distinct fill values are involved in abstracting the
// value of Position and determining the final output value and the Position
// value itself is used to add complexity to the output.
unsigned char Mangler::Rotate(unsigned char i) {   // Bitwise rotates i
  return (
    (i & 0x80)?                                    // This operation is
      (i<<1)+1:                                    // described without
      (i<<1)                                       // using asm.
    );
  }
void Mangler::ChaosDriver(unsigned char i) {    // Drives chaos engine.
  // First we move our mixing position in the fill buffer forward.
  Position=(                                    // Move mixing position.
    Position+1+                                 // Move at least 1, then
    (Fill[Position]&0x0f)                       // maybe a few more.
    )%256;                                      // But stay within the fill.
  // The fill position in version 2 was simply incremented. This allowed
  // for an attacker to predict something important about the state of
  // the chaos engine. The new method above uses abstraction through the
  // fill buffer to introduce "jitter" when setting a new position based
  // on data that is hidden from the outside.
  // Next we abstract the incoming character through the fill buffer and
  // use it to select fill data to rotate and swap.
  unsigned char Swap = ((Fill[Position]^Fill[i])+Position+i)%256;
  unsigned char Tmp;
  Tmp = Fill[Swap];
  Fill[Swap]=Fill[Position];
  Fill[Position]=Rotate(Tmp);
  // Whenever the Swap and Path positions are the same, the result is
  // that no data is swapped in the chaos field. We resolve that by
  // recalling the ChaosDriver. This has the added effect of increasing
  // the complexity and making it more difficult to predict the state
  // of the engine... particularly because the engine evloves to a new
  // state under these conditions without having exposed that change
  // to the outside world.
  if(Position==Swap) ChaosDriver(Tmp); // If we didn't swap, recurse.
  }
// The encryption / decryption scheme works by modulating an input data
// stream with a chaotic system and allowing the encrypted stream to drive
// the chaotic system of both the transmitter and receiver. This will
// synchronize the two chaotic systems and allow the receiving system to
// "predict" the state of the transmiting system so that it can properly
// demodulate the encrypted stream. Both chaotic systems must start in the
// same state with the same fill data characteristics or else the two
// chaotic systems evolve to further divergent states.
unsigned char Mangler::Encrypt(unsigned char i) {
   unsigned char g = ChaosDriver() ^ i;         // Take the output of the
   ChaosDriver(g);                              // chaos engine and use it
   return g;                                    // to moduleate the input.
   }                                            // Then drive the engine
                                                // with the encrypted data.
unsigned char Mangler::Decrypt(unsigned char i) {
   unsigned char g = ChaosDriver() ^ i;         // Take the output of the
   ChaosDriver(i);                              // chaos engine and use it
   return g;                                    // to demodulate the input.
   }                                            // then drive the engine
                                                // with the original input.
Mangler::Mangler(void) : Position(0) {          // The default constructor sets
   for(unsigned int c = 0;c<256;c++)            // the key to the root primary
      Fill[c]=(unsigned char) c;                // value and Position to 0.
   }
} // End namespace codedweller
 |