func testKeyGeneration(t *testing.T, c *bitelliptic.BitCurve, tag string) {
	priv, err := GenerateKey(c, rand.Reader)
	if err != nil {
		t.Errorf("%s: error: %s", tag, err)
		return
	}
	if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) {
		t.Errorf("%s: public key invalid: %s", tag, err)
	}
}
Exemplo n.º 2
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
}