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>