func FMPtoBigPrivateKey(key *FMPPrivateKey) *x509big.BigPrivateKey {
	pubKey := &x509big.BigPublicKey{
		N: new(big.Int).SetBytes(key.N.Bytes()),
		E: new(big.Int).SetBytes(key.PublicKey.E.Bytes()),
	}
	var privateKey *x509big.BigPrivateKey
	if key.D != nil {
		privateKey = &x509big.BigPrivateKey{
			PublicKey: *pubKey,
			D:         new(big.Int).SetBytes(key.D.Bytes()),
		}
		for _, p := range key.Primes {
			privateKey.Primes = append(privateKey.Primes, new(big.Int).SetBytes(p.Bytes()))
		}
	} else {
		privateKey = &x509big.BigPrivateKey{
			PublicKey: *pubKey,
		}
	}
	return privateKey
}
FMPtoBigPrivateKey takes a FMPPrivateKey and returns an x509big.PrivateKey using native go
big Int types.
package keys
import (
	"encoding/pem"
	"fmt"
	"log"
	"math/big"
	"github.com/sourcekris/goRsaTool/ln"
	"github.com/sourcekris/x509big"
	fmp "github.com/sourcekris/goflint"
)
type RSA struct {
	Key            FMPPrivateKey
	CipherText     []byte
	PlainText      []byte
	KnownPlainText []byte
	DLSB           []byte
	KeyFilename    string
	PastPrimesFile string
	NumPrimes      int
	Verbose        bool
	Log            *log.Logger
}
func NewRSA(key *FMPPrivateKey, c []byte, m []byte, pf string, v bool) (*RSA, error) {
	var pastPrimesFile string
	if pf != "" {
		pastPrimesFile = pf
	}
	var cipherText []byte
	if c != nil {
		cipherText = c
	}
	return &RSA{
		Key:            *key,
		PastPrimesFile: pastPrimesFile,
		CipherText:     cipherText,
		Verbose:        v,
	}, nil
}
func (t *RSA) PackGivenP(p *fmp.Fmpz) {
	q := new(fmp.Fmpz).Div(t.Key.N, p)
	t.Key.Primes = []*fmp.Fmpz{p, q}
	t.Key.D = ln.SolveforD(p, q, t.Key.PublicKey.E)
	if t.CipherText != nil && t.PlainText == nil {
		t.PlainText = ln.NumberToBytes(new(fmp.Fmpz).Exp(ln.BytesToNumber(t.CipherText), t.Key.D, t.Key.PublicKey.N))
	}
}
func (t *RSA) PackMultiPrime(primes []*fmp.Fmpz) error {
	var (
		n  = fmp.NewFmpz(1)
		cp = fmp.NewFmpz(1)
	)
	for _, p := range primes {
		n.MulZ(p)
		cp.MulZ(new(fmp.Fmpz).Sub(p, ln.BigOne))
	}
	if !n.Equals(t.Key.N) {
		return fmt.Errorf("product of primes does not equal N")
	}
	t.Key.Primes = primes
	t.Key.D = new(fmp.Fmpz).ModInverse(t.Key.PublicKey.E, cp)
	if t.CipherText != nil && t.PlainText == nil {
		t.PlainText = ln.NumberToBytes(new(fmp.Fmpz).Exp(ln.BytesToNumber(t.CipherText), t.Key.D, t.Key.PublicKey.N))
	}
	return nil
}
func (t *RSA) PackGivenD(d *fmp.Fmpz) {
	t.Key.D = new(fmp.Fmpz).Set(d)
	if t.CipherText != nil && t.PlainText == nil {
		t.PlainText = ln.NumberToBytes(new(fmp.Fmpz).Exp(ln.BytesToNumber(t.CipherText), t.Key.D, t.Key.PublicKey.N))
	}
}
func (t *RSA) String() string {
	var res string
	res = fmt.Sprintf("%s:\nn = %s\n", t.KeyFilename, t.Key.PublicKey.N)
	res = fmt.Sprintf("%se = %s\n", res, t.Key.PublicKey.E)
	if t.Key.D != nil {
		res = fmt.Sprintf("%sd = %s\n", res, t.Key.D)
		if len(t.Key.Primes) == 2 {
			res = fmt.Sprintf("%sp = %s\n", res, t.Key.Primes[0])
			res = fmt.Sprintf("%sq = %s\n", res, t.Key.Primes[1])
		} else {
			for i, p := range t.Key.Primes {
				res = fmt.Sprintf("%sprime[%d] = %s\n", res, i, p)
			}
		}
	}
	if len(t.CipherText) > 0 {
		res = fmt.Sprintf("%sc = %s\n", res, ln.BytesToNumber(t.CipherText))
	}
	return res
}
func (t *RSA) DumpKey() {
	fmt.Print(t.String())
}
type FMPPublicKey struct {
	N *fmp.Fmpz
	E *fmp.Fmpz
}
type CRTValue struct {
	Exp   *fmp.Fmpz  
	Coeff *fmp.Fmpz  
	R     *fmp.Fmpz  
}
type PrecomputedValues struct {
	Dp, Dq *fmp.Fmpz  
	Qinv   *fmp.Fmpz  
	CRTValues []CRTValue
}
type FMPPrivateKey struct {
	PublicKey *FMPPublicKey
	D         *fmp.Fmpz
	Primes    []*fmp.Fmpz
	N         *fmp.Fmpz
	Precomputed *PrecomputedValues
}
func BigtoFMPPrivateKey(key *x509big.BigPrivateKey) FMPPrivateKey {
	fmpPubKey := &FMPPublicKey{
		N: new(fmp.Fmpz).SetBytes(key.PublicKey.N.Bytes()),
		E: new(fmp.Fmpz).SetBytes(key.PublicKey.E.Bytes()),
	}
	var fmpPrivateKey *FMPPrivateKey
	if key.D != nil {
		fmpPrivateKey = &FMPPrivateKey{
			PublicKey: fmpPubKey,
			D:         new(fmp.Fmpz).SetBytes(key.D.Bytes()),
		}
		for _, p := range key.Primes {
			fmpPrivateKey.Primes = append(fmpPrivateKey.Primes, new(fmp.Fmpz).SetBytes(p.Bytes()))
		}
	} else {
		fmpPrivateKey = PrivateFromPublic(fmpPubKey)
	}
	return *fmpPrivateKey
}