"crypto/elliptic"
"crypto/sha512"
"encoding/asn1"
+ "errors"
"io"
"math/big"
)
return new(big.Int).Exp(k, nMinus2, N)
}
+var errZeroParam = errors.New("zero parameter")
+
// Sign signs an arbitrary length hash (which should be the result of hashing a
// larger message) using the private key, priv. It returns the signature as a
// pair of integers. The security of the private key depends on the entropy of
// See [NSA] 3.4.1
c := priv.PublicKey.Curve
N := c.Params().N
-
+ if N.Sign() == 0 {
+ return nil, nil, errZeroParam
+ }
var k, kInv *big.Int
for {
for {
if in, ok := priv.Curve.(invertible); ok {
kInv = in.Inverse(k)
} else {
- kInv = fermatInverse(k, N)
+ kInv = fermatInverse(k, N) // N != 0
}
r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
s = new(big.Int).Mul(priv.D, r)
s.Add(s, e)
s.Mul(s, kInv)
- s.Mod(s, N)
+ s.Mod(s, N) // N != 0
if s.Sign() != 0 {
break
}
err = ErrDecryption
return
}
+ if priv.N.Sign() == 0 {
+ return nil, ErrDecryption
+ }
var ir *big.Int
if random != nil {
}
}
bigE := big.NewInt(int64(priv.E))
- rpowe := new(big.Int).Exp(r, bigE, priv.N)
+ rpowe := new(big.Int).Exp(r, bigE, priv.N) // N != 0
cCopy := new(big.Int).Set(c)
cCopy.Mul(cCopy, rpowe)
cCopy.Mod(cCopy, priv.N)