mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-07-14 12:49:45 -04:00
Add rsa3072 implementation
This commit is contained in:
@ -1,34 +1,127 @@
|
||||
package rsa
|
||||
|
||||
import "github.com/go-i2p/go-i2p/lib/crypto/types"
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha512"
|
||||
"crypto/x509"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/crypto/types"
|
||||
"github.com/samber/oops"
|
||||
)
|
||||
|
||||
type (
|
||||
RSA3072PrivateKey [786]byte
|
||||
)
|
||||
|
||||
// Sign implements types.Signer.
|
||||
// Len implements types.SigningPrivateKey.
|
||||
func (r *RSA3072PrivateKey) Len() int {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// NewSigner implements types.SigningPrivateKey.
|
||||
func (r *RSA3072PrivateKey) NewSigner() (types.Signer, error) {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// Sign implements types.Signer - signs data with SHA512 hash
|
||||
func (r RSA3072PrivateKey) Sign(data []byte) (sig []byte, err error) {
|
||||
panic("unimplemented")
|
||||
// Hash the data with SHA-512 which is appropriate for RSA-3072
|
||||
hash := sha512.Sum512(data)
|
||||
return r.SignHash(hash[:])
|
||||
}
|
||||
|
||||
// SignHash implements types.Signer.
|
||||
// SignHash implements types.Signer - signs a pre-computed hash
|
||||
func (r RSA3072PrivateKey) SignHash(h []byte) (sig []byte, err error) {
|
||||
panic("unimplemented")
|
||||
// Convert byte array to rsa.PrivateKey
|
||||
privKey, err := r.toRSAPrivateKey()
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("failed to parse RSA private key: %w", err)
|
||||
}
|
||||
|
||||
// Sign the hash with PKCS#1 v1.5
|
||||
sig, err = rsa.SignPKCS1v15(rand.Reader, privKey, crypto.SHA512, h)
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("failed to sign hash: %w", err)
|
||||
}
|
||||
|
||||
log.Debug("RSA-3072 signature created successfully")
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
// Bytes implements types.PrivateKey.
|
||||
// Bytes implements types.PrivateKey - returns raw key bytes
|
||||
func (r RSA3072PrivateKey) Bytes() []byte {
|
||||
panic("unimplemented")
|
||||
return r[:]
|
||||
}
|
||||
|
||||
// Public implements types.PrivateKey.
|
||||
// Public implements types.PrivateKey - derives public key from private key
|
||||
func (r RSA3072PrivateKey) Public() (types.SigningPublicKey, error) {
|
||||
panic("unimplemented")
|
||||
// Convert byte array to rsa.PrivateKey
|
||||
privKey, err := r.toRSAPrivateKey()
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("failed to parse RSA private key: %w", err)
|
||||
}
|
||||
|
||||
// Extract public key from private key
|
||||
pubBytes := x509.MarshalPKCS1PublicKey(&privKey.PublicKey)
|
||||
if len(pubBytes) > 384 {
|
||||
return nil, oops.Errorf("RSA public key exceeds expected size")
|
||||
}
|
||||
|
||||
// Create and return RSA3072PublicKey
|
||||
var pubKey RSA3072PublicKey
|
||||
copy(pubKey[:], pubBytes)
|
||||
|
||||
log.Debug("RSA-3072 public key derived successfully")
|
||||
return pubKey, nil
|
||||
}
|
||||
|
||||
// Zero implements types.PrivateKey.
|
||||
// Zero implements types.PrivateKey - securely erases key material
|
||||
func (r RSA3072PrivateKey) Zero() {
|
||||
panic("unimplemented")
|
||||
// Overwrite private key material with zeros
|
||||
for i := range r {
|
||||
r[i] = 0
|
||||
}
|
||||
log.Debug("RSA-3072 private key securely erased")
|
||||
}
|
||||
|
||||
// Helper method to convert byte array to rsa.PrivateKey
|
||||
func (r RSA3072PrivateKey) toRSAPrivateKey() (*rsa.PrivateKey, error) {
|
||||
// Parse PKCS#1 encoded private key
|
||||
privKey, err := x509.ParsePKCS1PrivateKey(r[:])
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("invalid RSA private key format: %w", err)
|
||||
}
|
||||
|
||||
// Validate key size is 3072 bits (384 bytes)
|
||||
if privKey.Size() != 384 {
|
||||
return nil, oops.Errorf("unexpected RSA key size: got %d, want 384", privKey.Size())
|
||||
}
|
||||
|
||||
return privKey, nil
|
||||
}
|
||||
|
||||
// Generate creates a new RSA-3072 private key
|
||||
func (r *RSA3072PrivateKey) Generate() (types.SigningPrivateKey, error) {
|
||||
// Generate a new RSA-3072 private key
|
||||
privateKey, err := rsa.GenerateKey(rand.Reader, 3072)
|
||||
if err != nil {
|
||||
return nil, oops.Errorf("failed to generate RSA-3072 key: %w", err)
|
||||
}
|
||||
|
||||
// Convert to PKCS#1 format
|
||||
privBytes := x509.MarshalPKCS1PrivateKey(privateKey)
|
||||
if len(privBytes) > 786 {
|
||||
return nil, oops.Errorf("RSA private key exceeds expected size")
|
||||
}
|
||||
|
||||
// Copy bytes into fixed-size array
|
||||
var newKey RSA3072PrivateKey
|
||||
copy(newKey[:], privBytes)
|
||||
|
||||
log.Debug("RSA-3072 private key generated successfully")
|
||||
return &newKey, nil
|
||||
}
|
||||
|
||||
var _ types.PrivateKey = RSA3072PrivateKey{}
|
||||
|
@ -1,6 +1,14 @@
|
||||
package rsa
|
||||
|
||||
import "github.com/go-i2p/go-i2p/lib/crypto/types"
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"crypto/sha512"
|
||||
"math/big"
|
||||
|
||||
"github.com/go-i2p/go-i2p/lib/crypto/types"
|
||||
"github.com/samber/oops"
|
||||
)
|
||||
|
||||
type (
|
||||
RSA3072PublicKey [384]byte
|
||||
@ -8,27 +16,69 @@ type (
|
||||
|
||||
// Verify implements types.Verifier.
|
||||
func (r RSA3072PublicKey) Verify(data []byte, sig []byte) error {
|
||||
panic("unimplemented")
|
||||
// Hash the data with SHA512 (commonly used with RSA3072 in I2P)
|
||||
hash := sha512.Sum512(data)
|
||||
return r.VerifyHash(hash[:], sig)
|
||||
}
|
||||
|
||||
// VerifyHash implements types.Verifier.
|
||||
func (r RSA3072PublicKey) VerifyHash(h []byte, sig []byte) error {
|
||||
panic("unimplemented")
|
||||
pubKey, err := rsaPublicKeyFromBytes(r[:])
|
||||
if err != nil {
|
||||
return oops.Errorf("failed to parse RSA3072 public key: %w", err)
|
||||
}
|
||||
|
||||
// For RSA3072, SHA512 is often used
|
||||
hashed := h
|
||||
if len(h) != sha512.Size {
|
||||
// If we received a different hash size, warn but continue
|
||||
log.Warnf("RSA3072 verification received unexpected hash size: %d", len(h))
|
||||
}
|
||||
|
||||
err = rsa.VerifyPKCS1v15(pubKey, crypto.SHA512, hashed, sig)
|
||||
if err != nil {
|
||||
return oops.Errorf("RSA signature verification failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bytes implements SigningPublicKey.
|
||||
func (r RSA3072PublicKey) Bytes() []byte {
|
||||
panic("unimplemented")
|
||||
return r[:]
|
||||
}
|
||||
|
||||
// Len implements SigningPublicKey.
|
||||
func (r RSA3072PublicKey) Len() int {
|
||||
panic("unimplemented")
|
||||
return len(r)
|
||||
}
|
||||
|
||||
// NewVerifier implements SigningPublicKey.
|
||||
func (r RSA3072PublicKey) NewVerifier() (types.Verifier, error) {
|
||||
panic("unimplemented")
|
||||
// The RSA3072PublicKey itself implements the Verifier interface
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// rsaPublicKeyFromBytes converts raw bytes to an rsa.PublicKey
|
||||
func rsaPublicKeyFromBytes(data []byte) (*rsa.PublicKey, error) {
|
||||
// For RSA3072, the public exponent is typically 65537 (0x10001)
|
||||
e := int(65537)
|
||||
|
||||
// The modulus is the full key
|
||||
n := new(big.Int).SetBytes(data)
|
||||
|
||||
pubKey := &rsa.PublicKey{
|
||||
N: n,
|
||||
E: e,
|
||||
}
|
||||
|
||||
// Validate key size
|
||||
bitSize := pubKey.Size() * 8
|
||||
if bitSize < 3072 {
|
||||
return nil, oops.Errorf("invalid RSA key size: %d (expected 3072)", bitSize)
|
||||
}
|
||||
|
||||
return pubKey, nil
|
||||
}
|
||||
|
||||
var _ types.PublicKey = RSA3072PublicKey{}
|
||||
|
Reference in New Issue
Block a user