Brandon schrieb:
> a plug in just to read a bit of documentation which could have been done
> in HTML.
for minimalists (no browser ;-))):
INTEL was able to write the datasheet for the i386 in plain-text
(IBM-codepage 437 -- ascii-graphic); so i should be able to reformat
the crypto-papaer in plaintext.
-------------- next part --------------

        F R E E |\| E '|'    ( R Y P '|' () G R A P |-| | (    |_ AYER

        --=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
        Adam Langley, agl at linuxpower.org
        and
        Scott Miller, scgmille at indiana.edu
        --=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--
        FREENET CRYPTOGRAPHIC LAYER as posted in freenet-dev
        Sat, 13 May 2000 21:30:39 +0000 by Adam Langley
        --=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--=--

        Key Exchange
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          The key exchange system is temporary. Scott and Oskar expect
        to switch to a full public-private key system at a later date.
          The current key exchange system is Diffie-Hellman (Applied
        Cryptography, Chapter 22). The following is quoted from
        Applied Cryptography.

                The math is simple. First, Alice and Bob agree on a
              large prime, n and g such that g is primitive mod n.
              These two integers don't have to be secret; Alice and
              Bob can agree to them over some insecure channel. They
              can even be common among a group of users. It doesn't
              matter.
                Then, the protocol goes as follows:

                 (1) Alice chooses a random large integer x
                     and sends Bob
                             X = gx mod n
                 (2) Bob chooses a random large integer y
                     and sends Alice
                             Y = gy mod n
                 (3) Alice computes
                             k = Y x mod n
                 (4) Bob computes
                             k  = Xy mod n

                Both k and k  are equal to gxy mod n. No one listening
                on the channel can compute that value; they only know
                n, g, X and Y . Unless they can compute the discrete
                logarithm and recover x or y, they do not solve the
                problem. So, k is the secret key that both Alice and
                Bob computed independently.


          Freenet uses a fixed 1024 bit n, it's an IPSec standard prime:
                FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
                29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
                EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
                E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
                EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
                FFFFFFFF FFFFFFFF

          The generator (g) is 2. When sending or hashing etc MPI
        (multi-precision-integers) are defined the same way the
        OpenPGP spec does.


        MPIs
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          Multi-Precision Integers (also called MPIs) are unsigned
        integers used to hold large integers such as the ones used in
        cryptographic calculations.
          An MPI consists of two pieces: a two-octet scalar that is
        the length of the MPI in bits followed by a string of octets
        that contain the actual integer.
          These octets form a big-endian number; a big-endian number
        can be made into an MPI by prefixing it with the appropriate
        length. Examples:

          The string of octets [00 01 01] forms an MPI with the value
        1. The string [00 09 01 FF] forms an MPI with the value of
        511. The size of an MPI is ((MPI.length + 7) / 8) + 2 octets.
        The length field of an MPI describes the length starting from
        its most significant non-zero bit. Thus, the MPI [00 02 01]
        is not formed correctly. It should be [00 01 01].


        Block Cipher Key Generation
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          Hash (using SHA1) e and k (where k is in MPI format). In
        this e is an array consisting of m octets of 0x00, initially
        m = 1. Each hash generates 20 octets of key data. The length
        of the key depends of the block cipher used (currently
        Twofish). To generate more key data, increment m, regenerate
        e and hash again. For example:

                Hash [0 k] for the first 20 key bytes
                  (e = [0] because m = 1)

                Hash [0 0 k] for the next 20 bytes (m = 2)

                Hash [0 0 0 k] for the next 20 bytes (m = 3)

          Now both sides have the shared key we switch to sending data
        with the block cipher in PCFB mode.


        PCFB Mode
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          PCFB mode is Periodic Cipher Feedback Mode. Each direction
        is treated as a different object. The code is the same but you
        have one set of data for receiving and one for transmitting.
        The text below describes one side only, and remember this
        happens on both ends. The advantage of PCFB is that you can
        send a single byte at a time.
          A feedback register is setup, a[]. In the Java code it is
        named feedback register[]. The register is equal to the
        cipher's block size. Fill a[] with random bytes and transmit
        those random bytes to the peer. That's the initialization
        vector (IV). The peer puts that data into its a[], then both
        sides encrypt a[], replacing its contents with the newly
        encrypted data.
          To transmit a byte, XOR it with a byte from a[] and also
        replace the byte in a[] with the cipher-byte. To fill a
        transmit buffer t[] from a plain text buffer p[] do:

          for (i = 0; i < BLOCKSIZE; i++) t[i] = a[i] = p[i] XOR a[i];

          The peer can now decrypt t[] by XORing it with a[], the peer
        also replaces a[] with t[]. In other words, both ends put the
        encrypted byte in the feedback register, a[]). Both sides need
        to keep a pointer (i in the code above) telling where in the
        register you are.
          Once you have transmitted a block worth of bytes you need to
        re-encrypt the register. To do so, encrypt a[] to get the new
        a[]. Note that this uses the block cipher in encryption mode
        for both encryption and decryption. You then continue with the
        re-encrypted a[].


        PCFB Summary
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

         Sending
         ~~~~~~~

            1 Create a buffer, called the feedback register that is
              equal to the block-size of the symmetric cipher used
              with PCFB mode.

            2 Create a random initialization vector, IV, and transmit
              it to the peer, then encrypt it with the block-cipher
              and store the results in the feedback register.

            3 To transmit a byte, XOR the plaintext byte with a byte
              from the feedback register, then place the resulting
              byte back in the feedback register in place of the byte
              used in XOR.

            4 Transmit the byte.

            5 When every byte in the buffer has been used (and
              replaced by the corresponding cipher byte), encrypt the
              feedback register, yielding a new register to use for
              transmission.


         Receiving
         ~~~~~~~~~

            1 Receive the initialization vector from the peer, encrypt
              it, and place the results in the feedback register.

            2 When a ciphertext byte is received from the peer, XOR it
              with a byte from the feedback register to form a
              plaintext byte. Place the ciphertext byte back in the
              feedback register.

            3 When the entire feedback register has been used, encrypt
              it using the block cipher and place the results in the
              feedback register, yielding a new register to use for
              reception.


         Mathematically
         ~~~~~~~~~~~~~~   

            * Initialization vector: IV
            * Feedback register: R
            * Ciphertext byte: C
            * Plaintext byte: P
            * Block-cipher k, with block size n

          do the following:

                R = Ek(IV )
                Then, repeat for 0   i < n, encryption:
                Ri = Ci = Pi   Ri, and for decryption
                Pi = Ci   Ri, Ri = Ci
                When i = n, R = Ek(R), i = 0

Reply via email to