Beispiel #1
0
        internal static Tweak EncodeTweak(UInt64 position, bool bitPad, TweakType type, bool first, bool final)
        {
            //
            // Takes tweak parameters and encodes them in a 128 bit value. The lower half of the 128 byte value (only the position)
            // is stuck in low64 and the high half in stuck in high64.
            //
            // N.B SimpleSkeinManaged specifies that position can be upto 2^96 but we support only 2^64. We could add support by rolling our own BigInteger
            //
            // The encoding is as follows (ASCII art not to scale)
            //
            // 128             120                   112            96                                    0
            // --------------------------------------------------------------------------------------------
            // F1|F2|    Type   |B|       TreeLevel   |   reserved  |      Position                       |
            //   |  |           | |                   |             |                                     |
            // --------------------------------------------------------------------------------------------
            //  F1 = First
            //  F2 = Final
            //  B  - BitPad
            //

            Tweak tweak = new Tweak(0,0);
            tweak.high64 = 0;

            //
            // The shift numbers are calculated using 64 - (128 - end-byte-from-diagram-above)
            //
            if (final) tweak.high64 |= (UInt64)1L << 63; // Set F1 in diagram above
            if (first) tweak.high64 |= (UInt64)1L << 62; // Set F2 in diagram above
            tweak.high64 |= (UInt64)type << 56; // Set type
            if (bitPad) tweak.high64 |= (UInt64)1L << 55; // Set bit pad

            tweak.low64 = position;
            return tweak;
        }
Beispiel #2
0
        internal void Update(UInt64[] message, Tweak tweak)
        {
            //
            // Takes encoded tweak value and message, encrypts using current state as key and XORs
            // result with message. The block size is determined by looking at input message length
            // TODO: Reuse block cipher instance
            //

            if (_Hi.Length != message.Length){
                throw new InvalidOperationException("Can't change block size in mid flight");

            }
            Threefish threeFish = new Threefish(_Hi, tweak, _blockSize);
            threeFish.Encrypt(message, _Hi);

            for (int i = 0; i < _Hi.Length; i++){

                _Hi[i] ^= message[i];
            }
        }
Beispiel #3
0
        public Threefish(UInt64[] key, Tweak tweak, ThreeFishBlockSize blockSize)
        {
            //
            // TODO: Move non-onetime initialization so that consumers can cache instances
            //
            if (key.Length != (int)blockSize/8) {
                throw new ArgumentException("Key size should match block size");
            }

            this.BlockSize = blockSize;

            //
            // Set number of words rounds based on block size
            //

            _numWords = (int)BlockSize / sizeof(UInt64);

            switch (BlockSize) {

                case ThreeFishBlockSize.BLOCKSIZE_256_BITS:
                    this._rounds = ThreeFishRounds.ROUNDS_72;
                    this.RotationConstants = Rdj_Nw_4;
                    this.PermutationPi = Threefish.PI_I_Nw_4;
                    break;
                case ThreeFishBlockSize.BLOCKSIZE_512_BITS:
                    this._rounds = ThreeFishRounds.ROUNDS_72;
                    this.RotationConstants = Rdj_Nw_8;
                    this.PermutationPi = Threefish.PI_I_Nw_8;
                    break;
                case ThreeFishBlockSize.BLOCKSIZE_1024_BITS:
                    this._rounds = ThreeFishRounds.ROUNDS_80;
                    this.RotationConstants = Rdj_Nw_16;
                    this.PermutationPi = Threefish.PI_I_Nw_16;
                    break;
            }

            //
            // KeyWords is special in that it has an extra element kNw at the end
            //
            this.KeyWords = new UInt64[key.Length + 1];
            Array.Copy(key, KeyWords, key.Length) ;

            //
            // Initialize Vd, Ed, fd and Ksd
            //

            _vd = new UInt64[_numWords];
            _ed = new UInt64[_numWords];
            _kdi = new UInt64[_numWords];
            _fd = new UInt64[_numWords];

            //
            // Initialize ts values(as per section 3.3.2)
            //
            _ts[0] = tweak.low64;
            _ts[1] = tweak.high64;
            _ts[2] = _ts[0] ^ _ts[1];

            //
            // Initialize kNw (as per section 3.3.2). Already set to 2^64/3
            //

            for (int i = 0; i < _numWords; i++) {
                _kNw ^= KeyWords[i];
            }
            KeyWords[_numWords] = _kNw;
        }