summaryrefslogtreecommitdiffstats
path: root/lib/rsa.go
diff options
context:
space:
mode:
authorsiddharth ravikumar <s@ricketyspace.net>2022-08-14 13:05:53 -0400
committersiddharth ravikumar <s@ricketyspace.net>2022-08-14 13:05:53 -0400
commit3aadff0d4782858afb687593ba54a6066467c95d (patch)
treef166a13e56e1d81f036a7eb99f7d409826f17abb /lib/rsa.go
parenteb436e38563783b901c271d5779d35ecad7c45f9 (diff)
lib: add `RSAGenKey`
Diffstat (limited to 'lib/rsa.go')
-rw-r--r--lib/rsa.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/lib/rsa.go b/lib/rsa.go
index 2c0769b..17cf6b0 100644
--- a/lib/rsa.go
+++ b/lib/rsa.go
@@ -4,6 +4,7 @@
package lib
import (
+ "crypto/rand"
"math/big"
)
@@ -13,6 +14,22 @@ type GCDResult struct {
Y *big.Int // Bézout coefficient 'y'
}
+// Represents an RSA key pair.
+type RSAPair struct {
+ Public *RSAPub
+ Private *RSAPrivate
+}
+
+type RSAPub struct {
+ e *big.Int
+ n *big.Int
+}
+
+type RSAPrivate struct {
+ d *big.Int
+ n *big.Int
+}
+
// Copy b to a.
func biCopy(a, b *big.Int) *big.Int {
a.SetBytes(b.Bytes())
@@ -98,3 +115,63 @@ func invmod(a, n *big.Int) (*big.Int, error) {
}
return t0, nil
}
+
+func RSAGenKey() (*RSAPair, error) {
+ // Initialize.
+ e := big.NewInt(3)
+ d := big.NewInt(0)
+ n := big.NewInt(0)
+
+ // Compute n and d.
+ for {
+ // Generate prime p.
+ p, err := rand.Prime(rand.Reader, 1024)
+ if err != nil {
+ return nil, CPError{"unable to generate p"}
+ }
+
+ // Generate prime q.
+ q, err := rand.Prime(rand.Reader, 1024)
+ if err != nil {
+ return nil, CPError{"unable to generate q"}
+ }
+
+ // Calculate n.
+ n = big.NewInt(0).Mul(p, q)
+
+ // Calculate totient.
+ p1 := big.NewInt(0).Sub(p, big.NewInt(1)) // p-1
+ q1 := big.NewInt(0).Sub(q, big.NewInt(1)) // q-1
+ et := big.NewInt(0).Mul(p1, q1) // Totient `et`.
+
+ // Calculate private key `d`.
+ d, err = invmod(e, et)
+ if err != nil {
+ continue // Inverse does not does. Try again.
+ }
+ break
+ }
+ if n.Cmp(big.NewInt(0)) <= 0 {
+ return nil, CPError{"unable to compute n"}
+ }
+ if d.Cmp(big.NewInt(0)) <= 0 {
+ return nil, CPError{"unable to compute d"}
+ }
+
+ // Make pub key.
+ pub := new(RSAPub)
+ pub.e = e
+ pub.n = biCopy(big.NewInt(0), n)
+
+ // Make private key.
+ prv := new(RSAPrivate)
+ prv.d = d
+ prv.n = biCopy(big.NewInt(0), n)
+
+ // Make key pair.
+ pair := new(RSAPair)
+ pair.Public = pub
+ pair.Private = prv
+
+ return pair, nil
+}