http://ave1.org/code/eucrypt/eucrypt_crc32_div.vpatch.ave1.sig

http://ave1.org/code/eucrypt/eucrypt_crc32_div.vpatch

Nice implementation, easy to read!

I implemented a version that does the division (I use the same CRC32 type). This turned out to be a nice exercise; the message bits, as specificied for CRC32, have a reversed bit order (the xor at the start and end gave me some problems in the first implementation).

I do like the tricks that can be played with the shifts and the xors to get to the table implementation!

-- Function to calculate the a 32 bit CRC number. function crc32_of_string (message : in String) return CRC32 is A : CRC32 := 16#00_00_00_00#; R : CRC32 := 16#00_00_00_00#; D : constant CRC32 := 16#04_C1_1D_B7#; Zero : constant Character := Character'Val (0); -- Extend the string with 0 characters, needed to get all message bits -- into the division S : String := message & Zero & Zero & Zero & Zero; -- The Shift_Left instruction does not return the bit that was shifted -- We need a mask for this last bit -- Bits are counted from right to left, starting at 0 Bit31 : constant CRC32 := 16#80_00_00_00#; Bit1 : constant CRC32 := 16#01#; -- These functions need to be imported to get to the shift operators. -- (Specific for GNAT) function Shift_Left (Value : CRC32; Amount : Natural) return CRC32; pragma Import (Intrinsic, Shift_Left); function Shift_Right (Value : CRC32; Amount : Natural) return CRC32; pragma Import (Intrinsic, Shift_Right); begin -- Xor with 16#FF, the first 4 characters, same as a not for I in Integer range S'First .. S'First + 3 loop declare C : CRC32 := Character'Pos (S (I)); begin S (I) := Character'Val ((not C) and 16#FF#); end; end loop; -- The division, shift bits from the message unto the register -- If the left most bit on the register is 1 do an xor with the divisor for I in Integer range S'First .. S'Last loop declare C : CRC32 := Character'Pos (S (I)); begin for J in Integer range 1 .. 8 loop declare Bit31Set : constant Boolean := (Bit31 and A) = Bit31; BitSet : constant Boolean := (Bit1 and C) = Bit1; begin A := Shift_Left (A, 1); -- Shift right as the bit order is reversed in CRC 32 C := Shift_Right (C, 1); if BitSet then A := A or Bit1; end if; if Bit31Set then A := A xor D; end if; end; end loop; end; end loop; -- Reverse the bits in the result for I in Integer range 1 .. 32 loop declare Bit31Set : constant Boolean := (Bit31 and A) = Bit31; begin A := Shift_Left (A, 1); R := Shift_Right (R, 1); if Bit31Set then R := R or Bit31; end if; end; end loop; -- xor the result as per spec R := R xor 16#FF_FF_FF_FF#; return R; end crc32_of_string;]]>