Skip to content

Commit d92b667

Browse files
committed
More documentation
1 parent 5d646ad commit d92b667

8 files changed

Lines changed: 182 additions & 68 deletions

File tree

doc/compatibility.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ through the ``pyrsa-priv2pub`` command::
4242
--out=OUTFILENAME Output filename. Writes to stdout of not specified
4343
--inform=INFORM key format of input - default PEM
4444
--outform=OUTFORM key format of output - default PEM
45+

doc/conf.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
# Add any Sphinx extension module names here, as strings. They can be extensions
2727
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
2828
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo',
29-
'sphinx.ext.coverage', 'sphinx.ext.viewcode', 'sphinx.ext.pngmath']
29+
'sphinx.ext.coverage', 'sphinx.ext.pngmath']
30+
31+
# I would like to add 'sphinx.ext.viewcode', but it causes a UnicodeDecodeError
3032

3133
# Add any paths that contain templates here, relative to this directory.
3234
templates_path = ['_templates']
@@ -35,7 +37,7 @@
3537
source_suffix = '.rst'
3638

3739
# The encoding of source files.
38-
#source_encoding = 'utf-8-sig'
40+
source_encoding = 'utf-8'
3941

4042
# The master toctree document.
4143
master_doc = 'index'

doc/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Contents
3939
licence
4040
usage
4141
compatibility
42+
reference
4243

4344

4445
Indices and tables

doc/intro.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ numbers. It also included generating public and private keys. There
1414
was no functionality for working with byte sequences (such as files)
1515
yet.
1616

17-
.. TODO:: write more history
17+
.. todo:: write more history
1818

1919

doc/reference.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Reference
2+
==================================================
3+
4+
Functions
5+
--------------------------------------------------
6+
7+
.. autofunction:: rsa.encrypt
8+
9+
.. autofunction:: rsa.decrypt
10+
11+
.. autofunction:: rsa.sign
12+
13+
.. autofunction:: rsa.verify
14+
15+
.. autofunction:: rsa.newkeys(keysize)
16+
17+
Classes
18+
--------------------------------------------------
19+
20+
.. autoclass:: rsa.PublicKey
21+
:members:
22+
:inherited-members:
23+
24+
.. autoclass:: rsa.PrivateKey
25+
:members:
26+
:inherited-members:
27+
28+
29+

doc/usage.rst

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ Usage
33

44
This section describes the usage of the Python-RSA module.
55

6-
7-
Generating keys
8-
--------------------------------------------------
9-
106
Before you can use RSA you need keys. You will receive a private key
117
and a public key.
128

@@ -15,10 +11,86 @@ and a public key.
1511
The private key is called *private* for a reason. Never share this
1612
key with anyone.
1713

14+
The public key is used for encypting a message such that it can only
15+
be read by the owner of the private key. As such it's also referred to
16+
as the *encryption key*. Decrypting a message can only be done using
17+
the private key, hence it's also called the *decryption key*.
18+
19+
The private key is used for signing a message. With this signature and
20+
the public key, the receiver can verifying that a message was signed
21+
by the owner of the private key, and that the message was not modified
22+
after signing.
23+
24+
Generating keys
25+
--------------------------------------------------
26+
27+
You can use the :py:func:`rsa.newkeys` function to create a keypair.
28+
Alternatively you can use :py:func:`rsa.PrivateKey.load_pkcs1` and
29+
:py:func:`rsa.PublicKey.load_pkcs1` to load keys from a file.
30+
31+
Generating a keypair may take a long time, depending on the number of
32+
bits required. The number of bits determines the cryptographic
33+
strength of the key, as well as the size of the message you can
34+
encrypt. If you don't mind having a slightly smaller key than you
35+
requested, you can pass ``accurate=False`` to speed up the key
36+
generation process.
37+
38+
These are some timings from my netbook (Linux 2.6, 1.6 GHz Intel Atom
39+
N270 CPU, 2 GB RAM):
40+
41+
+----------------+------------------+
42+
| Keysize (bits) | Time to generate |
43+
+================+==================+
44+
| 32 | 0.01 sec. |
45+
+----------------+------------------+
46+
| 64 | 0.03 sec. |
47+
+----------------+------------------+
48+
| 96 | 0.04 sec. |
49+
+----------------+------------------+
50+
| 128 | 0.08 sec. |
51+
+----------------+------------------+
52+
| 256 | 0.27 sec. |
53+
+----------------+------------------+
54+
| 384 | 0.93 sec. |
55+
+----------------+------------------+
56+
| 512 | 1.21 sec. |
57+
+----------------+------------------+
58+
| 1024 | 7.93 sec. |
59+
+----------------+------------------+
60+
| 2048 | 132.97 sec. |
61+
+----------------+------------------+
62+
1863

1964
Encryption and decryption
2065
--------------------------------------------------
2166

67+
To encrypt or decrypt a message, use :py:func:`rsa.encrypt` resp.
68+
:py:func:`rsa.decrypt`. Let's say that Alice wants to send a message
69+
that only Bob can read.
70+
71+
#. Bob generates a keypair, and gives the public key to Alice. This is
72+
done such that Alice knows for sure that the key is really Bob's
73+
(for example by handing over a USB stick that contains the key).
74+
75+
#. Alice writes a message
76+
77+
#. Alice encrypts the message using Bob's public key, and sends the
78+
encrypted message.
79+
80+
#. Bob receives the message, and decrypts it with his private key.
81+
82+
Since Bob kept his private key *private*, Alice can be sure that he is
83+
the only one who can read the message. Bob does *not* know for sure
84+
that it was Alice that sent the message, since she didn't sign it.
85+
86+
87+
Low-level operations
88+
++++++++++++++++++++++++++++++
89+
90+
The core RSA algorithm operates on large integers. These operations
91+
are considered low-level and are supported by the
92+
:py:func:`rsa.core.encrypt_int` and :py:func:`rsa.core.decrypt_int`
93+
functions.
2294

2395
Signing and verification
2496
--------------------------------------------------

rsa/key.py

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,17 @@ class AbstractKey(object):
4141
def load_pkcs1(cls, keyfile, format='PEM'):
4242
r'''Loads a key in PKCS#1 DER or PEM format.
4343
44-
@param keyfile: contents of a DER- or PEM-encoded file that contains
44+
:param keyfile: contents of a DER- or PEM-encoded file that contains
4545
the public key.
46-
@param format: the format of the file to load; 'PEM' or 'DER'
47-
@return: a PublicKey object
46+
:param format: the format of the file to load; 'PEM' or 'DER'
47+
48+
:return: a PublicKey object
49+
4850
'''
4951

5052
methods = {
51-
'PEM': cls.load_pkcs1_pem,
52-
'DER': cls.load_pkcs1_der,
53+
'PEM': cls._load_pkcs1_pem,
54+
'DER': cls._load_pkcs1_der,
5355
}
5456

5557
if format not in methods:
@@ -63,13 +65,14 @@ def load_pkcs1(cls, keyfile, format='PEM'):
6365
def save_pkcs1(self, format='PEM'):
6466
'''Saves the public key in PKCS#1 DER or PEM format.
6567
66-
@param format: the format to save; 'PEM' or 'DER'
67-
@returns: the DER- or PEM-encoded public key.
68+
:param format: the format to save; 'PEM' or 'DER'
69+
:returns: the DER- or PEM-encoded public key.
70+
6871
'''
6972

7073
methods = {
71-
'PEM': self.save_pkcs1_pem,
72-
'DER': self.save_pkcs1_der,
74+
'PEM': self._save_pkcs1_pem,
75+
'DER': self._save_pkcs1_der,
7376
}
7477

7578
if format not in methods:
@@ -86,7 +89,8 @@ class PublicKey(AbstractKey):
8689
This key is also known as the 'encryption key'. It contains the 'n' and 'e'
8790
values.
8891
89-
Supports attributes as well as dictionary-like access.
92+
Supports attributes as well as dictionary-like access. Attribute accesss is
93+
faster, though.
9094
9195
>>> PublicKey(5, 3)
9296
PublicKey(5, 3)
@@ -128,7 +132,7 @@ def __ne__(self, other):
128132
return not (self == other)
129133

130134
@classmethod
131-
def load_pkcs1_der(cls, keyfile):
135+
def _load_pkcs1_der(cls, keyfile):
132136
r'''Loads a key in PKCS#1 DER format.
133137
134138
@param keyfile: contents of a DER-encoded file that contains the public
@@ -160,7 +164,7 @@ def load_pkcs1_der(cls, keyfile):
160164
as_ints = tuple(int(x) for x in priv)
161165
return cls(*as_ints)
162166

163-
def save_pkcs1_der(self):
167+
def _save_pkcs1_der(self):
164168
'''Saves the public key in PKCS#1 DER format.
165169
166170
@returns: the DER-encoded public key.
@@ -183,7 +187,7 @@ class AsnPubKey(univ.Sequence):
183187
return encoder.encode(asn_key)
184188

185189
@classmethod
186-
def load_pkcs1_pem(cls, keyfile):
190+
def _load_pkcs1_pem(cls, keyfile):
187191
'''Loads a PKCS#1 PEM-encoded public key file.
188192
189193
The contents of the file before the "-----BEGIN RSA PUBLIC KEY-----" and
@@ -197,7 +201,7 @@ def load_pkcs1_pem(cls, keyfile):
197201
der = rsa.pem.load_pem(keyfile, 'RSA PUBLIC KEY')
198202
return cls.load_pkcs1_der(der)
199203

200-
def save_pkcs1_pem(self):
204+
def _save_pkcs1_pem(self):
201205
'''Saves a PKCS#1 PEM-encoded public key file.
202206
203207
@return: contents of a PEM-encoded file that contains the public key.
@@ -212,7 +216,8 @@ class PrivateKey(AbstractKey):
212216
This key is also known as the 'decryption key'. It contains the 'n', 'e',
213217
'd', 'p', 'q' and other values.
214218
215-
Supports attributes as well as dictionary-like access.
219+
Supports attributes as well as dictionary-like access. Attribute accesss is
220+
faster, though.
216221
217222
>>> PrivateKey(3247, 65537, 833, 191, 17)
218223
PrivateKey(3247, 65537, 833, 191, 17)
@@ -290,7 +295,7 @@ def __ne__(self, other):
290295
return not (self == other)
291296

292297
@classmethod
293-
def load_pkcs1_der(cls, keyfile):
298+
def _load_pkcs1_der(cls, keyfile):
294299
r'''Loads a key in PKCS#1 DER format.
295300
296301
@param keyfile: contents of a DER-encoded file that contains the private
@@ -334,7 +339,7 @@ def load_pkcs1_der(cls, keyfile):
334339
as_ints = tuple(int(x) for x in priv[1:9])
335340
return cls(*as_ints)
336341

337-
def save_pkcs1_der(self):
342+
def _save_pkcs1_der(self):
338343
'''Saves the private key in PKCS#1 DER format.
339344
340345
@returns: the DER-encoded private key.
@@ -371,7 +376,7 @@ class AsnPrivKey(univ.Sequence):
371376
return encoder.encode(asn_key)
372377

373378
@classmethod
374-
def load_pkcs1_pem(cls, keyfile):
379+
def _load_pkcs1_pem(cls, keyfile):
375380
'''Loads a PKCS#1 PEM-encoded private key file.
376381
377382
The contents of the file before the "-----BEGIN RSA PRIVATE KEY-----" and
@@ -385,7 +390,7 @@ def load_pkcs1_pem(cls, keyfile):
385390
der = rsa.pem.load_pem(keyfile, 'RSA PRIVATE KEY')
386391
return cls.load_pkcs1_der(der)
387392

388-
def save_pkcs1_pem(self):
393+
def _save_pkcs1_pem(self):
389394
'''Saves a PKCS#1 PEM-encoded private key file.
390395
391396
@return: contents of a PEM-encoded file that contains the private key.
@@ -535,15 +540,16 @@ def gen_keys(nbits, accurate=True):
535540
def newkeys(nbits, accurate=True):
536541
"""Generates public and private keys, and returns them as (pub, priv).
537542
538-
The public key is also known as the 'encryption key', and is a PublicKey
539-
object. The private key is also known as the 'decryption key' and is a
540-
PrivateKey object.
541-
542-
@param nbits: the number of bits required to store ``n = p*q``.
543-
@param accurate: when True, ``n`` will have exactly the number of bits you
544-
asked for. However, this makes key generation much slower.
543+
The public key is also known as the 'encryption key', and is a
544+
:py:class:`PublicKey` object. The private key is also known as the
545+
'decryption key' and is a :py:class:`PrivateKey` object.
546+
547+
:param nbits: the number of bits required to store ``n = p*q``.
548+
:param accurate: when True, ``n`` will have exactly the number of bits you
549+
asked for. However, this makes key generation much slower. When False,
550+
`n`` may have slightly less bits.
545551
546-
@return: a tuple (PublicKey, PrivateKey)
552+
:returns: a tuple (:py:class:`rsa.PublicKey`, :py:class:`rsa.PrivateKey`)
547553
548554
"""
549555

0 commit comments

Comments
 (0)