//TODO: add to tests, new functionality
// GenerateKey generates a key pair of public key matching the given private key.
func GenerateFromPrivateKey(d *big.Int, c *bitelliptic.BitCurve) (priv *PrivateKey, err error) {
	if CheckIsOnCurve(c, d) == false {
		return nil, nil
	}

	priv = new(PrivateKey)
	priv.PublicKey.BitCurve = c
	priv.D = d
	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(d.Bytes())
	return
}
// GenerateKey generates a public&private key pair.
func GenerateKey(c *bitelliptic.BitCurve, rand io.Reader) (priv *PrivateKey, err os.Error) {
	k, err := randFieldElement(c, rand)
	if err != nil {
		return
	}

	priv = new(PrivateKey)
	priv.PublicKey.BitCurve = c
	priv.D = k
	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
	return
}
示例#3
0
func RecoverPubKeyFromSignature(r, s *big.Int, msg []byte, curve *bitelliptic.BitCurve, recid uint) (qx, qy *big.Int, err error) {
	if recid > 3 {
		return nil, nil, fmt.Errorf("Illegal recid %v - must be in 0..3", recid)
	}
	order := curve.N
	i := recid / 2
	field := curve.P
	x := new(big.Int).Set(order)
	x.Mul(x, big.NewInt(int64(i)))
	x.Add(x, r)
	if x.Cmp(field) >= 0 {
		err = fmt.Errorf("%v >= %v", x, field)
		return
	}

	rx, ry, err := uncompressPoint(x, curve, 0 == (recid%2))
	if err != nil {
		return nil, nil, err
	}
	if !curve.IsOnCurve(rx, ry) {
		return nil, nil, fmt.Errorf("Point %d, %d not on curve", rx, ry)
	}

	e := new(big.Int).SetBytes(msg)
	if 8*len(msg) > curve.BitSize {
		e.Rsh(e, uint(8-(curve.BitSize&7)))
	}
	e.Neg(e).Mod(e, order)

	var rr, sor, eor big.Int
	rr.ModInverse(r, order)
	//return nil, nil, fmt.Errorf("r: %d, r_inv: %d", r, &rr)
	//Q = (R.multiply(s).add(G.multiply(minus_e))).multiply(inv_r);
	sor.Mul(s, &rr)
	eor.Mul(e, &rr)

	Georx, Geory := curve.ScalarBaseMult(eor.Bytes())
	Rsorx, Rsory := curve.ScalarMult(rx, ry, sor.Bytes())
	qx, qy = curve.Add(Georx, Geory, Rsorx, Rsory)

	return
}