]> Git Repo - secp256k1.git/blob - ecdsa.cpp
Split headers/code
[secp256k1.git] / ecdsa.cpp
1 #include "num.h"
2 #include "field.h"
3 #include "group.h"
4 #include "ecmult.h"
5 #include "ecdsa.h"
6
7 namespace secp256k1 {
8
9 bool ParsePubKey(GroupElemJac &elem, const unsigned char *pub, int size) {
10     if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
11         FieldElem x;
12         x.SetBytes(pub+1);
13         elem.SetCompressed(x, pub[0] == 0x03);
14     } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
15         FieldElem x,y;
16         x.SetBytes(pub+1);
17         y.SetBytes(pub+33);
18         elem = GroupElem(x,y);
19         if ((pub[0] == 0x06 || pub[0] == 0x07) && y.IsOdd() != (pub[0] == 0x07))
20             return false;
21     } else {
22         return false;
23     }
24     return elem.IsValid();
25 }
26
27 bool Signature::Parse(const unsigned char *sig, int size) {
28     if (sig[0] != 0x30) return false;
29     int lenr = sig[3];
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);
40     return true;
41 }
42
43 bool Signature::RecomputeR(Number &r2, const GroupElemJac &pubkey, const Number &message) {
44     const GroupConstants &c = GetGroupConst();
45
46     if (r.IsNeg() || s.IsNeg())
47         return false;
48     if (r.IsZero() || s.IsZero())
49         return false;
50     if (r.Compare(c.order) >= 0 || s.Compare(c.order) >= 0)
51         return false;
52
53     Number sn, u1, u2;
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);
58     if (pr.IsInfinity())
59         return false;
60     FieldElem xr; pr.GetX(xr);
61     unsigned char xrb[32]; xr.GetBytes(xrb);
62     r2.SetBytes(xrb,32); r2.SetMod(r2,c.order);
63     return true;
64 }
65
66 bool Signature::Verify(const GroupElemJac &pubkey, const Number &message) {
67     Number r2;
68     if (!RecomputeR(r2, pubkey, message))
69         return false;
70     return r2.Compare(r) == 0;
71 }
72
73 void Signature::SetRS(const Number &rin, const Number &sin) {
74     r = rin;
75     s = sin;
76 }
77
78 std::string Signature::ToString() const {
79     return "(" + r.ToString() + "," + s.ToString() + ")";
80 }
81
82 }
This page took 0.027008 seconds and 4 git commands to generate.