/* The eXtended Keccak Code Package (XKCP) https://github.com/XKCP/XKCP Implementation by Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". For more information, feedback or questions, please refer to the Keccak Team website: https://keccak.team/ To the extent possible under law, the implementer has waived all copyright and related or neighboring rights to the source code in this file. http://creativecommons.org/publicdomain/zero/1.0/ --- This file contains macros that help implement a permutation in a SnP-compatible way. It converts an implementation that implement state input/output functions in a lane-oriented fashion (i.e., using SnP_AddLanes() and SnP_AddBytesInLane, and similarly for Overwite, Extract and ExtractAndAdd) to the byte-oriented SnP. Please refer to SnP-documentation.h for more details. */ #ifndef _SnP_Relaned_h_ #define _SnP_Relaned_h_ #define SnP_AddBytes(state, data, offset, length, SnP_AddLanes, SnP_AddBytesInLane, SnP_laneLengthInBytes) \ { \ if ((offset) == 0) { \ SnP_AddLanes(state, data, (length)/SnP_laneLengthInBytes); \ SnP_AddBytesInLane(state, \ (length)/SnP_laneLengthInBytes, \ (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ 0, \ (length)%SnP_laneLengthInBytes); \ } \ else { \ unsigned int _sizeLeft = (length); \ unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ const unsigned char *_curData = (data); \ while(_sizeLeft > 0) { \ unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ if (_bytesInLane > _sizeLeft) \ _bytesInLane = _sizeLeft; \ SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ _sizeLeft -= _bytesInLane; \ _lanePosition++; \ _offsetInLane = 0; \ _curData += _bytesInLane; \ } \ } \ } #define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \ { \ if ((offset) == 0) { \ SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \ SnP_OverwriteBytesInLane(state, \ (length)/SnP_laneLengthInBytes, \ (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ 0, \ (length)%SnP_laneLengthInBytes); \ } \ else { \ unsigned int _sizeLeft = (length); \ unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ const unsigned char *_curData = (data); \ while(_sizeLeft > 0) { \ unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ if (_bytesInLane > _sizeLeft) \ _bytesInLane = _sizeLeft; \ SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ _sizeLeft -= _bytesInLane; \ _lanePosition++; \ _offsetInLane = 0; \ _curData += _bytesInLane; \ } \ } \ } #define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \ { \ if ((offset) == 0) { \ SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \ SnP_ExtractBytesInLane(state, \ (length)/SnP_laneLengthInBytes, \ (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ 0, \ (length)%SnP_laneLengthInBytes); \ } \ else { \ unsigned int _sizeLeft = (length); \ unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ unsigned char *_curData = (data); \ while(_sizeLeft > 0) { \ unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ if (_bytesInLane > _sizeLeft) \ _bytesInLane = _sizeLeft; \ SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ _sizeLeft -= _bytesInLane; \ _lanePosition++; \ _offsetInLane = 0; \ _curData += _bytesInLane; \ } \ } \ } #define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \ { \ if ((offset) == 0) { \ SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \ SnP_ExtractAndAddBytesInLane(state, \ (length)/SnP_laneLengthInBytes, \ (input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ (output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ 0, \ (length)%SnP_laneLengthInBytes); \ } \ else { \ unsigned int _sizeLeft = (length); \ unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ const unsigned char *_curInput = (input); \ unsigned char *_curOutput = (output); \ while(_sizeLeft > 0) { \ unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ if (_bytesInLane > _sizeLeft) \ _bytesInLane = _sizeLeft; \ SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \ _sizeLeft -= _bytesInLane; \ _lanePosition++; \ _offsetInLane = 0; \ _curInput += _bytesInLane; \ _curOutput += _bytesInLane; \ } \ } \ } #endif