I've incorporated lots from Scott and this is an updated version of the crypto 
paper. It's at http://freenet.sourceforge.net/fncrypto.pdf

Again pdftotext output included below (but you really should read the PDF)

Freenet Cryptographic Layer
Adam Langley, agl at linuxpower.org and Scott Miller, scgmille at indiana.edu



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:

                                                      1


    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.

                                                        2


      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

AGL

-- 
Whenever anyone says, "theoretically," they really mean, "not really."
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 240 bytes
Desc: not available
URL: 
<https://emu.freenetproject.org/pipermail/devl/attachments/20000513/eee2b2a5/attachment.pgp>

Reply via email to