From 2fc8be08ae2f72ebca965decadc191729e6bb32b Mon Sep 17 00:00:00 2001 From: siddharth ravikumar Date: Sat, 8 Nov 2025 13:23:56 -0500 Subject: lib: add `RSAPrivate.Sign` --- lib/rsa.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'lib') 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 +} -- cgit v1.2.3