Next: , Previous: crypto blowfish, Up: crypto


2.3.4 Cyclic Redundancy Codes

The (weinholt crypto crc) library exports syntax for defining procedures that calculate CRCs. There is a simple syntax that simply requires the name of the CRC, and an advanced syntax that can define new CRCs.

CRCs do not really qualify as cryptography, because it is trivial to modify data so that the modified data's CRC matches the old one.

— Syntax: define-crc name

This is the simple interface that requires merely the name of the CRC algorithm. The pre-defined CRCs that can be used this way are currently: crc-32, crc-16, crc-16/ccitt, crc-32c, crc-24, crc-64 (CRC-64-ISO), and crc-64/ecma-182.

          (import (weinholt crypto crc))
          (define-crc crc-32)
— Syntax: define-crc name width polynomial init ref-in ref-out xor-out check

For details on how the arguments work, and the theory behind them, see Ross N. Williams's paper A painless guide to CRC error detection algorithms, which is available at http://www.ross.net/crc/crcpaper.html. A brief description of the arguments follows.

The width is the bitwise length of the polynomial. You might be led to believe that it should sometimes be 33, but if so you've been counting the highest bit, which doesn't count.

The polynomial for CRC-16 is sometimes given as x^16 + x^15 + x^2 + 1. This translates to #b1000000000000101 (#x8005). Notice that x^16 is absent. Don't use the reversed polynomial if you have one of those, instead set ref-in and ref-out properly.

After a CRC has been calculated it is sometimes xor'd with a final value, this is xor-out.

check is either #f or the CRC of the string "123456789".

— Syntax: define-crc name (coefficients ...) init ref-in ref-out xor-out check

This is a slightly easier version of the advanced interface where you can simply specify the powers of the coefficients. CRC-16 in this syntax becomes:

          (import (weinholt crypto crc))
          (define-crc crc-16 (16 15 2 0) #x0000 #t #t #x0000 #xBB3D)
          ==>
          (begin
            (define (crc-16 bv)
              (crc-16-finish (crc-16-update (crc-16-init) bv)))
            (define (crc-16-init) #x0000)
            (define (crc-16-finish r) (bitwise-xor r #x0000))
            (define (crc-16-self-test)
              (if #xBB3D
                  (if (= (crc-16 (string->utf8 "123456789")) #xBB3D)
                      'success 'failure)
                  'no-self-test))
            ...)

Another example: the polynomial x^8 + x^2 + x + 1 in this syntax is (8 2 1 0).

After e.g. (define-crc crc-32) has been used, these bindings will be available (with names that match the name of the CRC):

— Procedure: crc-32 bytevector

Calculates the final CRC of the entire bytevector and returns it as an integer.

          (import (weinholt crypto crc))
          (define-crc crc-32)
          (crc-32 (string->utf8 "A fiendish scheme"))
          ⇒ 1384349758
— Procedure: crc-32-init

Returns an initial CRC state.

— Procedure: crc-32-update state bv [start end]

Uses the state and returns a new state that includes the CRC of the given bytes.

          (import (weinholt crypto crc))
          (define-crc crc-32)
          (crc-32-finish
           (crc-32-update (crc-32-init)
                          (string->utf8 "A fiendish scheme")))
          ⇒ 1384349758
— Procedure: crc-32-finish state

Finalizes the CRC state.

— Procedure: crc-32-width

Returns the bit-width of the CRC, e.g. 32 for CRC-32.

— Procedure: crc-32-self-test

Performs a sanity check and returns either success, failure or no-self-test.

Version history: