9 bool ParsePubKey(GroupElemJac &elem, const unsigned char *pub, int size) {
10 if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
13 elem.SetCompressed(x, pub[0] == 0x03);
14 } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
18 elem = GroupElem(x,y);
19 if ((pub[0] == 0x06 || pub[0] == 0x07) && y.IsOdd() != (pub[0] == 0x07))
24 return elem.IsValid();
27 bool Signature::Parse(const unsigned char *sig, int size) {
28 if (sig[0] != 0x30) return false;
30 if (5+lenr >= size) return false;
31 int lens = sig[lenr+5];
32 if (sig[1] != lenr+lens+4) return false;
33 if (lenr+lens+6 > size) return false;
34 if (sig[2] != 0x02) return false;
35 if (lenr == 0) return false;
36 if (sig[lenr+4] != 0x02) return false;
37 if (lens == 0) return false;
38 r.SetBytes(sig+4, lenr);
39 s.SetBytes(sig+6+lenr, lens);
43 bool Signature::RecomputeR(Number &r2, const GroupElemJac &pubkey, const Number &message) {
44 const GroupConstants &c = GetGroupConst();
46 if (r.IsNeg() || s.IsNeg())
48 if (r.IsZero() || s.IsZero())
50 if (r.Compare(c.order) >= 0 || s.Compare(c.order) >= 0)
54 sn.SetModInverse(s, c.order);
55 u1.SetModMul(sn, message, c.order);
56 u2.SetModMul(sn, r, c.order);
57 GroupElemJac pr; ECMult(pr, pubkey, u2, u1);
60 FieldElem xr; pr.GetX(xr);
61 unsigned char xrb[32]; xr.GetBytes(xrb);
62 r2.SetBytes(xrb,32); r2.SetMod(r2,c.order);
66 bool Signature::Verify(const GroupElemJac &pubkey, const Number &message) {
68 if (!RecomputeR(r2, pubkey, message))
70 return r2.Compare(r) == 0;
73 void Signature::SetRS(const Number &rin, const Number &sin) {
78 std::string Signature::ToString() const {
79 return "(" + r.ToString() + "," + s.ToString() + ")";