package rsa
import (
)
type TestingOnlyLargeExponentPublicKey struct {
N *bigmod.Modulus
E []byte
}
func ( *TestingOnlyLargeExponentPublicKey) () int {
return (.N.BitLen() + 7) / 8
}
func ( *TestingOnlyLargeExponentPublicKey) error {
if .N == nil {
return errors.New("crypto/rsa: missing public modulus")
}
if .N.Nat().IsOdd() == 0 {
return errors.New("crypto/rsa: public modulus is even")
}
if .N.BitLen() < 2048 {
return errors.New("crypto/rsa: public modulus too small")
}
if .N.BitLen()%2 == 1 {
return errors.New("crypto/rsa: public modulus bit length not even")
}
:= .E
for len() > 0 && [0] == 0 {
= [1:]
}
if len() < 32/8 || (len() == 32/8 && [0] < 0x80) {
return errors.New("crypto/rsa: public exponent too small")
}
if len() > 256/8 {
return errors.New("crypto/rsa: public exponent too large")
}
if [len()-1]&1 == 0 {
return errors.New("crypto/rsa: public exponent is even")
}
return nil
}
func ( *TestingOnlyLargeExponentPublicKey, []byte) ([]byte, error) {
, := bigmod.NewNat().SetBytes(, .N)
if != nil {
return nil,
}
return bigmod.NewNat().Exp(, .E, .N).Bytes(.N), nil
}
func ( *TestingOnlyLargeExponentPublicKey, string, []byte, []byte) error {
fipsSelfTest()
fips140.RecordApproved()
checkApprovedHashName()
if := checkLargeExponentPublicKey(); != nil {
return
}
if .Size() != len() {
return ErrVerification
}
, := encryptLargeExponent(, )
if != nil {
return ErrVerification
}
, := pkcs1v15ConstructEM(&PublicKey{N: .N}, , )
if != nil {
return ErrVerification
}
if !bytes.Equal(, ) {
return ErrVerification
}
return nil
}
func ( *TestingOnlyLargeExponentPublicKey, hash.Hash, []byte, []byte) error {
fipsSelfTest()
fips140.RecordApproved()
checkApprovedHash()
if := checkLargeExponentPublicKey(); != nil {
return
}
if len() != .Size() {
return ErrVerification
}
:= .N.BitLen() - 1
:= ( + 7) / 8
, := encryptLargeExponent(, )
if != nil {
return ErrVerification
}
for len() > && len() > 0 {
if [0] != 0 {
return ErrVerification
}
= [1:]
}
return emsaPSSVerify(, , , pssSaltLengthAutodetect, )
}
type TestingOnlyLargeExponentPrivateKey struct {
n *bigmod.Modulus
e []byte
d *bigmod.Nat
p, q *bigmod.Modulus
dP []byte
dQ []byte
qInv *bigmod.Nat
}
func ( *TestingOnlyLargeExponentPrivateKey) () int {
return (.n.BitLen() + 7) / 8
}
func ( []byte, []byte, , , , , , []byte) (*TestingOnlyLargeExponentPrivateKey, error) {
, := bigmod.NewModulus()
if != nil {
return nil,
}
, := bigmod.NewModulus()
if != nil {
return nil,
}
, := bigmod.NewModulus()
if != nil {
return nil,
}
, := bigmod.NewNat().SetBytes(, )
if != nil {
return nil,
}
, := bigmod.NewNat().SetBytes(, )
if != nil {
return nil,
}
:= &TestingOnlyLargeExponentPrivateKey{
n: , e: , d: , p: , q: ,
dP: , dQ: , qInv: ,
}
if := checkLargeExponentPrivateKey(); != nil {
return nil,
}
return , nil
}
func ( *TestingOnlyLargeExponentPrivateKey) error {
:= &TestingOnlyLargeExponentPublicKey{N: .n, E: .e}
if := checkLargeExponentPublicKey(); != nil {
return
}
:= .n
:= .p
:= .q
if .BitLen() != .BitLen() {
}
:= bigmod.NewNat().ExpandFor()
if , := .SetBytes(.Nat().Bytes(), ); != nil {
return errors.New("crypto/rsa: invalid prime")
}
:= bigmod.NewNat().ExpandFor()
if , := .SetBytes(.Nat().Bytes(), ); != nil {
return errors.New("crypto/rsa: invalid prime")
}
if .Mul(, ).IsZero() != 1 {
return errors.New("crypto/rsa: p * q != n")
}
, := bigmod.NewModulus(.Nat().SubOne().Bytes())
if != nil {
return errors.New("crypto/rsa: invalid prime")
}
, := bigmod.NewNat().SetBytes(.dP, )
if != nil {
return errors.New("crypto/rsa: invalid CRT exponent")
}
:= bigmod.NewNat()
if , := .SetBytes(.e, ); != nil {
, := bigmod.NewNat().SetBytes(.e, .n)
.Mod(, )
}
.Mul(, )
if .IsOne() != 1 {
return errors.New("crypto/rsa: invalid CRT exponent")
}
, := bigmod.NewModulus(.Nat().SubOne().Bytes())
if != nil {
return errors.New("crypto/rsa: invalid prime")
}
, := bigmod.NewNat().SetBytes(.dQ, )
if != nil {
return errors.New("crypto/rsa: invalid CRT exponent")
}
if , := .SetBytes(.e, ); != nil {
, := bigmod.NewNat().SetBytes(.e, .n)
.Mod(, )
}
.Mul(, )
if .IsOne() != 1 {
return errors.New("crypto/rsa: invalid CRT exponent")
}
, := bigmod.NewNat().SetOverflowingBytes(.Nat().Bytes(), )
if != nil {
= bigmod.NewNat().Mod(.Nat(), )
}
if .Mul(.qInv, ).IsOne() != 1 {
return errors.New("crypto/rsa: invalid CRT coefficient")
}
return nil
}
func ( *TestingOnlyLargeExponentPrivateKey, []byte) ([]byte, error) {
:= .n
, := bigmod.NewNat().SetBytes(, )
if != nil {
return nil, ErrDecryption
}
, := .p, .q
:= bigmod.NewNat()
:= bigmod.NewNat().Exp(.Mod(, ), .dP, )
:= bigmod.NewNat().Exp(.Mod(, ), .dQ, )
.Sub(.Mod(, ), )
.Mul(.qInv, )
.ExpandFor().Mul(.Mod(.Nat(), ), )
.Add(.ExpandFor(), )
return .Bytes(), nil
}
func (, hash.Hash, *TestingOnlyLargeExponentPrivateKey, []byte, []byte) ([]byte, error) {
fipsSelfTest()
fips140.RecordApproved()
checkApprovedHash()
:= .Size()
if len() > || < .Size()*2+2 {
return nil, ErrDecryption
}
, := decryptLargeExponent(, )
if != nil {
return nil,
}
.Reset()
.Write()
:= .Sum(nil)
:= constanttime.ByteEq([0], 0)
:= [1 : .Size()+1]
:= [.Size()+1:]
mgf1XOR(, , )
mgf1XOR(, , )
:= [0:.Size()]
:= subtle.ConstantTimeCompare(, )
var , , int
= 1
:= [.Size():]
for := 0; < len(); ++ {
:= constanttime.ByteEq([], 0)
:= constanttime.ByteEq([], 1)
= constanttime.Select(&, , )
= constanttime.Select(, 0, )
= constanttime.Select(&^, 1, )
}
if &&^&^ != 1 {
return nil, ErrDecryption
}
return [+1:], nil
}
func (, hash.Hash, io.Reader, *TestingOnlyLargeExponentPublicKey, []byte, []byte) ([]byte, error) {
fipsSelfTest()
fips140.RecordApproved()
checkApprovedHash()
if := checkLargeExponentPublicKey(); != nil {
return nil,
}
:= .Size()
if len() > -2*.Size()-2 {
return nil, ErrMessageTooLong
}
.Reset()
.Write()
:= .Sum(nil)
:= make([]byte, )
:= [1 : 1+.Size()]
:= [1+.Size():]
copy([0:.Size()], )
[len()-len()-1] = 1
copy([len()-len():], )
if := drbg.ReadWithReader(, ); != nil {
return nil,
}
mgf1XOR(, , )
mgf1XOR(, , )
return encryptLargeExponent(, )
}