Cryptography

RSA-TZ Mode [Easy]

Handouts:

from Crypto.Util.number import *
Flag = b'CSCCTF{SXMgSFRVIHNvIGJhZCBhZnRlcmFsbD8}'

Flag = bytes_to_long(Flag)

p = getPrime(512)
q = getPrime(512)
while p >= q:
    q = getPrime(512)

n = p*q
e = 0x10001

def encrypt(m):
    return pow(m, e, n)


with open('out.txt', 'w') as f:
    f.write(f'ct = {encrypt(Flag)}\n')
    f.write(f'n = {n}\n')
    f.write(f'e = {e}\n') 
    f.write(f'TZ = {q%p}\n')

Solution Explanation

In this challenge, we exploit the fact that the prime factors p and q of the modulus n are close in value given the hint q%p:

Key Observations and Reshaping the Problem

  1. Given Relationship:

    • Since q % p = TZ (the remainder when q is divided by p), we can express q in terms of p and TZ as:

    q=kp+TZq = k * p + TZ

    Where k is a small integer, and we can assume k is small, since p is very close to q.

  2. Rewriting TZ:

    • Using the relation TZ = q - p, we can substitute and reshape the equation.

  3. Substituting Into n:

    • The modulus n is the product of p and q, so:

n=pqn=p(TZ+p)n = p * q \newline n = p*(TZ + p)

  1. Quadratic Equation:

    • Expanding and reshaping:

    n=p2+TZpp2+TZpn=0n = p^2 + TZ * p \newline p^2 + TZ * p - n = 0

    • This is a standard quadratic equation of the form:

    ax2+bx+c=0ax^2 + bx + c = 0

    Here, a = 1, b = TZ, and c = -n.

Solving for q

Using the quadratic formula:

p=(b±b24ac)/2ap = (-b \pm \sqrt{b^2 - 4ac}) / 2a

Substituting the values:

p=(TZ±TZ2+4n)/2p = (-TZ \pm \sqrt{TZ^2 + 4n}) / 2

Select the positive root, as q must be positive.

Finding p

Once q is found, compute p using:

Computing phi and the Private Key d

  1. Compute phi:

    • The Euler's totient function phi is given by:

  2. Find d:

    • The private exponent d is the modular inverse of e modulo phi:

Decrypting the Ciphertext

Finally, use the private key d to decrypt the ciphertext ct:

The decrypted value flag represents the plaintext or solution to the challenge.In this challenge, we exploit the fact that the prime factors p and q of the modulus n are close in value (i.e., they have the same bit length), and p is slightly less than q. Here's a step-by-step breakdown of the solution:

Solver:


APT [Medium]

Handouts:

Solution Explanation

This challenge leverages RSA encryption and exploits a cryptographic vulnerability known as the common modulus attack. Below is a detailed explanation of the challenge mechanics and how to solve it.


Challenge Details

The challenge introduces the APT game, where:

  1. RSA encryption is used to generate ciphertexts ("shots").

  2. Each player is assigned a unique public exponent (e).

  3. A common modulus n is used for all encryption operations.

At the start of the game:

  • The list of public exponents (Es) and the modulus (n) is displayed.

  • The goal is to recover the plaintext (FLAG) by collecting ciphertexts and exploiting the vulnerability.


The Cryptographic Vulnerability

Common Modulus Attack

The RSA encryption formula is: [c=memodn][ c = m^e \mod n ] Where:

  • ( c ): ciphertext

  • ( m ): plaintext

  • ( e ): public exponent

  • ( n ): common modulus

If two ciphertexts are generated using the same modulus n but different public exponents e1 and e2, and if e1 and e2 are coprime, the plaintext ( m ) can be recovered using the common modulus attack.


Attack Steps

1. Collect Ciphertexts

You need two ciphertexts (( c1, c2 )) encrypted with different public exponents (( e1, e2 )). Ensure:

  • The ciphertexts are valid (not distorted, indicated by the absence of the huh? message).

  • ( e1 ) and ( e2 ) are coprime.

c1=me1modnc2=me2modnc_1 = m^{e_1} \mod n\\ c_2 = m^{e_2} \mod n

where mm is the plaintext, nn is the common modulus, and e1,e2e_1, e_2 are the public exponents with gcd(e1,e2)=1\gcd(e_1, e_2) = 1.

Using Bézout's identity, since gcd(e1,e2)=1\gcd(e_1, e_2) = 1, there exist integers aa and bb such that:

[ae1+be2=1.][ a \cdot e_1 + b \cdot e_2 = 1. ]

Raising mm to the power of this equation modulo nn gives:

[mae1+be2m1mmodn.][ m^{a \cdot e_1 + b \cdot e_2} \equiv m^1 \equiv m \mod n. ]

Substituting c1=me1modnc_1 = m^{e_1} \mod n and c2=me2modnc_2 = m^{e_2} \mod n, we get:

[m=c1ac2bmodn][m = c_1^a \cdot c_2^b \mod n]

where aa and bb satisfy Bézout's identity.

Solver:

You could bruteforce the 6 Es like I did in my solver, or you could map each CTs shot taker to the corresponding entry in the Es array given, feel free to do it however you see fit :))

RZA [Hard]

Handout:

Solution Explanation

This challenge involves exploiting RSA encryption with hints provided through a custom modulus generation mechanism. The ultimate goal is to recover the FLAG using the provided ciphertext and modulus hints.


Challenge Details

The challenge uses:

  • An RSA public exponent ( e = 65537 ).

  • A ciphertext ( c ) that encrypts the flag.

  • Modulus hints provided through a menu option.

At the start of the game:

  • You are given the ciphertext ( c ).

  • You can request modulus hints in the form of congruence relations, allowing the recovery of the modulus.

The objective is to reconstruct the modulus ( p ), decrypt the ciphertext, and retrieve the FLAG.


The Cryptographic Vulnerability

The modulus ( p ) is generated with properties that allow reconstruction through the Chinese Remainder Theorem (CRT):

  • Multiple congruences (amodm)( a \mod m ) are provided.

  • Using CRT, the modulus ( p ) can be recovered.


Attack Steps

1. Collect Congruences

Using the menu option, collect congruence relations (( a \mod m )). Ensure that the moduli ( m ) are pairwise coprime to use CRT.

2. Reconstruct ( p )

Apply CRT to the collected congruences to reconstruct ( p ). The reconstructed value will require a brute-force adjustment due to a missing bit range.

3. Decrypt the Ciphertext

Since the Flag is smaller than P, we don't need Q to decrypt

Proof

We are given:

[c=memod(pq),][ c = m^e \mod (p \cdot q), ]

and need to prove:

[cmodp=memodp][ c \mod p = m^e \mod p]


Step 1: Express ( c )

From ( c=memod(pq)c = m^e \mod (p \cdot q) ), there exists an integer ( k ) such that:

[c=mek(pq)][ c = m^e - k \cdot (p \cdot q) ]


Step 2: Take modulo ( p )

Taking (modp \mod p ) on both sides:

[cmodp=(mek(pq))modp.][ c \mod p = \big(m^e - k \cdot (p \cdot q)\big) \mod p. ]


Step 3: Simplify

Since ( p ) divides (pqp \cdot q ), the term ( k(pq)modpk \cdot (p \cdot q) \mod p ) vanishes, leaving:

[cmodp=memodp][ c \mod p = m^e \mod p ]


With ( p ), compute: [ϕ=p1][ \phi = p - 1 ] The private key ( d ) is calculated as: [d=e1modϕ][ d = e^{-1} \mod \phi ] Finally, decrypt the ciphertext: [FLAG=cdmodp][ \text{FLAG} = c^d \mod p ]

Solver:

Digital Encryption League [Insane]

Handout:

Solution Explanation

In this challenge, we exploit a cryptographic vulnerability that arises when the same random value k is reused during the signing of two different messages. This section explains the process and how the attack functions.

Key Concept: The Danger of Reusing k

When signing a message, the user generates a random value k and uses it in the signature calculation. The following values are publicly shared as part of the signature:

  1. r=(kG).xmodpr = (k * G).x \mod p

  2. s=k1(z+rdA)s = k^-1 * (z + r * dA)

Where:

  • G is the generator point.

  • z is the hash of the message.

  • dA is the private key.

  • p is the prime order of the curve or group.

If the same k is used for two different signatures, the attacker can recover the private key dA using the following process.

Exploiting the Reuse of k

  1. Obtain Two Signatures with the Same k:

    • Let the two messages have hashes z1 and z2, and the corresponding signatures are (r, s1) and (r, s2).

    • Since the k value is the same for both signatures, we know:

      s1=k1(z1+rdA)s2=k1(z2+rdA)s1 = k^-1 * (z1 + r * dA)\newline s2 = k^-1 * (z2 + r * dA)

  2. Calculate k:

    • Subtract the two equations:

    s1s2=k1(z1z2)s1 - s2 = k^-1 * (z1 - z2)

    • Rearrange to solve for k:

    k=(z1z2)/(s1s2)k = (z1 - z2) / (s1 - s2)

  3. Recover the Private Key dA:

    • Using one of the signatures, calculate:

    dA=r1(ksz)dA = r^-1 * (k * s - z)

    • This equation allows the attacker to compute the private key.

Challenge-Specific Requirements

For the attack to work, you must:

  1. Send inp1, which is added to the static random value k.

  2. Send inp2, where:

By sending these inputs, the same k value is effectively reused in two signatures, enabling the attack as described above.

Once the attacker has recovered the private key dA, they can find the flag as it is the secret key.

Solver:

Last updated