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 provide SECP256K1 as a default because it is the basis for a number of crypto-blockchain projects;
we don't otherwise endorse its security. we don't otherwise endorse its security.
.. testsetup::
from umbral import config, keys
from cryptography.hazmat.primitives.asymmetric import ec
Setting a default curve Setting a default curve
-------------------------- --------------------------
Before you perform any ECC operations, you can set 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 .. code-block:: python
from umbral import config >>> from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric import ec >>> config.set_default_curve(ec.SECP256K1)
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 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. operation. This causes a small one-time performance penalty.
.. doctest:: .. code-block:: python
>>> config._CONFIG.___CONFIG__curve = None
>>> config._CONFIG.___CONFIG__params = None >>> from umbral import keys
>>> keys.UmbralPrivateKey.gen_key() >>> 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().
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 .. 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() >>> config.set_default_curve()
.. code-block:: python
config.set_default_curve()
Attempting to set the default curve twice in the same runtime will raise Attempting to set the default curve twice in the same runtime will raise
a `UmbralConfigurationError`. a `UmbralConfigurationError`.
.. doctest:: .. code-block:: python
>>> config._CONFIG.___CONFIG__curve = None
>>> config._CONFIG.___CONFIG__params = None >>> from umbral import config
>>> config.set_default_curve() >>> config.set_default_curve()
>>> config.set_default_curve() >>> config.set_default_curve()
Traceback (most recent call last): Traceback (most recent call last):
... ...
umbral.config._CONFIG.UmbralConfigurationError: umbral.config._CONFIG.UmbralConfigurationError
.. code-block:: python
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.

View File

@ -6,17 +6,18 @@ Using pyUmbral
Import umbral modules Import umbral modules
.. testsetup:: .. testsetup:: capsule_story
import sys import sys
import os import os
sys.path.append(os.path.abspath(os.getcwd()))
sys.path.append(os.path.abspath(os.getcwd()))
from umbral import pre, keys, config, signing
.. code-block:: python .. testcleanup:: capsule_story
from umbral import pre, keys, config, signing from umbral import config
config._CONFIG.___CONFIG__curve = None
config._CONFIG.___CONFIG__params = None
Configuration 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. 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 .. doctest:: capsule_story
>>> config._CONFIG.___CONFIG__params = None
>>> from umbral import config
>>> from cryptography.hazmat.primitives.asymmetric import ec >>> from cryptography.hazmat.primitives.asymmetric import ec
>>> config.set_default_curve(ec.SECP256K1) >>> 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`. 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: First, Let's generate two asymmetric key pairs for Alice:
A delegating key pair and a Signing key pair. 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_private_key = keys.UmbralPrivateKey.gen_key()
>>> alices_public_key = alices_private_key.get_pubkey() >>> 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_verifying_key = alices_signing_key.get_pubkey()
>>> alices_signer = signing.Signer(private_key=alices_signing_key) >>> 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 Encrypt with a public key
-------------------------- --------------------------
@ -78,31 +68,22 @@ and a `capsule`, Anyone with Alice's public key can perform
this operation. this operation.
.. doctest:: .. doctest:: capsule_story
>>> from umbral import pre
>>> plaintext = b'Proxy Re-encryption is cool!' >>> plaintext = b'Proxy Re-encryption is cool!'
>>> ciphertext, capsule = pre.encrypt(alices_public_key, plaintext) >>> 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 Decrypt with a private key
--------------------------- ---------------------------
Since data was encrypted with Alice's public key, Since data was encrypted with Alice's public key,
Alice can open the capsule and decrypt the ciphertext with her private 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) >>> 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 Threshold split-key re-encryption
================================== ==================================
@ -110,19 +91,13 @@ Threshold split-key re-encryption
Bob Exists Bob Exists
----------- -----------
.. doctest:: .. doctest:: capsule_story
>>> from umbral import keys
>>> bobs_private_key = keys.UmbralPrivateKey.gen_key() >>> bobs_private_key = keys.UmbralPrivateKey.gen_key()
>>> bobs_public_key = bobs_private_key.get_pubkey() >>> 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 Alice grants access to Bob by generating kfrags
----------------------------------------------- -----------------------------------------------
When Alice wants to grant Bob access to open her encrypted messages, 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. | `threshold` - Minimum threshold of key fragments needed to activate a capsule.
| `N` - Total number of key fragments to generate. | `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 Bob receives a capsule
----------------------- -----------------------
Next, let's generate a key pair for Bob, and pretend to send 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, 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. 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): Traceback (most recent call last):
... ...
cryptography.exceptions.InvalidTag 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 Ursulas perform re-encryption
------------------------------ ------------------------------
Bob asks several Ursulas to re-encrypt the capsule so he can open it. 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. Bob must gather at least `threshold` `cfrags` in order to activate the capsule.
.. doctest:: .. doctest:: capsule_story
>>> import random >>> 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: >>> for kfrag in kfrags:
... cfrag = pre.reencrypt(kfrag=kfrag, capsule=capsule) ... 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 >>> 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 cfrags to the capsule
---------------------------------- ----------------------------------
Bob attaches at least `threshold` `cfrags` to the capsule; Bob attaches at least `threshold` `cfrags` to the capsule;
Then it can become *activated*. Then it can become *activated*.
.. doctest:: .. doctest:: capsule_story
>>> capsule.set_correctness_keys(delegating=alices_public_key, receiving=bobs_public_key, verifying=alices_verifying_key)
>>> capsule.set_correctness_keys(delegating=alices_public_key,
... receiving=bobs_public_key,
... verifying=alices_verifying_key)
(True, True, True) (True, True, True)
>>> for cfrag in cfrags: >>> for cfrag in cfrags:
... capsule.attach_cfrag(cfrag) ... 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 Bob activates and opens the capsule
------------------------------------ ------------------------------------
Finally, Bob activates and opens the capsule, Finally, Bob activates and opens the capsule,
then decrypts the re-encrypted ciphertext. 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) >>> cleartext = pre.decrypt(ciphertext=ciphertext, capsule=capsule, decrypting_key=bobs_private_key)
.. doctest:: capsule_story
:hide:
>>> assert cleartext == plaintext >>> assert cleartext == plaintext
.. code-block:: python
cleartext = pre.decrypt(ciphertext=ciphertext,
capsule=capsule,
decrypting_key=bobs_private_key)