Skip to content

Fixing several misuses of private/public key pairs, other corrections #61

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion asymmetric-key-ciphers/ecc-encryption-decryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

In this section we shall explain how to implement **elliptic-curve based public-key encryption / decryption** \(asymmetric encryption scheme based on ECC\). This is **non-trivial** and usually involves a design of hybrid encryption scheme, involving ECC cryptography, ECDH key exchange and symmetric encryption algorithm.

Assume we have a ECC **private-public key pair**. We want to encrypt and decrypt data using these keys. By definition, **asymmetric encryption** works as follows: if we **encrypt data by a private key**, we will be able to **decrypt** the ciphertext later by the corresponding **public key**:
Assume we have a ECC **private-public key pair**. We want to encrypt and decrypt data using these keys. By definition, **asymmetric encryption** works as follows: if we **encrypt data by a public key**, we will be able to **decrypt** the ciphertext later by the corresponding **private key**:

![](../.gitbook/assets/asymmetric-encryption-diagram.png)

Expand Down
2 changes: 1 addition & 1 deletion asymmetric-key-ciphers/ecies-public-key-encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A hybrid encryption scheme similar to the previously demonstrated code is standardized under the name **Elliptic Curve Integrated Encryption Scheme** \(**ECIES**\) in many crypto standards like [SECG SEC-1](http://www.secg.org/sec1-v2.pdf), [ISO/IEC 18033-2](https://www.shoup.net/iso/std4.pdf), [IEEE 1363a](http://grouper.ieee.org/groups/1722/contributions/2012/1722a-butterworth-ieee1363.pdf) and [ANSI X9.63](ftp://ftp.iks-jena.de/mitarb/lutz/standards/ansi/X9/x963-7-5-98.pdf). **ECIES** is a public-key authenticated encryption scheme, which works similarly to the above code examples, but uses a **KDF** \(key-derivation function\) for deriving separate **MAC key** and symmetric **encryption key** from the ECDH shared secret. It has many variants.

The **ECIES standard** combines ECC-based **asymmetric cryptography** with **symmetric ciphers** to provide data encryption by EC private key and decryption by the corresponding EC public key. The **ECIES** encryption scheme uses **ECC** cryptography \(public key cryptosystem\) + key-derivation function \(**KDF**\) + **symmetric encryption** algorithm + **MAC** algorithm, combined together like it is shown on the figure below:
The **ECIES standard** combines ECC-based **asymmetric cryptography** with **symmetric ciphers** to provide data encryption by EC public key and decryption by the corresponding EC private key. The **ECIES** encryption scheme uses **ECC** cryptography \(public key cryptosystem\) + key-derivation function \(**KDF**\) + **symmetric encryption** algorithm + **MAC** algorithm, combined together like it is shown on the figure below:

![](../.gitbook/assets/ecies.png)

Expand Down
2 changes: 1 addition & 1 deletion cryptographic-hash-functions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ print("SHA-256('hello') = ", binascii.hexlify(sha256hash))

Run the above code example: [https://repl.it/@nakov/SHA-256-hello-in-Python](https://repl.it/@nakov/SHA-256-hello-in-Python).

There is no efficient algorithm to find the input message \(in the above example `hello`\) from its hash value \(in the above example `2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824`\). It is well-known that cryptographic hash functions **cannot be reversed** back, so they are used widely to encode an input without revealing it \(e.g. encode a private key to a blockchain address without revealing the key\).
There is no efficient algorithm to find the input message \(in the above example `hello`\) from its hash value \(in the above example `2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824`\). It is well-known that cryptographic hash functions **cannot be reversed** back, so they are used widely to encode an input without revealing it \(e.g. encode a public key to a blockchain address without revealing the key\).

As another **example**, we can take the cryptographic hash function `SHA3-512` and calculate the hash value of the same text message `hello`:

Expand Down
4 changes: 2 additions & 2 deletions cryptographic-hash-functions/hash-functions-applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The above example comes from the `/etc/shadow` file in a modern Linux system. Th

## Generate Unique ID

Generate an \(**almost**\) **unique ID** of certain document / message. Cryptographic hash functions almost uniquely identify documents based on their content. In theory **collisions are possible** with any cryptographic hash function, but are very unlikely to happen, so most systems \(like **Git**\) assume that the hash function they use is **collistion free**.
Generate an \(**almost**\) **unique ID** of certain document / message. Cryptographic hash functions almost uniquely identify documents based on their content. In theory **collisions are possible** with any cryptographic hash function, but are very unlikely to happen, so most systems \(like **Git**\) assume that the hash function they use is **collision free**.

Usually a document is **hashed** and the **document ID** \(hash value\) is used later to prove the existence of the document, or to retrieve the document from a storage system. Example of hash-based unique IDs are the commit hashes in **Git** and **GitHub**, based on the content of the commit \(e.g. `3c3be25bc1757ca99aba55d4157596a8ea217698`\) and the **Bitcoin** addresses \(e.g. `1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2`\).

Expand All @@ -34,7 +34,7 @@ In the above example the SHA-1 unique ID identifies a certain commit in GitHub.

## Proof-of-Work Algorithms

**Proof-of-work** \(PoW\) algorithms. Most proof-of-work algorithms calculate a hash value which is bigger than certain value \(known as mining difficulty\). To find this hash value, miners calculate billions of different hashes and take the biggest of them, because hash numbers are unpredictable. For example, the proof of work problem might be defined as follows: find a number `p`, such that `hash(x + p)` holds 10 zero bits at its beginning.
**Proof-of-work** \(PoW\) algorithms. Most proof-of-work algorithms seek to calculate a hash value which is smaller than certain value \(known as mining difficulty\). To find this hash value, miners calculate billions of different hashes and take the biggest of them, because hash numbers are unpredictable. For example, the proof of work problem might be defined as follows: find a number `p`, such that `hash(x + p)` holds 10 zero bits at its beginning.

## Cryptographic Hashes are Part of Modern Programming

Expand Down
2 changes: 1 addition & 1 deletion cryptographic-hash-functions/secure-hash-algorithms.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ BLAKE2b('hello') = e4cfa39a3d37be31c59609e807970799caa68a19bfaa15135f165085e01d4

The **160-bit** variant of **RIPEMD** is widely used in practice, while the other variations like RIPEMD-128, RIPEMD-256 and RIPEMD-320 are not popular and have disputable security strengths.

As recommendation, **prefer using SHA-2 and SHA-3** instead of RIPEMD, because they are more stronger than RIPEMD, due to higher bit length and less chance for collisions.
As recommendation, **prefer using SHA-2 and SHA-3** instead of RIPEMD, because they are stronger than RIPEMD, due to higher bit length and less chance for collisions.

Examples of RIPEMD hashes:

Expand Down
6 changes: 3 additions & 3 deletions digital-signatures/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

**Digital signatures** cannot identify who is the person, created a certain signature. This can be solved in combination with a [**digital certificate**](https://en.wikipedia.org/wiki/Public_key_certificate), which binds a public key owner with identity \(person, organization, web site or other\). By design digital signatures bind messages to public keys, not to digital identities.

## Sign Messages and Verify Signatures: How It Works?
## Sign Messages and Verify Signatures: How Does It Work?

**Digital signature** schemes typically use a **public-key cryptosystem** \(such as RSA or ECC\) and use a **public / private key pairs**. A message is signed by a private key and the signature is verified by the corresponding public key:
**Digital signature** schemes typically use a **public-key cryptosystem** \(such as RSA or ECC\) and use **public / private key pairs**. A message is signed by a private key and the signature is verified by the corresponding public key:

![](../.gitbook/assets/public-key-cryptography-sign-verify.png)

Expand Down Expand Up @@ -84,7 +84,7 @@ A **deterministic-ECDSA** variant is defined in [**RFC 6979**](https://tools.iet

**EdDSA** \(Edwards-curve Digital Signature Algorithm\) is a fast **digital signature algorithm**, using **elliptic curves** in Edwards form \(like [**Ed25519**](https://ed25519.cr.yp.to) and [**Ed448-Goldilocks**](https://eprint.iacr.org/2015/625.pdf)\), a deterministic variant of the [**Schnorr's signature**](https://en.wikipedia.org/wiki/Schnorr_signature) scheme, designed by a team of the well-known cryptographer [**Daniel Bernstein**](https://cr.yp.to/djb.html).

**EdDSA** is more **simple** than **ECDSA**, more **secure** than **ECDSA** and is designed to be **faster** than **ECDSA** \(for curves with comparables key length\). Like **ECDSA**, the **EdDSA** signature scheme relies on the difficulty of the **ECDLP problem** \(elliptic-curve discrete logarithm problem\) for its security strength.
**EdDSA** is **simpler** than **ECDSA**, more **secure** than **ECDSA** and is designed to be **faster** than **ECDSA** \(for curves with comparable key lengths\). Like **ECDSA**, the **EdDSA** signature scheme relies on the difficulty of the **ECDLP problem** \(elliptic-curve discrete logarithm problem\) for its security strength.

The **EdDSA** signature algorithm is works with Edwards elliptic curves like **Curve25519** and **Curve448**, which are highly optimized for **performance** and **security**. It is shown that **Ed25519 signatures** are typically **faster** than traditional **ECDSA signatures** over curves with comparable key length. Still, the performance competition is disputable. The **EdDSA sign / verify** process works as follows:

Expand Down
2 changes: 1 addition & 1 deletion digital-signatures/ecdsa-sign-verify-messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The public key EC point {_**x**_, _**y**_} can be **compressed** to just one of

## ECDSA Sign

The ECDSA signing algorithm \([**RFC 6979**](https://tools.ietf.org/html/rfc6979#section-3.2)\) takes as input a message _**msg**_ ****+ a private key _**privKey**_ ****and produces as output a **signature**, which consists of pair of integers {_**r**_, _**s**_}. The **ECDSA signing** algorithm is based on the [**ElGamal signature scheme**](https://en.wikipedia.org/wiki/ElGamal_signature_scheme) and works as follows \(with minor simplifications\):
The ECDSA signing algorithm \([**RFC 6979**](https://tools.ietf.org/html/rfc6979#section-3.2)\) takes as input a message _**msg**_ + a private key _**privKey**_ and produces as output a **signature**, which consists of pair of integers {_**r**_, _**s**_}. The **ECDSA signing** algorithm is based on the [**ElGamal signature scheme**](https://en.wikipedia.org/wiki/ElGamal_signature_scheme) and works as follows \(with minor simplifications\):

1. Calculate the message **hash**, using a cryptographic hash function like SHA-256: _**h**_ = hash\(_**msg**_\)
2. Generate securely a **random** number _**k**_ in the range \[1.._**n**_-1\]
Expand Down
10 changes: 6 additions & 4 deletions encryption-symmetric-and-asymmetric.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The **secret key** used to **cipher** \(encrypt\) and **decipher** \(decrypt\) d

Most applications use a [**password-to-key-derivation**](https://github.com/svetlin-nakov/practical-cryptography-for-developers/tree/34666e7576d7427e08bf3940a69214b0cda94676/content/part-1-blockchain-networks-concepts/blockchain-cryptography/blockchain-cryptography-overview/hmac-and-key-derivation.html) scheme to extract a **secret key** from certain **password**, because users tend to remember passwords easier than binary data. Additionally, **message authentication** is often incorporated along with the encryption to provide **integrity** and **authenticity** \(this encryption approach is known as "[**authenticated encryption**](https://en.wikipedia.org/wiki/Authenticated_encryption)"\).

How does a **private key** look like? Let's start from a simple example of **256-bit secret key**, encoded as [**hex string**](https://en.wikipedia.org/wiki/Hexadecimal):
What does a **private key** look like? Let's start from a simple example of **256-bit secret key**, encoded as [**hex string**](https://en.wikipedia.org/wiki/Hexadecimal):

```text
02c324648931b89e3e8a0fc42c96e8e3be2e42812986573a40d46563bceaf75110
Expand Down Expand Up @@ -105,18 +105,20 @@ In some public key cryptosystems \(like the Elliptic-Curve Cryptography - **ECC*

Usually, a **public / private key pair** is randomly generated in a secure environment \(e.g. in a hardware wallet\) and the public key is revealed, while the private key is securely stored in a crypto-wallet and is protected by a password or by multi-factor authentication.

**Example** of 256-bit private key and its corresponding 256-bit public key \(based on **secp256k1** curve\):
**Example** of 256-bit private key and its corresponding public key \(based on **secp256k1** curve\):

```text
privKey: 648fc1fa828c7f185d825c04a5b21af9e473b867eeee1acea4dbab938433e158
pubKey: 02c324648931b89e3e8a0fc42c96e8e3be2e42812986573a40d46563bceaf75110
```

Note that the pubKey value written here is a *compressed* pubkey, which is hex-encoded as 33 bytes (264 total bits). The actual pubkey varies depending on the algorithm being used, but the **secp256k1** curve generates a *point on a curve* which is actually the combination of a 256-bit X value and a 256-bit Y value. Using certain mathematical techniques, it is possible to calculate this full point using just one of these values and one extra bit. In this encoding, the extra bit is written using an extra byte. This will be covered in further detail in a later chapter.

### Private Keys

Message **encryption** and **signing** is done by a **private key**. The private keys are always kept **secret** by their owner, just like passwords. In the server infrastructure, private key usually stay in an encrypted and protected **keystore**. In the blockchain systems the private keys usually stay in specific software or hardware apps or devices called "**crypto wallets**", which store securely a set of private keys.

**Example** of 256-bit private key:
**Example** of a 256-bit private key:

```text
648fc1fa828c7f185d825c04a5b21af9e473b867eeee1acea4dbab938433e158
Expand All @@ -128,7 +130,7 @@ Message **decryption** and **signature verification** is done by the **public ke

In many systems the **public key** is encapsulated in a **digital certificate**, which binds certain identity \(e.g. person or Internet domain name\) to certain public key. In blockchain systems public keys are usually published as parts of the blockchain transactions to help identify who has signed each transaction. In systems like PGP and SSH the public key is downloaded from the server once \(after manual user verification\) and is remembered for further use.

**Example** of 256-bit public key:
**Example** of a compressed public key:

```text
02c324648931b89e3e8a0fc42c96e8e3be2e42812986573a40d46563bceaf75110
Expand Down
2 changes: 1 addition & 1 deletion key-exchange/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
In cryptography [**key establishment**](http://cacr.uwaterloo.ca/hac/about/chap12.pdf) \(**key exchange**, **key negotiation**\) is a process or protocol, whereby a **shared secret** becomes available to two parties, for subsequent cryptographic use, typically for encrypted communication. Establishment techniques can be **key agreement** or **key transport** schemes.

* In a **key agreement** scheme both parties contribute to the negotiation of the shared secret. Examples of key agreement schemes are Diffie-Hellman \(**DHKE**\) and Elliptic-Curve Diffie-Hellman \(**ECDH**\).
* In a **key transport** scheme only one of the parties contributes to the shared secret and the other party obtains the secret from it. Key transport schemes are typically implemented through **public-key cryptography**, e.g. in the **RSA key exchange** the client encrypts a random session key by its private key and sends it to the server, where it is decrypted using the client's public key.
* In a **key transport** scheme only one of the parties contributes to the shared secret and the other party obtains the secret from it. Key transport schemes are typically implemented through **public-key cryptography**, e.g. in the **RSA key exchange** the client generates a private/public key pair and transmits the public key to a server, which encrypts a random session key using the public key obtained from the client and responds with this encrypted message. The client can then use the private key it generated in the first step to decrypt the message and obtain the session key.

By design [**key exchange**](https://en.wikipedia.org/wiki/Key_exchange) schemes securely exchange cryptographic keys between two parties, in a way that noone else can obtain a copy of the keys. Typically, at the start of an **encrypted conversation** \(e.g. during the **TLS handshake** phase\), the parties first negotiate about the encryption keys \(the shared secret\) to be used during the conversation. **Key exchange schemes** are really important topic in the modern cryptography, because keys are exchanged hundreds of times by million devices and servers in Internet.

Expand Down
2 changes: 1 addition & 1 deletion symmetric-key-ciphers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ When the input data is encrypted, it is transformed to **encrypted ciphertext**

It is important to know as a concept that symmetric-key encryption algorithms usually do not work standalone. They work together with other related crypto algorithms, into a **symmetric encryption scheme** / **symmetric encryption construction**.

In most encryption schemes an **encryption** is combined with password to **key derivation** algorithm and **message authentication** scheme \(see [authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption)\). Typically a symmetric encryption procedure uses a sequence of steps, involving different crypto algorithms:
In most encryption schemes an **encryption** is combined with a password to a **key derivation** algorithm and a **message authentication** scheme \(see [authenticated encryption](https://en.wikipedia.org/wiki/Authenticated_encryption)\). Typically a symmetric encryption procedure uses a sequence of steps, involving different crypto algorithms:

* **Password-to-key derivation** algorithm \(like Scrypt or Argon2\): to allow using a password instead of a key and to make password cracking hard and slow to be performed.
* **Block to stream cipher transformation** algorithm \(block cipher mode like **CBC** or **CTR**\) + **message padding** algorithm like **PKCS7** \(in some modes\): to allow encrypting data of arbitrary size using a block cipher algorithm \(like **AES**\).
Expand Down
2 changes: 1 addition & 1 deletion symmetric-key-ciphers/aes-cipher-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

The [**Advanced Encryption Standard \(AES\)**](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) cipher, also known as "**Rijndael**" is a popular, secure, widely used **symmetric key block cipher** algorithm, used officially as recommended encryption technology standard in the United States. **AES** operates using **block size of 128 bits** and symmetric **keys of length** **128**, **160**, **192**, **224** and **256** bits.

## AES is Secure and Very Popular Symmetric Encryption Algorithm
## AES is a Secure and Very Popular Symmetric Encryption Algorithm

The **AES** symmetric encryption algorithm is considered **highly secure** \(when configured correctly\) and no significant practical attacks are known for AES in its history.

Expand Down