Skip to content
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

Patch 1 #15

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
20 changes: 10 additions & 10 deletions _posts/2022-9-9-CofactorClearing.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ title: Clamping & Cofactor clearing in Curve25519
### Clamping
When using DJB's $Curve25519$, the private key is clamped before use.

The claimping function typically looks like this
The clamping function typically looks like this

~~~ruby

Expand All @@ -23,18 +23,18 @@ key[31] |= 64;

Here `key` is the private key, a 32-byte value interpreted as an integer in **little-endian** format. Let's see what these 3 lines of code do.

> key[0] &= 248; // 248 is 011111000
`key[0] &= 248; // 248 is 11111000`

This Bitwise ANDing will clear (zero out) the lowest 3 bits of the key. This is called **Cofactor Clearing** and a majority of this post is spent in discussing this.
This Bitwise AND will clear (zero out) the lowest 3 bits of the key. This is called **Cofactor Clearing** and a majority of this post is spent in discussing this.


> key[31] &= 127; // 127 is 01111111
`key[31] &= 127; // 127 is 01111111`

This Bitwise ANDing will clear (zero out) bit 255. This ensures that the key is always in the range $0..2^{255}-1$ where the operations are defined.
This Bitwise AND will clear (zero out) bit 255. This ensures that the key is always in the range $0..2^{255}-1$ where the operations are defined.

> key[31] |= 64; // 64 is 01000000
`key[31] |= 64; // 64 is 01000000`

This Bitwise ORing will set bit 254 to 1 which improves performance when operations are implemented in a way that doesn't leak information about the key through timing.
This Bitwise OR will set bit 254 to 1 which improves performance when operations are implemented in a way that doesn't leak information about the key through timing.

This post is mainly about the Cofactor Clearing part of the Clamping function, so the rest of the post only discusses that.

Expand Down Expand Up @@ -73,17 +73,17 @@ There are also a couple of other attacks similar to the one we described.

- Instead of Bob launching the above attack, a man in the middle (Mallory) intercepts $bG$ sent by Bob & replace it with $H$, then he can brute force the secret key generated by Alice ($aH$) because it can only be one of $8$ points.

In DH, leaking $a \bmod 8$ matters only if Alice reuses $a$. However, above attack is not limited to DH, but also applicable to many other Cryptographic protocols. In some protocols like like PAKE, MQV etc, the attack can have far worse effects.
In DH, leaking $a \bmod 8$ matters only if Alice reuses $a$. However, above attack is not limited to DH, but also applicable to many other Cryptographic protocols. In some protocols like like PAKE, MQV, etc the attack can have far worse effects.

**Mitigation for the small subgroup attack - cofactor clearing**
#### **Mitigation for the small subgroup attack -- cofactor clearing**

If you have a cyclic group of order $np$ (where $p$ is a prime), then scalar multipliying any element of the group by the cofactor ($n$) gives you an element of the prime order subgroup irrespective irrespective of which subgroup it was in originally. This can be easily done by both parties - i.e. Alice after choosing a private key $a$, she multiplies it by $8$ & uses $8a$ as the private key. So when she receives $bG$ from Bob, the shared secret is derived from $8abG$ instread of from $abG$. Likewise Bob does the same. Now if Bob is a malicious player, then what is leaked is $8a \bmod 8$ instead of $a \bmod 8$. Since $8a \bmod 8$ is always 0, nothing of significance is leaked. Thus, mutliplying the private key by the cofactor mitigates the small subgroup attack.

Below is a sage program which takes all possible values of $a$ & scalar multiplies it by $8$. And you can see that after doing this, the output is always an element of the prime order subgroup.

As we saw at the beginning of the post DJB uses something similar for $Curve25519$ - the lower 3 bits of the private key/scalar is cleared before use. Any element with $3$ least significant bits as $0$ is a multiple of $8$ & nothing is leaked by the small subgroup attack.

**Torsion safe cofactor clearing**
#### **Torsion safe cofactor clearing**

The method of cofactor clearing by scalar multiplying by the cofactor works fine for many protocols but isn't suitable everywhere. In many implementations of $Ed25519$, the private key/scalar is persisted as is and before use the least significant 3 bits of the scalar are cleared. This creates a problem for some use-cases.
Any point $Q$ on the full curve of order $8p$ can be written as the sum of 2 components i.e. the prime order component $P$ & a $8$-torsion component $T$ from the subgroup of order $8$ i.e $Q = P + T$. Clearing the lower 3 bits of $Q$ could change both the prime order component & also the 8-torsion component. This may not be appropriate in some places (like BIP-32 which uses hierarchical key derivation scheme). These use-cases require "torsion-safe" cofactor clearing.
Expand Down