I hope this is somewhat in the right direction? What should "digest_size" and "block_size" return?
Wouldn't it for the CRC function be better if "digest" and "hash" return the integer value, instead of a string? Best regards, Marc
commit c3e60d6d4d6e26b79bb63737633323e03f5b8be3 Author: Marc Dirix <[email protected]> Date: Wed Jun 16 15:21:56 2010 +0200 Add CRC to Crypto diff --git a/lib/modules/Crypto.pmod/CRC16.pmod b/lib/modules/Crypto.pmod/CRC16.pmod new file mode 100644 index 0000000..f98657f --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC16.pmod @@ -0,0 +1,14 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! CRC16 IBM Standard + +inherit .CRCState; + +.CRCState `()() { + +::init("CRC16", 16, ({ 16, 15, 2, 0 }), 0 , 1, 0, 0 ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRC16USB.pmod b/lib/modules/Crypto.pmod/CRC16USB.pmod new file mode 100644 index 0000000..e031fd7 --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC16USB.pmod @@ -0,0 +1,15 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! CRC used in USB data packets + + +inherit .CRCState; + +.CRCState `()() { + +::init("CRC16USB", 16, ({ 16, 15, 2, 0 }), 0xFFFF , 1, 0, 0xFFFF ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRC16X.pmod b/lib/modules/Crypto.pmod/CRC16X.pmod new file mode 100644 index 0000000..46338c2 --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC16X.pmod @@ -0,0 +1,9 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! CRC16 xmodem or zmodem. Also used for PlugWise. + +inherit .CRCState; + +.CRCState `()() { ::init("CRC16X",16, 0x11021, 0, 0, 0 , 0 ); return this; } + diff --git a/lib/modules/Crypto.pmod/CRC24.pmod b/lib/modules/Crypto.pmod/CRC24.pmod new file mode 100644 index 0000000..1a9e6b5 --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC24.pmod @@ -0,0 +1,14 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! CRC24 used in RFC-2440 and MIL STD 188-184 + +inherit .CRCState; + +.CRCState `()() { + +::init("CRC24", ({ 24, 23, 18, 17, 14, 11, 10, 7, 6, 5, 4, 3, 1, 0}), 0xB704CE , 0, 0, 0 ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRC32.pmod b/lib/modules/Crypto.pmod/CRC32.pmod new file mode 100644 index 0000000..c3cd11b --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC32.pmod @@ -0,0 +1,14 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! 32 bit CRC. + +inherit .CRCState; + +.CRCState `()() { + +::init("CRC32", 32, ({ 32, 26, 23, 22, 16, 12, 11, 10, 8, 7, 5, 4, 2, 1, 0 }), 0xFFFFFFFF , 1, 0, 0xFFFFFFFF ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRC32C.pmod b/lib/modules/Crypto.pmod/CRC32C.pmod new file mode 100644 index 0000000..32be862 --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC32C.pmod @@ -0,0 +1,14 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! 32 bit CRC used in iSCSI (RFC-3385); usually credited to Guy Castagnoli. + +inherit .CRCState; + +.CRCState `()() { + +::init("CRC32C", 16, ({ 32, 28, 27, 26, 25, 23, 22, 20, 19, 18, 14, 13, 11, 10, 9, 8, 6, 0 }), 0xFFFFFFFF , 1, 0, 0xFFFFFFFF ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRC5USB.pmod b/lib/modules/Crypto.pmod/CRC5USB.pmod new file mode 100644 index 0000000..bc10ea7 --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC5USB.pmod @@ -0,0 +1,15 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! CRC used in USB Token and Start-Of-Frame packets + + +inherit .CRCState; + +.CRCState `()() { + +::init("CRC5USB", 5, ({ 5, 2, 0 }), 0x1F , 1, 0, 0x1F ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRC64.pmod b/lib/modules/Crypto.pmod/CRC64.pmod new file mode 100644 index 0000000..1cd256e --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC64.pmod @@ -0,0 +1,14 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! 64 bit CRC according ISO 3309. + +inherit .CRCState; + +.CRCState `()() { + +::init("CRC64", ({ 64, 4, 3, 1, 0 }), 0 , 1, 0, 0 ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRC8SMbus.pmod b/lib/modules/Crypto.pmod/CRC8SMbus.pmod new file mode 100644 index 0000000..92b6bd9 --- /dev/null +++ b/lib/modules/Crypto.pmod/CRC8SMbus.pmod @@ -0,0 +1,14 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! CRC8 SMBus, Used in ATM HEC and SMBus. + +inherit .CRCState; + +.CRCState `()() { + +::init("CRC8SMBus", 8, ({ 8, 2, 1, 0 }), 0 , 0, 0, 0 ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRCCCITT.pmod b/lib/modules/Crypto.pmod/CRCCCITT.pmod new file mode 100644 index 0000000..3b72b8e --- /dev/null +++ b/lib/modules/Crypto.pmod/CRCCCITT.pmod @@ -0,0 +1,14 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! CRC16 CCITT + +inherit .CRCState; + +.CRCState `()() { + +::init("CRCCCITT", 16, ({ 16, 12, 5, 0 }), z , 0, 0, 0x0000 ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/CRCHDLC.pmod b/lib/modules/Crypto.pmod/CRCHDLC.pmod new file mode 100644 index 0000000..833b27a --- /dev/null +++ b/lib/modules/Crypto.pmod/CRCHDLC.pmod @@ -0,0 +1,14 @@ +#pike __REAL_VERSION__ +#pragma strict_types + +//! CRC HDLC is used in X.25 and for HDLC 2-byte FCS. + +inherit .CRCState; + +.CRCState `()() { + +::init("CRCHDLC", 16, ({ 16, 12, 5, 0 }), 0xFFFF , 1, 0, 0xFFFF ); +return this; +} + + diff --git a/lib/modules/Crypto.pmod/module.pmod b/lib/modules/Crypto.pmod/module.pmod index a08da57..94c39a2 100644 --- a/lib/modules/Crypto.pmod/module.pmod +++ b/lib/modules/Crypto.pmod/module.pmod @@ -112,3 +112,135 @@ function(string:string) rot13 = Crypto.Substitution()->set_rot_key()->crypt; #else constant this_program_does_not_exist=1; #endif /* constant(Nettle.HashState) */ + +class CRCState +{ + string name=""; + int width; + int lsbfirst=0; + int lsbfirstdata=0; + int xormask=0; + int bitmask; + int polymask; + int inbitmask; + int outbitmask; + int value; + + //! Initialize the CRC object. + //! @param width + //! The length of the polynomial. + //! @param polynomial + //! The polynomial, either an array or integer. + //! @param seed + //! The starting value of the algoritm + //! @param lsbfirst + //! Calculate the CRC from msb to lsb (zero) or lsb to msb (non zero). + //! @param lsbfirstdata + //! Calculate the data words from msb to lsb (zero) or lsb to msb (non zero). + //! If lsbfirstdata is zero, lsbfirstdata behaviour follows lsbfirst. + //! @param xormask + //! The output mask for the final computed CRC. + void init ( string name, int(0..) width, int|array polynomial, int seed, int lsbfirst, int lsbfirstdata, int xormask ) + { + this->name=name; + this->value = seed; + this->width=width; + this->lsbfirst=lsbfirst; + this->lsbfirstdata=lsbfirstdata | lsbfirst; + this->xormask=xormask; + + int word = 0; + if (arrayp(polynomial)) + { + foreach(polynomial,int n) + word |= 1 << n; + } + else + word=polynomial; + + bitmask = (1 << width) -1; + polymask = word & bitmask; + + if(lsbfirst) + { + polymask = Int.reflect(polymask,width); + inbitmask = 1 << (width -1 ); + outbitmask = 1; + } + else + { + this->inbitmask = 1; + this->outbitmask = 1 << ( width -1 ); + } + + + } + + //! Add's one bit to the CRC calculation. + void take_bit( int bit ) + { + int outbit; + if ( bit > 1 || bit < 0 ) + werror( "Values other then 0 or 1 are not allowed for bits\n"); + outbit = ((this->value & this->outbitmask) !=0 ); + if ( lsbfirst ) + value >>= 1; + else + value <<= 1; + value &= bitmask; + if ( outbit ^ bit ) + value ^= polymask; + } + + //! Add one word (int) to the CRC calculation. + //! @param word + //! The added word (int) + //! @param width + //! The bitlength of the word value. + //! If none given a bitlength of 8 is assumed. + void take_word( int word, int|void width ) + { + int len = 8; + if ( width > 0 ) + len = width; + if ( this->lsbfirstdata ) + for ( int i = 0; i < len; i++ ) + this->take_bit( (word >> i) & 1 ); + else + for ( int i = (len-1) ; i >= 0 ; i-- ) + this->take_bit( (word >> i) & 1 ); + + } + + //! Add a string to the CRC computation. + //! @param data + //! The string to be added. + CRCState update( string data ) + { + int len = String.width( data ); + foreach( data/"", string data) + take_word( data[0] , len); + return this; + } + + string hash( string data ) + { + this->update( data ); + return this->digest(); + } + + //! Returns the computed CRC value with xormask applied. + string digest(void|int length) + { + string format; + + if(length) + format = sprintf("%%0%dX",length); + else + format = "%X"; + return sprintf(format,value ^ xormask); + } +} + + +
