]>
Commit | Line | Data |
---|---|---|
1 | #ifndef _SECP256K1_ECDSA_IMPL_H_ | |
2 | #define _SECP256K1_ECDSA_IMPL_H_ | |
3 | ||
4 | #include "../num.h" | |
5 | #include "../field.h" | |
6 | #include "../group.h" | |
7 | #include "../ecmult.h" | |
8 | #include "../ecdsa.h" | |
9 | ||
10 | void static secp256k1_ecdsa_sig_init(secp256k1_ecdsa_sig_t *r) { | |
11 | secp256k1_num_init(&r->r); | |
12 | secp256k1_num_init(&r->s); | |
13 | } | |
14 | ||
15 | void static secp256k1_ecdsa_sig_free(secp256k1_ecdsa_sig_t *r) { | |
16 | secp256k1_num_free(&r->r); | |
17 | secp256k1_num_free(&r->s); | |
18 | } | |
19 | ||
20 | int static secp256k1_ecdsa_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) { | |
21 | if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) { | |
22 | secp256k1_fe_t x; | |
23 | secp256k1_fe_set_b32(&x, pub+1); | |
24 | secp256k1_ge_set_xo(elem, &x, pub[0] == 0x03); | |
25 | } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { | |
26 | secp256k1_fe_t x, y; | |
27 | secp256k1_fe_set_b32(&x, pub+1); | |
28 | secp256k1_fe_set_b32(&y, pub+33); | |
29 | secp256k1_ge_set_xy(elem, &x, &y); | |
30 | if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) | |
31 | return 0; | |
32 | } else { | |
33 | return 0; | |
34 | } | |
35 | return secp256k1_ge_is_valid(elem); | |
36 | } | |
37 | ||
38 | int static secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) { | |
39 | if (sig[0] != 0x30) return 0; | |
40 | int lenr = sig[3]; | |
41 | if (5+lenr >= size) return 0; | |
42 | int lens = sig[lenr+5]; | |
43 | if (sig[1] != lenr+lens+4) return 0; | |
44 | if (lenr+lens+6 > size) return 0; | |
45 | if (sig[2] != 0x02) return 0; | |
46 | if (lenr == 0) return 0; | |
47 | if (sig[lenr+4] != 0x02) return 0; | |
48 | if (lens == 0) return 0; | |
49 | secp256k1_num_set_bin(&r->r, sig+4, lenr); | |
50 | secp256k1_num_set_bin(&r->s, sig+6+lenr, lens); | |
51 | return 1; | |
52 | } | |
53 | ||
54 | int static secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) { | |
55 | int lenR = (secp256k1_num_bits(&a->r) + 7)/8; | |
56 | if (lenR == 0 || secp256k1_num_get_bit(&a->r, lenR*8-1)) | |
57 | lenR++; | |
58 | int lenS = (secp256k1_num_bits(&a->s) + 7)/8; | |
59 | if (lenS == 0 || secp256k1_num_get_bit(&a->s, lenS*8-1)) | |
60 | lenS++; | |
61 | if (*size < 6+lenS+lenR) | |
62 | return 0; | |
63 | *size = 6 + lenS + lenR; | |
64 | sig[0] = 0x30; | |
65 | sig[1] = 4 + lenS + lenR; | |
66 | sig[2] = 0x02; | |
67 | sig[3] = lenR; | |
68 | secp256k1_num_get_bin(sig+4, lenR, &a->r); | |
69 | sig[4+lenR] = 0x02; | |
70 | sig[5+lenR] = lenS; | |
71 | secp256k1_num_get_bin(sig+lenR+6, lenS, &a->s); | |
72 | return 1; | |
73 | } | |
74 | ||
75 | int static secp256k1_ecdsa_sig_recompute(secp256k1_num_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message) { | |
76 | const secp256k1_ge_consts_t *c = secp256k1_ge_consts; | |
77 | ||
78 | if (secp256k1_num_is_neg(&sig->r) || secp256k1_num_is_neg(&sig->s)) | |
79 | return 0; | |
80 | if (secp256k1_num_is_zero(&sig->r) || secp256k1_num_is_zero(&sig->s)) | |
81 | return 0; | |
82 | if (secp256k1_num_cmp(&sig->r, &c->order) >= 0 || secp256k1_num_cmp(&sig->s, &c->order) >= 0) | |
83 | return 0; | |
84 | ||
85 | int ret = 0; | |
86 | secp256k1_num_t sn, u1, u2; | |
87 | secp256k1_num_init(&sn); | |
88 | secp256k1_num_init(&u1); | |
89 | secp256k1_num_init(&u2); | |
90 | secp256k1_num_mod_inverse(&sn, &sig->s, &c->order); | |
91 | secp256k1_num_mod_mul(&u1, &sn, message, &c->order); | |
92 | secp256k1_num_mod_mul(&u2, &sn, &sig->r, &c->order); | |
93 | secp256k1_gej_t pubkeyj; secp256k1_gej_set_ge(&pubkeyj, pubkey); | |
94 | secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1); | |
95 | if (!secp256k1_gej_is_infinity(&pr)) { | |
96 | secp256k1_fe_t xr; secp256k1_gej_get_x(&xr, &pr); | |
97 | secp256k1_fe_normalize(&xr); | |
98 | unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr); | |
99 | secp256k1_num_set_bin(r2, xrb, 32); | |
100 | secp256k1_num_mod(r2, &c->order); | |
101 | ret = 1; | |
102 | } | |
103 | secp256k1_num_free(&sn); | |
104 | secp256k1_num_free(&u1); | |
105 | secp256k1_num_free(&u2); | |
106 | return ret; | |
107 | } | |
108 | ||
109 | int static secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message) { | |
110 | secp256k1_num_t r2; | |
111 | secp256k1_num_init(&r2); | |
112 | int ret = 0; | |
113 | ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_num_cmp(&sig->r, &r2) == 0; | |
114 | secp256k1_num_free(&r2); | |
115 | return ret; | |
116 | } | |
117 | ||
118 | int static secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *seckey, const secp256k1_num_t *message, const secp256k1_num_t *nonce) { | |
119 | const secp256k1_ge_consts_t *c = secp256k1_ge_consts; | |
120 | ||
121 | secp256k1_gej_t rp; | |
122 | secp256k1_ecmult_gen(&rp, nonce); | |
123 | secp256k1_fe_t rx; | |
124 | secp256k1_gej_get_x(&rx, &rp); | |
125 | unsigned char b[32]; | |
126 | secp256k1_fe_normalize(&rx); | |
127 | secp256k1_fe_get_b32(b, &rx); | |
128 | secp256k1_num_set_bin(&sig->r, b, 32); | |
129 | secp256k1_num_mod(&sig->r, &c->order); | |
130 | secp256k1_num_t n; | |
131 | secp256k1_num_init(&n); | |
132 | secp256k1_num_mod_mul(&n, &sig->r, seckey, &c->order); | |
133 | secp256k1_num_add(&n, &n, message); | |
134 | secp256k1_num_mod(&n, &c->order); | |
135 | secp256k1_num_mod_inverse(&sig->s, nonce, &c->order); | |
136 | secp256k1_num_mod_mul(&sig->s, &sig->s, &n, &c->order); | |
137 | secp256k1_num_free(&n); | |
138 | if (secp256k1_num_is_zero(&sig->s)) | |
139 | return 0; | |
140 | if (secp256k1_num_is_odd(&sig->s)) | |
141 | secp256k1_num_sub(&sig->s, &c->order, &sig->s); | |
142 | return 1; | |
143 | } | |
144 | ||
145 | void static secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s) { | |
146 | secp256k1_num_copy(&sig->r, r); | |
147 | secp256k1_num_copy(&sig->s, s); | |
148 | } | |
149 | ||
150 | void static secp256k1_ecdsa_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed) { | |
151 | secp256k1_fe_normalize(&elem->x); | |
152 | secp256k1_fe_normalize(&elem->y); | |
153 | secp256k1_fe_get_b32(&pub[1], &elem->x); | |
154 | if (compressed) { | |
155 | *size = 33; | |
156 | pub[0] = 0x02 | (secp256k1_fe_is_odd(&elem->y) ? 0x01 : 0x00); | |
157 | } else { | |
158 | *size = 65; | |
159 | pub[0] = 0x04; | |
160 | secp256k1_fe_get_b32(&pub[33], &elem->y); | |
161 | } | |
162 | } | |
163 | ||
164 | #endif |