|
30 | 30 |
|
31 | 31 | #include <boost/test/unit_test.hpp>
|
32 | 32 |
|
| 33 | +#include <secp256k1.h> |
33 | 34 | #include <univalue.h>
|
34 | 35 |
|
35 | 36 | // Uncomment if you want to output updated JSON tests.
|
@@ -144,25 +145,17 @@ void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
|
144 | 145 | r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
|
145 | 146 | s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
|
146 | 147 |
|
147 |
| - // Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1. |
148 |
| - static const unsigned char order[33] = { |
149 |
| - 0x00, |
150 |
| - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, |
151 |
| - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, |
152 |
| - 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, |
153 |
| - 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 |
154 |
| - }; |
155 | 148 | while (s.size() < 33) {
|
156 | 149 | s.insert(s.begin(), 0x00);
|
157 | 150 | }
|
158 |
| - int carry = 0; |
159 |
| - for (int p = 32; p >= 1; p--) { |
160 |
| - int n = (int)order[p] - s[p] - carry; |
161 |
| - s[p] = (n + 256) & 0xFF; |
162 |
| - carry = (n < 0); |
163 |
| - } |
164 |
| - assert(carry == 0); |
165 |
| - if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) { |
| 151 | + assert(s[0] == 0); |
| 152 | + // Perform mod-n negation of s by (ab)using libsecp256k1 |
| 153 | + // (note that this function is meant to be used for negating secret keys, |
| 154 | + // but it works for any non-zero scalar modulo the group order, i.e. also for s) |
| 155 | + int ret = secp256k1_ec_seckey_negate(secp256k1_context_static, s.data() + 1); |
| 156 | + assert(ret); |
| 157 | + |
| 158 | + if (s[1] < 0x80) { |
166 | 159 | s.erase(s.begin());
|
167 | 160 | }
|
168 | 161 |
|
|
0 commit comments