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