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) } }
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 }