Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/ecdsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
#include "scalar.h"
#include "group.h"

static void secp256k1_ecsda_start(void);
static void secp256k1_ecdsa_stop(void);

typedef struct {
secp256k1_scalar_t r, s;
} secp256k1_ecdsa_sig_t;
Expand All @@ -22,6 +19,5 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message);
static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid);
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid);
static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s);

#endif
42 changes: 19 additions & 23 deletions src/ecdsa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,32 +98,33 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const se
secp256k1_fe_t xr;
secp256k1_fe_set_b32(&xr, c);

// We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
// in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p),
// compute the remainder modulo n, and compare it to xr. However:
//
// xr == X(pr) mod n
// <=> exists h. (xr + h * n < p && xr + h * n == X(pr))
// [Since 2 * n > p, h can only be 0 or 1]
// <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr))
// [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p]
// <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p)
// [Multiplying both sides of the equations by pr.z^2 mod p]
// <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x)
//
// Thus, we can avoid the inversion, but we have to check both cases separately.
// secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test.
/** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
* in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p),
* compute the remainder modulo n, and compare it to xr. However:
*
* xr == X(pr) mod n
* <=> exists h. (xr + h * n < p && xr + h * n == X(pr))
* [Since 2 * n > p, h can only be 0 or 1]
* <=> (xr == X(pr)) || (xr + n < p && xr + n == X(pr))
* [In Jacobian coordinates, X(pr) is pr.x / pr.z^2 mod p]
* <=> (xr == pr.x / pr.z^2 mod p) || (xr + n < p && xr + n == pr.x / pr.z^2 mod p)
* [Multiplying both sides of the equations by pr.z^2 mod p]
* <=> (xr * pr.z^2 mod p == pr.x) || (xr + n < p && (xr + n) * pr.z^2 mod p == pr.x)
*
* Thus, we can avoid the inversion, but we have to check both cases separately.
* secp256k1_gej_eq_x implements the (xr * pr.z^2 mod p == pr.x) test.
*/
if (secp256k1_gej_eq_x_var(&xr, &pr)) {
// xr.x == xr * xr.z^2 mod p, so the signature is valid.
/* xr.x == xr * xr.z^2 mod p, so the signature is valid. */
return 1;
}
if (secp256k1_fe_cmp_var(&xr, &secp256k1_ecdsa_const_p_minus_order) >= 0) {
// xr + p >= n, so we can skip testing the second case.
/* xr + p >= n, so we can skip testing the second case. */
return 0;
}
secp256k1_fe_add(&xr, &secp256k1_ecdsa_const_order_as_fe);
if (secp256k1_gej_eq_x_var(&xr, &pr)) {
// (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid.
/* (xr + n) * pr.z^2 mod p == pr.x, so the signature is valid. */
return 1;
}
return 0;
Expand Down Expand Up @@ -195,9 +196,4 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_
return 1;
}

static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s) {
sig->r = *r;
sig->s = *s;
}

#endif
2 changes: 1 addition & 1 deletion src/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a);
/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be
* at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and
* outputs must not overlap in memory. */
static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]);
static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a);

/** Convert a field element to a hexadecimal string. */
static void secp256k1_fe_get_hex(char *r, int *rlen, const secp256k1_fe_t *a);
Expand Down
4 changes: 2 additions & 2 deletions src/field_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static void secp256k1_fe_get_hex(char *r, int *rlen, const secp256k1_fe_t *a) {
}

static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) {
unsigned char tmp[32] = {};
unsigned char tmp[32] = {0};
static const int cvt[256] = {0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0,
Expand Down Expand Up @@ -227,7 +227,7 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
#endif
}

static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t r[len], const secp256k1_fe_t a[len]) {
static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a) {
if (len < 1)
return;

Expand Down
2 changes: 1 addition & 1 deletion src/group.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a);
static void secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a);

/** Set a batch of group elements equal to the inputs given in jacobian coordinates */
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t r[len], const secp256k1_gej_t a[len]);
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a);


/** Set a group element (jacobian) equal to the point at infinity. */
Expand Down
9 changes: 5 additions & 4 deletions src/group_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static void secp256k1_ge_set_gej_var(secp256k1_ge_t *r, secp256k1_gej_t *a) {
r->y = a->y;
}

static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t r[len], const secp256k1_gej_t a[len]) {
static void secp256k1_ge_set_all_gej_var(size_t len, secp256k1_ge_t *r, const secp256k1_gej_t *a) {
size_t count = 0;
secp256k1_fe_t *az = checked_malloc(sizeof(secp256k1_fe_t) * len);
for (size_t i=0; i<len; i++) {
Expand Down Expand Up @@ -220,9 +220,10 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) {
}

static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
// For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity,
// Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have
// y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p.
/** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity,
* Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have
* y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p.
*/
r->infinity = a->infinity;
if (r->infinity) {
return;
Expand Down
6 changes: 3 additions & 3 deletions src/hash_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,21 +128,21 @@ static void secp256k1_sha256_write(secp256k1_sha256_t *hash, const unsigned char
const unsigned char* end = data + len;
size_t bufsize = hash->bytes % 64;
if (bufsize && bufsize + len >= 64) {
// Fill the buffer, and process it.
/* Fill the buffer, and process it. */
memcpy(hash->buf + bufsize, data, 64 - bufsize);
hash->bytes += 64 - bufsize;
data += 64 - bufsize;
secp256k1_sha256_transform(hash->s, hash->buf);
bufsize = 0;
}
while (end >= data + 64) {
// Process full chunks directly from the source.
/* Process full chunks directly from the source. */
secp256k1_sha256_transform(hash->s, data);
hash->bytes += 64;
data += 64;
}
if (end > data) {
// Fill the buffer with what remains.
/* Fill the buffer with what remains. */
memcpy(hash->buf + bufsize, data, end - data);
hash->bytes += end - data;
}
Expand Down
2 changes: 1 addition & 1 deletion src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
#define VERIFY_CHECK(cond) do { (void)(cond); } while(0)
#endif

static inline void *checked_malloc(size_t size) {
static SECP256K1_INLINE void *checked_malloc(size_t size) {
void *ret = malloc(size);
CHECK(ret != NULL);
return ret;
Expand Down