Remove duplicated doc snippets, Create test execution groups.

pull/173/head
Kieran Prasch 2018-06-28 13:48:58 -07:00
parent 6e02037dcc
commit 16dd9f16aa
2 changed files with 67 additions and 147 deletions

View File

@ -14,73 +14,47 @@ Be careful when choosing a curve - the security of your application depends on i
We provide SECP256K1 as a default because it is the basis for a number of crypto-blockchain projects;
we don't otherwise endorse its security.
.. testsetup::
from umbral import config, keys
from cryptography.hazmat.primitives.asymmetric import ec
Setting a default curve
--------------------------
Before you perform any ECC operations, you can set a default curve.
.. doctest::
>>> config._CONFIG.___CONFIG__curve = None
>>> config._CONFIG.___CONFIG__params = None
>>> config.set_default_curve(ec.SECP256K1)
.. code-block:: python
from umbral import config
from cryptography.hazmat.primitives.asymmetric import ec
config.set_default_curve(ec.SECP256K1)
>>> from cryptography.hazmat.primitives.asymmetric import ec
>>> config.set_default_curve(ec.SECP256K1)
If you don't set a default curve, then SECP256K1 will be set for you when you perform the first ECC
operation. This causes a small one-time performance penalty.
.. doctest::
>>> config._CONFIG.___CONFIG__curve = None
>>> config._CONFIG.___CONFIG__params = None
>>> keys.UmbralPrivateKey.gen_key()
RuntimeWarning: No default curve has been set. Using SECP256K1. A slight performance penalty has been incurred for only this call. Set a default curve with umbral.config.set_default_curve().
.. code-block:: python
>>> from umbral import keys
>>> private_key = keys.UmbralPrivateKey.gen_key()
RuntimeWarning: No default curve has been set. Using SECP256K1.
A slight performance penalty has been incurred for only this call.
Set a default curve with umbral.config.set_default_curve().
To use SECP256K1 and avoid this penalty, you can simply call `set_default_curve()` with no argument:
.. code-block:: python
from umbral import keys
keys.UmbralPrivateKey.gen_key()
RuntimeWarning: No default curve has been set. Using SECP256K1. A slight performance penalty has been incurred for only this call. Set a default curve with umbral.config.set_default_curve().
If you want SECP256K1 and want to avoid this penalty, you can simply call `set_default_curve()` with no argument:
.. doctest::
>>> config._CONFIG.___CONFIG__curve = None
>>> config._CONFIG.___CONFIG__params = None
>>> config.set_default_curve()
.. code-block:: python
config.set_default_curve()
Attempting to set the default curve twice in the same runtime will raise
a `UmbralConfigurationError`.
.. doctest::
>>> config._CONFIG.___CONFIG__curve = None
>>> config._CONFIG.___CONFIG__params = None
>>> config.set_default_curve()
>>> config.set_default_curve()
Traceback (most recent call last):
...
umbral.config._CONFIG.UmbralConfigurationError:
.. code-block:: python
config.set_default_curve()
>>> from umbral import config
>>> config.set_default_curve()
>>> config.set_default_curve()
Traceback (most recent call last):
...
umbral.config.UmbralConfigurationError: You can only set the default curve once. Do it once and then leave it alone.
umbral.config._CONFIG.UmbralConfigurationError

View File

@ -6,17 +6,18 @@ Using pyUmbral
Import umbral modules
.. testsetup::
.. testsetup:: capsule_story
import sys
import os
sys.path.append(os.path.abspath(os.getcwd()))
from umbral import pre, keys, config, signing
.. code-block:: python
from umbral import pre, keys, config, signing
.. testcleanup:: capsule_story
from umbral import config
config._CONFIG.___CONFIG__curve = None
config._CONFIG.___CONFIG__params = None
Configuration
@ -28,17 +29,13 @@ Setting the default curve
The best way to start using pyUmbral is to decide on a elliptic curve to use and set it as your default.
.. doctest::
>>> config._CONFIG.___CONFIG__curve = None
>>> config._CONFIG.___CONFIG__params = None
.. doctest:: capsule_story
>>> from umbral import config
>>> from cryptography.hazmat.primitives.asymmetric import ec
>>> config.set_default_curve(ec.SECP256K1)
.. code-block:: python
config.set_default_curve(ec.SECP256K1)
For more information on curves, see :doc:`choosing_and_using_curves`.
@ -51,7 +48,9 @@ Generate an Umbral key pair
First, Let's generate two asymmetric key pairs for Alice:
A delegating key pair and a Signing key pair.
.. doctest::
.. doctest:: capsule_story
>>> from umbral import keys, signing
>>> alices_private_key = keys.UmbralPrivateKey.gen_key()
>>> alices_public_key = alices_private_key.get_pubkey()
@ -60,15 +59,6 @@ A delegating key pair and a Signing key pair.
>>> alices_verifying_key = alices_signing_key.get_pubkey()
>>> alices_signer = signing.Signer(private_key=alices_signing_key)
.. code-block:: python
alices_private_key = keys.UmbralPrivateKey.gen_key()
alices_public_key = alices_private_key.get_pubkey()
alices_signing_key = keys.UmbralPrivateKey.gen_key()
alices_verifying_key = alices_signing_key.get_pubkey()
alices_signer = signing.Signer(private_key=alices_signing_key)
Encrypt with a public key
--------------------------
@ -78,31 +68,22 @@ and a `capsule`, Anyone with Alice's public key can perform
this operation.
.. doctest::
.. doctest:: capsule_story
>>> from umbral import pre
>>> plaintext = b'Proxy Re-encryption is cool!'
>>> ciphertext, capsule = pre.encrypt(alices_public_key, plaintext)
.. code-block:: python
plaintext = b'Proxy Re-encryption is cool!'
ciphertext, capsule = pre.encrypt(alices_public_key, plaintext)
Decrypt with a private key
---------------------------
Since data was encrypted with Alice's public key,
Alice can open the capsule and decrypt the ciphertext with her private key.
.. doctest::
.. doctest:: capsule_story
>>> cleartext = pre.decrypt(ciphertext=ciphertext, capsule=capsule, decrypting_key=alices_private_key)
.. code-block:: python
cleartext = pre.decrypt(ciphertext=ciphertext, capsule=capsule,
decrypting_key=alices_private_key)
Threshold split-key re-encryption
==================================
@ -110,19 +91,13 @@ Threshold split-key re-encryption
Bob Exists
-----------
.. doctest::
.. doctest:: capsule_story
>>> from umbral import keys
>>> bobs_private_key = keys.UmbralPrivateKey.gen_key()
>>> bobs_public_key = bobs_private_key.get_pubkey()
.. code-block:: python
# Generate umbral keys for Bob.
bobs_private_key = keys.UmbralPrivateKey.gen_key()
bobs_public_key = bobs_private_key.get_pubkey()
Alice grants access to Bob by generating kfrags
-----------------------------------------------
When Alice wants to grant Bob access to open her encrypted messages,
@ -133,19 +108,15 @@ which are next sent to N proxies or *Ursulas*.
| `threshold` - Minimum threshold of key fragments needed to activate a capsule.
| `N` - Total number of key fragments to generate.
.. doctest::
.. doctest:: capsule_story
>>> kfrags = pre.split_rekey(delegating_privkey=alices_private_key, signer=alices_signer, receiving_pubkey=bobs_public_key, threshold=10, N=20)
>>> kfrags = pre.split_rekey(delegating_privkey=alices_private_key,
... signer=alices_signer,
... receiving_pubkey=bobs_public_key,
... threshold=10,
... N=20)
.. code-block:: python
kfrags = pre.split_rekey(delegating_privkey=alices_private_key,
signer=alices_signer,
receiving_pubkey=bobs_public_key,
threshold=10,
N=20)
Bob receives a capsule
-----------------------
Next, let's generate a key pair for Bob, and pretend to send
@ -163,22 +134,16 @@ Bob fails to open the capsule
If Bob attempts to open a capsule that was not encrypted for his public key,
or re-encrypted for him by Ursula, he will not be able to open it.
.. doctest::
.. doctest:: capsule_story
>>> fail = pre.decrypt(ciphertext=ciphertext, capsule=capsule, decrypting_key=bobs_private_key)
>>> fail = pre.decrypt(ciphertext=ciphertext,
... capsule=capsule,
... decrypting_key=bobs_private_key)
Traceback (most recent call last):
...
cryptography.exceptions.InvalidTag
.. code-block:: python
try:
fail = pre.decrypt(ciphertext=ciphertext, capsule=capsule, decrypting_key=bobs_private_key)
except:
print("Decryption failed!")
Ursulas perform re-encryption
------------------------------
Bob asks several Ursulas to re-encrypt the capsule so he can open it.
@ -191,68 +156,49 @@ Bob collects the resulting `cfrags` from several Ursulas.
Bob must gather at least `threshold` `cfrags` in order to activate the capsule.
.. doctest::
.. doctest:: capsule_story
>>> import random
>>> kfrags = random.sample(kfrags, 10)
>>> kfrags = random.sample(kfrags, # All kfrags from above
... 10) # M - Threshold
>>> cfrags = list()
>>> cfrags = list() # Bob's cfrag collection
>>> for kfrag in kfrags:
... cfrag = pre.reencrypt(kfrag=kfrag, capsule=capsule)
... cfrags.append(cfrag)
... cfrags.append(cfrag) # Bob collects a cfrag
.. doctest:: capsule_story
:hide:
>>> assert len(cfrags) == 10
.. code-block:: python
import random
kfrags = random.sample(kfrags, # All kfrags from above
10) # M - Threshold
cfrags = list() # Bob's cfrag collection
for kfrag in kfrags:
cfrag = pre.reencrypt(kfrag=kfrag, capsule=capsule)
cfrags.append(cfrag) # Bob collects a cfrag
Bob attaches cfrags to the capsule
----------------------------------
Bob attaches at least `threshold` `cfrags` to the capsule;
Then it can become *activated*.
.. doctest::
>>> capsule.set_correctness_keys(delegating=alices_public_key, receiving=bobs_public_key, verifying=alices_verifying_key)
.. doctest:: capsule_story
>>> capsule.set_correctness_keys(delegating=alices_public_key,
... receiving=bobs_public_key,
... verifying=alices_verifying_key)
(True, True, True)
>>> for cfrag in cfrags:
... capsule.attach_cfrag(cfrag)
.. code-block:: python
capsule.set_correctness_keys(delegating=alices_public_key, receiving=bobs_public_key, verifying=alices_verifying_key)
for cfrag in cfrags:
capsule.attach_cfrag(cfrag)
Bob activates and opens the capsule
------------------------------------
Finally, Bob activates and opens the capsule,
then decrypts the re-encrypted ciphertext.
.. doctest::
.. doctest:: capsule_story
>>> capsule.set_correctness_keys(delegating=alices_public_key, receiving=bobs_public_key, verifying=alices_verifying_key)
(True, True, True)
>>> for cfrag in cfrags:
... capsule.attach_cfrag(cfrag)
>>> cleartext = pre.decrypt(ciphertext=ciphertext, capsule=capsule, decrypting_key=bobs_private_key)
.. doctest:: capsule_story
:hide:
>>> assert cleartext == plaintext
.. code-block:: python
cleartext = pre.decrypt(ciphertext=ciphertext,
capsule=capsule,
decrypting_key=bobs_private_key)