Safe Primes, M. LeBlanc and Sophie Germain

Sophie Germain (born 1776 in Paris) was a French mathematician and who used safe primes to investigate Fermat’s Last Theorem. She gained…

Safe Primes, M. LeBlanc and Sophie Germain

Sophie Germain (born 1776 in Paris) was a French mathematician and who used safe primes to investigate Fermat’s Last Theorem. She gained her knowledge of mathematics by studying the works of Euler and communicated her ideas with other famous mathematics scholars, including Legendre and Gauss.

In fact, at the time, she faced great resistance in her studies, including from her parent, who confiscated her candles and took away her clothes in order to stall her research. Sophie also hid her gender when communicating with Gauss and used the pseudonym of Monsieur LeBlanc. But, against all the obstacles she faced, she overcame them and even learnt Greek and Latin so that she could read about the works of Euler and Newton.

Sophie Germain prime

A Sophie Germain prime (p) is a prime number which also generates a prime at 2p + 1. Thus 11 is a Sophie Germain prime, and where 23 is a safe prime. But 17 is not a Sophie Germain prime, as we get 35 for 2x17+1, and which can be factorized. These primes have been seen as being important when selecting prime numbers to be used in the RSA method. For this, we create a public modulus (N) and which is the multiplication of two large prime numbers (p and q). If these prime numbers are weak, it can make the factorization of N easier.

The first few Sophie Germain primes are 2, 3, 5, 11, 23, and 29, and which lead to the safe primes of 5, 7, 11, 23, 47 and 59. We can create a Golang program to generate a random prime number with n bits and then test it to see if it is safe [here]:

package main

import (
"crypto/rand"
"fmt"
"math"
"math/big"
"os"
"strconv"
)

func main() {

bits := 16

argCount := len(os.Args[1:])

if argCount > 0 {
bits, _ = strconv.Atoi(os.Args[1])
}

if bits < 3 {
fmt.Printf("We need at least three bits")
}

var p *big.Int

checks := int(math.Max(float64(bits)/16, 8))
for {

p, _ = rand.Prime(rand.Reader, int(bits)-1)

p.Add(p.Lsh(p, 1), big.NewInt(1))

if p.ProbablyPrime(checks) {
break
}
}
fmt.Printf("Safe prime: %s", p)

}

With this, we shift p by one position to the left and is equivalent to a 2.p, and where we can add 1:

p.Add(p.Lsh(p, 1), big.NewInt(1))

A sample run for a 96-bit prime is: [here]:

Bits:		96
Selections: 13
Prime: 37053578410686858579548491583
Safe prime: 74107156821373717159096983167

A sample prime for 512 bits is:

Bits:		512
Selections: 216
Prime: 6215641074915422390891487240873485166396563079583149872792235087315853337457206134539638799981401165118482893105922463329240778055363535077155714487851623
Safe prime: 12431282149830844781782974481746970332793126159166299745584470174631706674914412269079277599962802330236965786211844926658481556110727070154311428975703247

Miller-Rabin test for primality

Overall safe primes are used in cryptography, as they are robust against attacks within discrete log methods (such as for the Diffie Hellman methods). In the following, we use the Miller-Rabin test for primality:

  • p=47 (safe as 46/2=23) Try!
  • p=59 (safe as 58/2=29) Try!
  • p=83 (safe as 82/2=41) Try!
  • p=99 (Not a prime!) Try!

The largest-ever safe prime found was 2618163402417 x2¹²⁹⁰⁰⁰⁰ − 1.

Conclusions

The usage of safe primes in RSA is not required, but they are in the Diffie-Hellman key exchange method as we typically use a small integer for the generator (such as g=2 or g=5) — and which has performance benefits.