summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorsiddharth ravikumar <s@ricketyspace.net>2025-11-08 13:23:56 -0500
committersiddharth ravikumar <s@ricketyspace.net>2025-11-08 13:23:56 -0500
commit2fc8be08ae2f72ebca965decadc191729e6bb32b (patch)
treeba163937fa38ca16419637c59ba3296b9d59a416 /lib
parent32803d4577151e18252c7e2102738b544e99fcbc (diff)
lib: add `RSAPrivate.Sign`
Diffstat (limited to 'lib')
-rw-r--r--lib/rsa.go47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/rsa.go b/lib/rsa.go
index 9353824..314e8bb 100644
--- a/lib/rsa.go
+++ b/lib/rsa.go
@@ -5,6 +5,7 @@ package lib
import (
"crypto/rand"
+ "errors"
"math/big"
)
@@ -156,3 +157,49 @@ func (r *RSAPrivate) Decrypt(cipher []byte) []byte {
return m.Bytes()
}
+
+// Sign generates a signature for the give data d according to RFC2313
+// sections 8 and 10.
+//
+// https://datatracker.ietf.org/doc/html/rfc2313
+func (r *RSAPrivate) Sign(msg []byte) (ed []byte, err error) {
+ // Hash message using md4.
+ var (
+ dgst Md4 = Md4{}
+ d []byte // Data to sign.
+ )
+ dgst.Init([]uint32{})
+ dgst.Message(msg)
+ d = dgst.Hash()
+
+ var (
+ kn int = r.n.BitLen() / 8 // Size of N in bytes.
+ dn int = len(d) // Length of d.
+ pn int = kn - 3 - dn // Number of padding characters.
+
+ eb []byte // Encryption block.
+ x *big.Int // Encryption block as an integer.
+ y *big.Int // Signature as an integer.
+ )
+ if dn > kn-11 {
+ err = errors.New("rsa: data len > k-11")
+ return
+ }
+
+ // Build encryption block.
+ eb = []byte{0x00, 0x01}
+ for i := 0; i < pn; i++ {
+ eb = append(eb, 0xFF)
+ }
+ eb = append(eb, 0x00)
+ eb = append(eb, d...)
+
+ // Convert to big int.
+ x = new(big.Int).SetBytes(eb)
+
+ // Sign.
+ y = big.NewInt(0).Exp(x, r.d, r.n)
+
+ ed = y.Bytes()
+ return
+}