Enhancements and inclusion of some suggestions via PR #1338.

pull/1338/head
Kieran R. Prasch 2019-09-23 20:07:27 -07:00
parent 3f31f3a4c7
commit ff1358ffe5
1 changed files with 91 additions and 45 deletions

View File

@ -1,106 +1,143 @@
# NuCypher Quickstart # NuCypher Quickstart
## A Note about Side-Channels ## A Note about Side Channels
The NuCypher network does not store or handle an application's data; instead - it manages access *to* application data The NuCypher network does not store or handle an application's data; instead - it manages access *to* application data.
Management of encrypted secrets and public keys tends to be highly domain-specific. In other words, the surrounding architecture will vary greatly depending on the throughput, sensitivity and sharing cadence of the data in question, to name but a few influencing factors. Management of encrypted secrets and public keys tends to be highly domain-specific - The surrounding architecture
In all cases however, NuCypher must be integrated with a storage and transport layer in order to function properly. will vary greatly depending on the throughput, sensitivity, and sharing cadence of application secrets.
Along with the transport of ciphertexts, the application also needs to include In all cases, NuCypher must be integrated with a storage and transport layer in order to function properly.
facilities for several other pieces of cryptographic material, specifically, channels Along with the transport of ciphertexts, a nucypher application also needs to include channels for Alice and Bob
for Alice and Bob to discover each other's public keys, as well as a way to provide the policy's public key to discover each other's public keys, and provide policy encrypting information to Bob and Enrico.
to Bob and Enrico.
##### Side Channel Data: ##### Side Channel Data:
- Secrets: - Secrets:
- Message Kits (Ciphertext) - Message Kits (Ciphertext)
- Labels
- Identities: - Identities:
- Alice Verifying Key - Alice Verifying Key
- Bob Encrypting Key - Bob Encrypting Key
- Bob Verifying Key - Bob Verifying Key
- Policies: - Policies:
- Policy Encrypting Key - Policy Encrypting Key
- Labels
## Running an Ethereum Node
## Connecting to the NuCypher Network Operation of a decentralized NuCypher character [`Alice`, `Bob`, `Ursula`] requires
a connection to an Ethereum node and wallet.
### Running an Ethereum Node To run a Goerli-connected Geth node in *fast* syncing mode:
Operation of NuCypher cryptological characters [`Alice`, `Bob`, `Ursula`] requires
a running Ethereum node and wallet (we recommend Geth).
To run a Goerli connected Geth node:
```bash ```bash
$ geth --goerl $ geth --goerl
``` ```
To run a Goerli-connected Geth node in *light* syncing mode:
```bash
$ geth --goerl --syncmode light
```
Note that using `--syncmode light` is not 100% stable but can be a life savior when using
a mobile connection (or congested hackathon wifi...).
### Provider URI ### Provider URI
Nucypher uses the node's IPC-File to communicate, specified by `provider_uri`. Nucypher uses the node's IPC-File to communicate, specified by `provider_uri`.
By default in ubuntu, the path is `~/.ethereum/goerli/geth.ipc` - This path By default in ubuntu, the path is `~/.ethereum/goerli/geth.ipc` - This path
will also be logged to the geth-running console on startup. will also be logged to the geth-running console on startup.
Connect to the Geth Console to test your ethereum node's IPC:
```bash
$ geth attach ~/.ethereum/goerli/geth.ipc
```
### Wallets
To list available accounts on your geth node:
```bash
$ geth attach ~/.ethereum/goerli/geth.ipc
> eth.accounts
["0x287a817426dd1ae78ea23e9918e2273b6733a43d", "0xc080708026a3a280894365efd51bb64521c45147"]
```
Hardware wallet addresses will also be listed here if one is attached to the system hardware.
Note that the Geth console does not return EIP-55 compliant checksum addresses, and instead will output
the *lowercase* version of the address. Since Nucypher requires EIP-55 checksum addresses, you will need
to convert your address to checksum format:
```bash
> web3.toChecksumAddress(eth.accounts[0])
"0x287A817426DD1AE78ea23e9918e2273b6733a43D"
```
## Connecting to The NuCypher Network
### Connecting Nucypher to an Ethereum Provider
```python
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
BlockchainInterfaceFactory.initialize_interface(provider_uri='~/.ethereum/goerli/geth.ipc')
```
### Ursula: Untrusted Re-Encryption Proxies ### Ursula: Untrusted Re-Encryption Proxies
When initializing an `Alice`, `Bob`, or `Ursula`, an initial "Stranger-`Ursula`" is needed to perform When initializing an `Alice`, `Bob`, or `Ursula`, an initial "Stranger-`Ursula`" is needed to perform
the role of a `Teacher`, or "seednode". The `known_nodes` will inform your character of all of the nodes the role of a `Teacher`, or "seednode":
they know about network-wide, then kick-off the automated node-discovery loop.
Stranger `Ursula`s can be created by invoking the `from_seed_and_stake_info` method, then a `list` of `known_nodes`
can be passed into any `Character`'s init:
```python ```python
from nucypher.characters.lawful import Ursula, Alice from nucypher.characters.lawful import Ursula, Alice
ursula = Ursula.from_seed_and_stake_info(seed_uri=<URI>) # ie. https://0.0.0.0:9151 ursula = Ursula.from_seed_and_stake_info(seed_uri=<URI>, federated_only=False) # ie. https://0.0.0.0:9151
another_ursula = Ursula.from_seed_and_stake_info(seed_uri=<URI>) another_ursula = Ursula.from_seed_and_stake_info(seed_uri=<URI>, federated_only=False)
```
alice = Alice(checksum_address='0xdeadbeef', Stranger `Ursula`s can be created by invoking the `from_seed_and_stake_info` method, then a `list` of `known_nodes`
provider_uri=<PROVIDER URI>, can be passed into any `Character`'s init. The `known_nodes` will inform your character of all of the nodes
known_nodes=[ursula, another_ursula]) they know about network-wide, then kick-off the automated node-discovery loop:
```python
alice = Alice(known_nodes=[ursula, another_ursula], ...)
``` ```
## Alice: Grant Access to a Secret ## Alice: Grant Access to a Secret
```python ```python
from nucypher.characters.lawful import Alice, Bob, Ursula from nucypher.characters.lawful import Alice, Bob, Ursula
from nucypher.network.middleware import RestMiddleware
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
# Application Side-Channel # Application Side-Channel
# -------------------------- # --------------------------
# bob_encrypting_key = <Side Channel> # bob_encrypting_key = <Side Channel>
# bob_verifying_key = <Side Channel> # bob_verifying_key = <Side Channel>
ursula = Ursula.from_seed_and_stake_info(seed_uri='https://0.0.0.0:9151') ursula = Ursula.from_seed_and_stake_info(seed_uri='https://0.0.0.0:9151', federated_only=False)
alice = Alice(checksum_address='0xdeadbeef', alice = Alice(known_nodes=[ursula],
provider_uri=<PROVIDER URI>, checksum_address="0x287A817426DD1AE78ea23e9918e2273b6733a43D",
known_nodes=[ursula]) registry=InMemoryContractRegistry.from_latest_publication(),
network_middleware=RestMiddleware())
bob = Bob.from_public_keys(verifying_key=bob_verifying_key, encrypting_key=bob_encrypting_key) bob = Bob.from_public_keys(verifying_key=bob_verifying_key, encrypting_key=bob_encrypting_key)
``` ```
```python ```python
from datetime import datetime, timedelta from datetime import datetime
import maya
# #
# Grant # Grant
# #
expiration = datetime.now() + timedelta(days=5) # Five days from now. policy_end_datetime = maya.now() + datetime.timedelta(days=5) # Five days from now
policy = alice.grant(bob, policy = alice.grant(bob,
label=b'my-secret-stuff', label=b'my-secret-stuff',
m=2, n=3, m=2, n=3,
expiration=expiration) expiration=policy_end_datetime)
policy_encrypting_key = policy.public_key policy_encrypting_key = policy.public_key
``` ```
Note that Alice can get the public key even before creating the policy.
From this moment on, any Data Source (Enrico) that knows the public key
can encrypt data originally intended for Alice, but can be shared with
any Bob that Alice grants access.
`policy_pubkey = alice.get_policy_encrypting_key_from_label(label)`
## Enrico: Encrypt a Secret ## Enrico: Encrypt a Secret
```python ```python
@ -111,15 +148,23 @@ from nucypher.characters.lawful import Enrico
# policy_encrypting_key = <Side Channel> # policy_encrypting_key = <Side Channel>
enrico = Enrico(policy_encrypting_key=policy_encrypting_key) enrico = Enrico(policy_encrypting_key=policy_encrypting_key)
ciphertext = enrico.encrypt_message(message=b'Peace at dawn.') ciphertext, signature = enrico.encrypt_message(message=b'Peace at dawn.')
``` ```
Note that Alice can get the public key even before creating the policy.
From this moment on, any Data Source (Enrico) that knows the public key
can encrypt data originally intended for Alice, but can be shared with
any Bob that Alice grants access.
`policy_pubkey = alice.get_policy_encrypting_key_from_label(label)`
## Bob: Decrypt a Secret ## Bob: Decrypt a Secret
```python ```python
from nucypher.characters.lawful import Alice, Bob, Enrico, Ursula from nucypher.characters.lawful import Alice, Bob, Enrico, Ursula
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
from nucypher.network.middleware import RestMiddleware
# Application Side-Channel # Application Side-Channel
# -------------------------- # --------------------------
@ -129,11 +174,12 @@ from nucypher.characters.lawful import Alice, Bob, Enrico, Ursula
# alice_verifying_key = <Side Channel> # alice_verifying_key = <Side Channel>
# Everyone! # Everyone!
ursula = Ursula.from_seed_and_stake_info(seed_uri='https://0.0.0.0:9151') ursula = Ursula.from_seed_and_stake_info(seed_uri='https://0.0.0.0:9151', federated_only=False)
alice = Alice.from_public_keys(verifying_key=alice_verifying_key) alice = Alice.from_public_keys(verifying_key=alice_verifying_key)
bob = Bob(checksum_address='0xdeadbeef', bob = Bob(known_nodes=[ursula],
provider_uri=<PROVIDER URI>, checksum_address="0xc080708026a3a280894365efd51bb64521c45147",
known_nodes=[ursula]) registry=InMemoryContractRegistry.from_latest_publication(),
network_middleware=RestMiddleware())
enrico = Enrico(policy_encrypting_key=policy_encrypting_key) enrico = Enrico(policy_encrypting_key=policy_encrypting_key)
``` ```