Skip to content

Instantly share code, notes, and snippets.

@as
Created March 9, 2018 03:09
Show Gist options
  • Save as/06416e61313a0a7c17c4089863b2ae78 to your computer and use it in GitHub Desktop.
Save as/06416e61313a0a7c17c4089863b2ae78 to your computer and use it in GitHub Desktop.
Compare two RSA keys in Go
package main
import (
"crypto/rsa"
"errors"
"fmt"
"math/big"
)
const confidence = 100
var one = new(big.Int).SetInt64(1)
var (
ErrPrimality = errors.New("primality test failed")
ErrModulus = errors.New("p*q != N")
ErrInverse = errors.New("bad inversion")
)
func fromBase10(s string) *big.Int {
b, ok := new(big.Int).SetString(s, 10)
if !ok {
panic(ok)
}
return b
}
func cmpPrivateKeys(pkA, pkB *rsa.PrivateKey) error {
var (
N = pkA.PublicKey.N
p, q = pkB.Primes[0], pkB.Primes[1]
E, D = pkA.D, big.NewInt(int64(pkB.PublicKey.E))
)
if !p.ProbablyPrime(confidence) || !q.ProbablyPrime(confidence) {
return ErrPrimality
}
if !sameN(p, q, N) {
return ErrModulus
}
ϕ := new(big.Int).Mul(
new(big.Int).Sub(p, one),
new(big.Int).Sub(q, one),
)
if new(big.Int).ModInverse(E, ϕ).Cmp(D) != 0 {
return ErrInverse
}
return nil
}
func sameN(p, q, N *big.Int) bool {
return new(big.Int).Mul(p, q).Cmp(N) == 0
}
func sameRSA(pk0, pk1 *rsa.PrivateKey) bool {
if len(pk0.Primes) != len(pk1.Primes) {
return false
}
err := cmpPrivateKeys(pk0, pk1)
return err == nil
}
func main() {
pk0 := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: fromBase10("143"),
E: 7,
},
D: fromBase10("103"),
Primes: []*big.Int{
fromBase10("11"),
fromBase10("13"),
},
}
pk1 := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
E: 7,
N: fromBase10("143"),
},
D: fromBase10("103"),
Primes: []*big.Int{
fromBase10("13"),
fromBase10("11"),
},
}
fmt.Println(sameRSA(pk0, pk1))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment