diff options
| author | siddharth ravikumar <s@ricketyspace.net> | 2025-11-08 13:23:56 -0500 |
|---|---|---|
| committer | siddharth ravikumar <s@ricketyspace.net> | 2025-11-08 13:23:56 -0500 |
| commit | 2fc8be08ae2f72ebca965decadc191729e6bb32b (patch) | |
| tree | ba163937fa38ca16419637c59ba3296b9d59a416 /lib | |
| parent | 32803d4577151e18252c7e2102738b544e99fcbc (diff) | |
lib: add `RSAPrivate.Sign`
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/rsa.go | 47 |
1 files changed, 47 insertions, 0 deletions
@@ -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 +} |
