Skip to content

Commit

Permalink
Merge pull request bitcoin#206
Browse files Browse the repository at this point in the history
34b898d Additional comments for the testing PRNG and a seeding fix. (Gregory Maxwell)
6efd6e7 Some comments explaining some of the constants in the code. (Gregory Maxwell)
  • Loading branch information
sipa committed Feb 13, 2015
2 parents 2d4cd53 + 34b898d commit 035406d
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 2 deletions.
22 changes: 22 additions & 0 deletions src/ecdsa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,33 @@
#include "ecmult_gen.h"
#include "ecdsa.h"

/** Group order for secp256k1 defined as 'n' in "Standards for Efficient Cryptography" (SEC2) 2.7.1
* sage: for t in xrange(1023, -1, -1):
* .. p = 2**256 - 2**32 - t
* .. if p.is_prime():
* .. print '%x'%p
* .. break
* 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'
* sage: a = 0
* sage: b = 7
* sage: F = FiniteField (p)
* sage: '%x' % (EllipticCurve ([F (a), F (b)]).order())
* 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'
*/
static const secp256k1_fe_t secp256k1_ecdsa_const_order_as_fe = SECP256K1_FE_CONST(
0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFFUL, 0xFFFFFFFEUL,
0xBAAEDCE6UL, 0xAF48A03BUL, 0xBFD25E8CUL, 0xD0364141UL
);

/** Difference between field and order, values 'p' and 'n' values defined in
* "Standards for Efficient Cryptography" (SEC2) 2.7.1.
* sage: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
* sage: a = 0
* sage: b = 7
* sage: F = FiniteField (p)
* sage: '%x' % (p - EllipticCurve ([F (a), F (b)]).order())
* '14551231950b75fc4402da1722fc9baee'
*/
static const secp256k1_fe_t secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_CONST(
0, 0, 0, 1, 0x45512319UL, 0x50B75FC4UL, 0x402DA172UL, 0x2FC9BAEEUL
);
Expand Down
1 change: 1 addition & 0 deletions src/field_10x26.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ typedef struct {
#endif
} secp256k1_fe_t;

/* Unpacks a constant into a overlapping multi-limbed FE element. */
#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \
(d0) & 0x3FFFFFFUL, \
((d0) >> 26) | ((d1) & 0xFFFFFUL) << 6, \
Expand Down
1 change: 1 addition & 0 deletions src/field_5x52.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ typedef struct {
#endif
} secp256k1_fe_t;

/* Unpacks a constant into a overlapping multi-limbed FE element. */
#define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \
(d0) | ((uint64_t)(d1) & 0xFFFFFUL) << 32, \
((d1) >> 20) | ((uint64_t)(d2)) << 12 | ((uint64_t)(d3) & 0xFFUL) << 44, \
Expand Down
1 change: 1 addition & 0 deletions src/field_5x52_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
static void secp256k1_fe_verify(const secp256k1_fe_t *a) {
const uint64_t *d = a->n;
int m = a->normalized ? 1 : 2 * a->magnitude, r = 1;
/* secp256k1 'p' value defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m);
r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m);
r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m);
Expand Down
3 changes: 3 additions & 0 deletions src/field_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ static void secp256k1_fe_get_hex(char *r64, const secp256k1_fe_t *a) {
secp256k1_fe_normalize(&b);
secp256k1_fe_get_b32(tmp, &b);
for (i=0; i<32; i++) {
/* Hex character table. */
static const char *c = "0123456789ABCDEF";
r64[2*i] = c[(tmp[i] >> 4) & 0xF];
r64[2*i+1] = c[(tmp[i]) & 0xF];
Expand All @@ -38,6 +39,7 @@ static void secp256k1_fe_get_hex(char *r64, const secp256k1_fe_t *a) {
static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a64) {
int i;
unsigned char tmp[32];
/* Byte to hex value table. */
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 @@ -203,6 +205,7 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
secp256k1_fe_inv(r, a);
#elif defined(USE_FIELD_INV_NUM)
secp256k1_num_t n, m;
/* secp256k1 field prime, value p defined in "Standards for Efficient Cryptography" (SEC2) 2.7.1. */
static const unsigned char prime[32] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
Expand Down
3 changes: 3 additions & 0 deletions src/group_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include "field.h"
#include "group.h"

/** Generator for secp256k1, value 'g' defined in
* "Standards for Efficient Cryptography" (SEC2) 2.7.1.
*/
static const secp256k1_ge_t secp256k1_ge_const_g = {
SECP256K1_FE_CONST(
0x79BE667EUL, 0xF9DCBBACUL, 0x55A06295UL, 0xCE870B07UL,
Expand Down
1 change: 1 addition & 0 deletions src/scalar_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_
secp256k1_num_set_bin(r, c, 32);
}

/** secp256k1 curve order, see secp256k1_ecdsa_const_order_as_fe in ecdsa_impl.h */
static void secp256k1_scalar_order_get_num(secp256k1_num_t *r) {
static const unsigned char order[32] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
Expand Down
4 changes: 3 additions & 1 deletion src/testrand.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
#include "libsecp256k1-config.h"
#endif

/** Seed the pseudorandom number generator. */
/* A non-cryptographic RNG used only for test infrastructure. */

/** Seed the pseudorandom number generator for testing. */
SECP256K1_INLINE static void secp256k1_rand_seed(uint64_t v);

/** Generate a pseudorandom 32-bit number. */
Expand Down
6 changes: 5 additions & 1 deletion src/testrand_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@ SECP256K1_INLINE static void secp256k1_rand_seed(uint64_t v) {
secp256k1_Rz = v >> 32;
secp256k1_Rw = v;

/* There are two seeds with short (length 1) cycles for the Rz PRNG. */
if (secp256k1_Rz == 0 || secp256k1_Rz == 0x9068ffffU) {
secp256k1_Rz = 111;
}
if (secp256k1_Rw == 0 || secp256k1_Rw == 0x464fffffU) {
/* There are four seeds with short (length 1) cycles for the Rw PRNG. */
if (secp256k1_Rw == 0 || secp256k1_Rw == 0x464fffffU ||
secp256k1_Rw == 0x8c9ffffeU || secp256k1_Rw == 0xd2effffdU) {
secp256k1_Rw = 111;
}
}

SECP256K1_INLINE static uint32_t secp256k1_rand32(void) {
/* MWC PRNG for tests. */
secp256k1_Rz = 36969 * (secp256k1_Rz & 0xFFFF) + (secp256k1_Rz >> 16);
secp256k1_Rw = 18000 * (secp256k1_Rw & 0xFFFF) + (secp256k1_Rw >> 16);
return (secp256k1_Rw << 16) + (secp256k1_Rw >> 16) + secp256k1_Rz;
Expand Down

0 comments on commit 035406d

Please sign in to comment.