Updated so that private keys are always the correct length.

Specifically, the private key for secp160r1 is now required to be
21 bytes. Added some comments about buffer sizes.
diff --git a/curve-specific.inc b/curve-specific.inc
index 07676e1..9d8cd7f 100644
--- a/curve-specific.inc
+++ b/curve-specific.inc
@@ -17,8 +17,6 @@
 #define num_words_secp256r1 32
 #define num_words_secp256k1 32
 
-#define num_n_words_secp160r1 21
-
 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \
     0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h
 #define BYTES_TO_WORDS_4(a, b, c, d) 0x##a, 0x##b, 0x##c, 0x##d
@@ -31,8 +29,6 @@
 #define num_words_secp256r1 8
 #define num_words_secp256k1 8
 
-#define num_n_words_secp160r1 6
-
 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e
 #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a
 
@@ -44,13 +40,13 @@
 #define num_words_secp256r1 4
 #define num_words_secp256k1 4
 
-#define num_n_words_secp160r1 3
-
 #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##ull
 #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##ull
 
 #endif /* uECC_WORD_SIZE */
 
+#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \
+    uECC_SUPPORTS_secp224r1 || uECC_SUPPORTS_secp256r1
 static void double_jacobian_default(uECC_word_t * X1,
                                     uECC_word_t * Y1,
                                     uECC_word_t * Z1,
@@ -98,7 +94,21 @@
     uECC_vli_set(Y1, t4, num_words);
 }
 
+/* Computes result = x^3 + ax + b. result must not overlap x. */
+static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) {
+    uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */
+    wordcount_t num_words = curve->num_words;
+
+    uECC_vli_modSquare_fast(result, x, curve);                             /* r = x^2 */
+    uECC_vli_modSub(result, result, _3, curve->p, num_words);       /* r = x^2 - 3 */
+    uECC_vli_modMult_fast(result, result, x, curve);                       /* r = x^3 - 3x */
+    uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */
+}
+#endif /* uECC_SUPPORTS_secp... */
+
 #if uECC_SUPPORT_COMPRESSED_POINT
+#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \
+    uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1
 /* Compute a = sqrt(a) (mod curve_p). */
 static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) {
     bitcount_t i;
@@ -117,18 +127,8 @@
     }
     uECC_vli_set(a, l_result, num_words);
 }
-#endif
-
-/* Computes result = x^3 + ax + b. result must not overlap x. */
-static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) {
-    uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */
-    wordcount_t num_words = curve->num_words;
-
-    uECC_vli_modSquare_fast(result, x, curve);                             /* r = x^2 */
-    uECC_vli_modSub(result, result, _3, curve->p, num_words);       /* r = x^2 - 3 */
-    uECC_vli_modMult_fast(result, result, x, curve);                       /* r = x^3 - 3x */
-    uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */
-}
+#endif /* uECC_SUPPORTS_secp... */
+#endif /* uECC_SUPPORT_COMPRESSED_POINT */
 
 #if uECC_SUPPORTS_secp160r1
 
@@ -138,8 +138,8 @@
 
 static const struct uECC_Curve_t curve_secp160r1 = {
     num_words_secp160r1,
-    num_n_words_secp160r1,
     num_bytes_secp160r1,
+    161, /* num_n_bits */
     { BYTES_TO_WORDS_8(FF, FF, FF, 7F, FF, FF, FF, FF),
         BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
         BYTES_TO_WORDS_4(FF, FF, FF, FF) },
@@ -283,8 +283,8 @@
 
 static const struct uECC_Curve_t curve_secp192r1 = {
     num_words_secp192r1,
-    num_words_secp192r1,
     num_bytes_secp192r1,
+    192, /* num_n_bits */
     { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
         BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF),
         BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) },
@@ -382,7 +382,7 @@
     uECC_vli_set(result, product, num_words_secp192r1);
     
     uECC_vli_set(tmp, &product[3], num_words_secp192r1);
-    carry = uECC_vli_add(result, result, tmp, num_words_secp192r1);
+    carry = (int)uECC_vli_add(result, result, tmp, num_words_secp192r1);
     
     tmp[0] = 0;
     tmp[1] = product[3];
@@ -413,8 +413,8 @@
 
 static const struct uECC_Curve_t curve_secp224r1 = {
     num_words_secp224r1,
-    num_words_secp224r1,
     num_bytes_secp224r1,
+    224, /* num_n_bits */
     { BYTES_TO_WORDS_8(01, 00, 00, 00, 00, 00, 00, 00),
         BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF),
         BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
@@ -735,8 +735,8 @@
 
 static const struct uECC_Curve_t curve_secp256r1 = {
     num_words_secp256r1,
-    num_words_secp256r1,
     num_bytes_secp256r1,
+    256, /* num_n_bits */
     { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
         BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00),
         BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00),
@@ -990,7 +990,7 @@
     tmp[1] = product[5] & 0xffffffff00000000ull;
     tmp[2] = product[6];
     tmp[3] = product[7];
-    carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1);
+    carry = (int)uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1);
     carry += uECC_vli_add(result, result, tmp, num_words_secp256r1);
     
     /* s2 */
@@ -1070,8 +1070,8 @@
 
 static const struct uECC_Curve_t curve_secp256k1 = {
     num_words_secp256k1,
-    num_words_secp256k1,
     num_bytes_secp256k1,
+    256, /* num_n_bits */
     { BYTES_TO_WORDS_8(2F, FC, FF, FF, FE, FF, FF, FF),
         BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
         BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
diff --git a/uECC.c b/uECC.c
index 70b8ce4..8ee63d0 100644
--- a/uECC.c
+++ b/uECC.c
@@ -39,10 +39,13 @@
     #define uECC_MAX_WORDS ((uECC_MAX_BYTES + 7) / 8)
 #endif /* uECC_WORD_SIZE */
 
+#define BITS_TO_WORDS(num_bits) ((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8))
+#define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8)
+
 struct uECC_Curve_t {
     wordcount_t num_words;
-    wordcount_t num_n_words;
     wordcount_t num_bytes;
+    bitcount_t num_n_bits;
     uECC_word_t p[uECC_MAX_WORDS];
     uECC_word_t n[uECC_MAX_WORDS];
     uECC_word_t G[uECC_MAX_WORDS * 2];
@@ -769,11 +772,11 @@
                                 uECC_word_t *k0,
                                 uECC_word_t *k1,
                                 uECC_Curve curve) {
-    wordcount_t num_n_words = curve->num_n_words;
-    bitcount_t num_bits = uECC_vli_numBits(curve->n, num_n_words);
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    bitcount_t num_n_bits = curve->num_n_bits;
     uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) ||
-        (num_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) &&
-         uECC_vli_testBit(k0, num_bits));
+        (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) &&
+         uECC_vli_testBit(k0, num_n_bits));
     uECC_vli_add(k1, k0, curve->n, num_n_words);
     return carry;
 }
@@ -791,7 +794,7 @@
         return 0;
     }
 
-    if (uECC_vli_cmp(curve->n, private, curve->num_n_words) != 1) {
+    if (uECC_vli_cmp(curve->n, private, BITS_TO_WORDS(curve->num_n_bits)) != 1) {
         return 0;
     }
     
@@ -799,9 +802,7 @@
        attack to learn the number of leading zeros. */
     carry = regularize_k(private, tmp1, tmp2, curve);
 
-    EccPoint_mult(result, curve->G, p2[!carry], 0,
-                  uECC_vli_numBits(curve->n, curve->num_n_words) + 1,
-                  curve);
+    EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve);
 
     if (EccPoint_isZero(result, curve)) {
         return 0;
@@ -811,60 +812,46 @@
 
 #if uECC_WORD_SIZE == 1
 
-uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint8_t *native, uECC_Curve curve) {
+uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes,
+                                         int num_bytes,
+                                         const uint8_t *native,
+                                         uECC_Curve curve) {
     wordcount_t i;
-    wordcount_t num_words = curve->num_words;
-    for (i = 0; i < num_words; ++i) {
-        dest[i] = src[(num_words - 1) - i];
+    for (i = 0; i < num_bytes; ++i) {
+        bytes[i] = native[(num_bytes - 1) - i];
     }
 }
 
-uECC_VLI_API void uECC_vli_bytesToNative(uint8_t *native, const uint8_t *bytes, uECC_Curve curve) {
-    uECC_vli_nativeToBytes(dest, src, curve);
-}
-
-#elif uECC_WORD_SIZE == 4
-
-uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint32_t *native, uECC_Curve curve) {
-    wordcount_t i;
-    wordcount_t num_words = curve->num_words;
-    for (i = 0; i < num_words; ++i) {
-        uint8_t *digit = bytes + 4 * (num_words - 1 - i);
-        digit[0] = native[i] >> 24;
-        digit[1] = native[i] >> 16;
-        digit[2] = native[i] >> 8;
-        digit[3] = native[i];
-    }
-}
-
-uECC_VLI_API void uECC_vli_bytesToNative(uint32_t *native, const uint8_t *bytes, uECC_Curve curve) {
-    wordcount_t i;
-    wordcount_t num_words = curve->num_words;
-    for (i = 0; i < num_words; ++i) {
-        const uint8_t *digit = bytes + 4 * (num_words - 1 - i);
-        native[i] = ((uint32_t)digit[0] << 24) | ((uint32_t)digit[1] << 16) |
-                    ((uint32_t)digit[2] << 8) | (uint32_t)digit[3];
-    }
+uECC_VLI_API void uECC_vli_bytesToNative(uint8_t *native,
+                                         const uint8_t *bytes,
+                                         int num_bytes,
+                                         uECC_Curve curve) {
+    uECC_vli_nativeToBytes(native, num_bytes, bytes, curve);
 }
 
 #else
 
-uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, const uint64_t *native, uECC_Curve curve) {
+uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes,
+                                         int num_bytes,
+                                         const uECC_word_t *native,
+                                         uECC_Curve curve) {
     wordcount_t i;
-    wordcount_t num_bytes = curve->num_bytes;
     for (i = 0; i < num_bytes; ++i) {
         unsigned b = num_bytes - 1 - i;
-        bytes[i] = native[b / 8] >> (8 * (b % 8));
+        bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE));
     }
 }
 
-uECC_VLI_API void uECC_vli_bytesToNative(uint64_t *native, const uint8_t *bytes, uECC_Curve curve) {
+uECC_VLI_API void uECC_vli_bytesToNative(uECC_word_t *native,
+                                         const uint8_t *bytes,
+                                         int num_bytes,
+                                         uECC_Curve curve) {
     wordcount_t i;
-    wordcount_t num_bytes = curve->num_bytes;
-    uECC_vli_clear(native, curve->num_words);
+    uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE);
     for (i = 0; i < num_bytes; ++i) {
         unsigned b = num_bytes - 1 - i;
-        native[b / 8] |= (uint64_t)bytes[i] << (8 * (b % 8));
+        native[b / uECC_WORD_SIZE] |= 
+            (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE));
     }
 }
 
@@ -892,18 +879,16 @@
     uECC_word_t public[uECC_MAX_WORDS * 2];
     uECC_word_t tries;
     
-    /* Zero out correctly (to compare to curve->n) for secp160r1. */
-    private[curve->num_n_words - 1] = 0; 
-    
     for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
-        if (!generate_random_int(private, curve->num_words, curve->num_bytes * 8)) {
+        if (!generate_random_int(private, BITS_TO_WORDS(curve->num_n_bits), curve->num_n_bits)) {
             return 0;
         }
 
         if (EccPoint_compute_public_key(public, private, curve)) {
-            uECC_vli_nativeToBytes(private_key, private, curve);
-            uECC_vli_nativeToBytes(public_key, public, curve);
-            uECC_vli_nativeToBytes(public_key + curve->num_bytes, public + curve->num_words, curve);
+            uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), private, curve);
+            uECC_vli_nativeToBytes(public_key, curve->num_bytes, public, curve);
+            uECC_vli_nativeToBytes(
+                public_key + curve->num_bytes, curve->num_bytes, public + curve->num_words, curve);
             return 1;
         }
     }
@@ -923,12 +908,10 @@
     uECC_word_t carry;
     wordcount_t num_words = curve->num_words;
     
-    /* Zero out correctly (for addition with curve->n) for secp160r1. */
-    private[curve->num_n_words - 1] = 0;
-    
-    uECC_vli_bytesToNative(private, private_key, curve);
-    uECC_vli_bytesToNative(public, public_key, curve);
-    uECC_vli_bytesToNative(public + num_words, public_key + curve->num_bytes, curve);
+    uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits), curve);
+    uECC_vli_bytesToNative(public, public_key, curve->num_bytes, curve);
+    uECC_vli_bytesToNative(
+        public + num_words, public_key + curve->num_bytes, curve->num_bytes, curve);
     
     /* Regularize the bitcount for the private key so that attackers cannot use a side channel
        attack to learn the number of leading zeros. */
@@ -950,10 +933,8 @@
         }
     }
     
-    EccPoint_mult(public, public, p2[!carry], initial_Z,
-                  uECC_vli_numBits(curve->n, curve->num_n_words) + 1,
-                  curve);
-    uECC_vli_nativeToBytes(secret, public, curve);
+    EccPoint_mult(public, public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve);
+    uECC_vli_nativeToBytes(secret, curve->num_bytes, public, curve);
     return !EccPoint_isZero(public, curve);
 }
 
@@ -969,7 +950,7 @@
 void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) {
     uECC_word_t point[uECC_MAX_WORDS * 2];
     uECC_word_t *y = point + curve->num_words;
-    uECC_vli_bytesToNative(point, compressed + 1, curve);
+    uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes, curve);
     curve->x_side(y, point, curve);
     curve->mod_sqrt(y, curve);
     
@@ -977,8 +958,8 @@
         uECC_vli_sub(y, curve->p, y, curve->num_words);
     }
     
-    uECC_vli_nativeToBytes(public_key, point, curve);
-    uECC_vli_nativeToBytes(public_key + curve->num_bytes, y, curve);
+    uECC_vli_nativeToBytes(public_key, curve->num_bytes, point, curve);
+    uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, y, curve);
 }
 #endif /* uECC_SUPPORT_COMPRESSED_POINT */
 
@@ -1002,14 +983,15 @@
     curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */
     
     /* Make sure that y^2 == x^3 + ax + b */
-    return (uECC_vli_equal(tmp1, tmp2, num_words));
+    return (int)(uECC_vli_equal(tmp1, tmp2, num_words));
 }
 
 int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) {
     uECC_word_t public[uECC_MAX_WORDS * 2];
 
-    uECC_vli_bytesToNative(public, public_key, curve);
-    uECC_vli_bytesToNative(public + curve->num_words, public_key + curve->num_bytes, curve);
+    uECC_vli_bytesToNative(public, public_key, curve->num_bytes, curve);
+    uECC_vli_bytesToNative(
+        public + curve->num_words, public_key + curve->num_bytes, curve->num_bytes, curve);
     return uECC_valid_point(public, curve);
 }
 
@@ -1017,14 +999,15 @@
     uECC_word_t private[uECC_MAX_WORDS];
     uECC_word_t public[uECC_MAX_WORDS * 2];
 
-    uECC_vli_bytesToNative(private, private_key, curve);
+    uECC_vli_bytesToNative(private, private_key, BITS_TO_BYTES(curve->num_n_bits), curve);
 
     if (!EccPoint_compute_public_key(public, private, curve)) {
         return 0;
     }
 
-    uECC_vli_nativeToBytes(public_key, public, curve);
-    uECC_vli_nativeToBytes(public_key + curve->num_bytes, public + curve->num_words, curve);
+    uECC_vli_nativeToBytes(public_key, curve->num_bytes, public, curve);
+    uECC_vli_nativeToBytes(
+        public_key + curve->num_bytes, curve->num_bytes, public + curve->num_words, curve);
     return 1;
 }
 
@@ -1042,8 +1025,8 @@
     uECC_word_t p[uECC_MAX_WORDS * 2];
     uECC_word_t carry;
     wordcount_t num_words = curve->num_words;
-    wordcount_t num_n_words = curve->num_n_words;
-    bitcount_t num_n_bits = uECC_vli_numBits(curve->n, num_n_words);
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    bitcount_t num_n_bits = curve->num_n_bits;
     
     /* Make sure 0 < k < curve_n */
     if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) {
@@ -1081,21 +1064,20 @@
     uECC_vli_modInv(k, k, curve->n, num_n_words);       /* k = 1 / k' */
     uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */
     
-    uECC_vli_nativeToBytes(signature, p, curve); /* store r */
+    uECC_vli_nativeToBytes(signature, curve->num_bytes, p, curve); /* store r */
     
-    tmp[num_n_words - 1] = 0;
-    uECC_vli_bytesToNative(tmp, private_key, curve); /* tmp = d */
+    uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits), curve); /* tmp = d */
     s[num_n_words - 1] = 0;
     uECC_vli_set(s, p, num_words);
     uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */
 
-    uECC_vli_bytesToNative(tmp, message_hash, curve);
+    uECC_vli_bytesToNative(tmp, message_hash, curve->num_bytes, curve);
     uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */
     uECC_vli_modMult(s, s, k, curve->n, num_n_words);  /* s = (e + r*d) / k */
     if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) {
         return 0;
     }
-    uECC_vli_nativeToBytes(signature + curve->num_bytes, s, curve);
+    uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s, curve);
     return 1;
 }
 
@@ -1105,10 +1087,11 @@
               uECC_Curve curve) {
     uECC_word_t k[uECC_MAX_WORDS];
     uECC_word_t tries;
-    bitcount_t num_n_bits = uECC_vli_numBits(curve->n, curve->num_n_words);
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    bitcount_t num_n_bits = curve->num_n_bits;
     
     for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
-        if (!generate_random_int(k, curve->num_n_words, num_n_bits)) {
+        if (!generate_random_int(k, num_n_words, num_n_bits)) {
             return 0;
         }
 
@@ -1176,8 +1159,8 @@
     uint8_t *K = hash_context->tmp;
     uint8_t *V = K + hash_context->result_size;
     wordcount_t num_bytes = curve->num_bytes;
-    wordcount_t num_n_words = curve->num_n_words;
-    bitcount_t num_n_bits = uECC_vli_numBits(curve->n, num_n_words);
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    bitcount_t num_n_bits = curve->num_n_bits;
     uECC_word_t tries;
     unsigned i;
     for (i = 0; i < hash_context->result_size; ++i) {
@@ -1263,16 +1246,17 @@
     bitcount_t i;
     uECC_word_t r[uECC_MAX_WORDS], s[uECC_MAX_WORDS];
     wordcount_t num_words = curve->num_words;
-    wordcount_t num_n_words = curve->num_n_words;
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
     
     rx[num_n_words - 1] = 0;
     r[num_n_words - 1] = 0;
     s[num_n_words - 1] = 0;
 
-    uECC_vli_bytesToNative(public, public_key, curve);
-    uECC_vli_bytesToNative(public + num_words, public_key + curve->num_bytes, curve);
-    uECC_vli_bytesToNative(r, signature, curve);
-    uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve);
+    uECC_vli_bytesToNative(public, public_key, curve->num_bytes, curve);
+    uECC_vli_bytesToNative(
+        public + num_words, public_key + curve->num_bytes, curve->num_bytes, curve);
+    uECC_vli_bytesToNative(r, signature, curve->num_bytes, curve);
+    uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes, curve);
     
     /* r, s must not be 0. */
     if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) {
@@ -1288,7 +1272,7 @@
     /* Calculate u1 and u2. */
     uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */
     u1[num_n_words - 1] = 0;
-    uECC_vli_bytesToNative(u1, hash, curve);
+    uECC_vli_bytesToNative(u1, hash, curve->num_bytes, curve);
     uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */
     uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */
     
@@ -1342,7 +1326,7 @@
     }
 
     /* Accept only if v == r. */
-    return (uECC_vli_equal(rx, r, num_words));
+    return (int)(uECC_vli_equal(rx, r, num_words));
 }
 
 #if uECC_ENABLE_VLI_API
@@ -1356,7 +1340,11 @@
 }
 
 unsigned uECC_curve_num_n_words(uECC_Curve curve) {
-    return curve->num_n_words;
+    return BITS_TO_WORDS(curve->num_n_bits);
+}
+
+unsigned uECC_curve_num_n_bits(uECC_Curve curve) {
+    return curve->num_n_bits;
 }
 
 const uECC_word_t *uECC_curve_p(uECC_Curve curve) {
@@ -1398,14 +1386,12 @@
     uECC_word_t *p2[2] = {tmp1, tmp2};
     uECC_word_t carry = regularize_k(scalar, tmp1, tmp2, curve);
 
-    EccPoint_mult(result, point, p2[!carry], 0,
-                  uECC_vli_numBits(curve->n, curve->num_n_words) + 1,
-                  curve);
+    EccPoint_mult(result, point, p2[!carry], 0, curve->num_n_bits + 1, curve);
 }
 
 int uECC_generate_random_int(uECC_word_t *random, uECC_Curve curve) {
-    wordcount_t num_n_words = curve->num_n_words;
-    bitcount_t num_n_bits = uECC_vli_numBits(curve->n, num_n_words);
+    wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
+    bitcount_t num_n_bits = curve->num_n_bits;
     uECC_word_t tries;
 
     for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
diff --git a/uECC.h b/uECC.h
index 443d28b..06c6cdd 100644
--- a/uECC.h
+++ b/uECC.h
@@ -113,8 +113,15 @@
 Create a public/private key pair.
 
 Outputs:
-    public_key  - Will be filled in with the public key.
-    private_key - Will be filled in with the private key.
+    public_key  - Will be filled in with the public key. Must be at least 2 * the curve size
+                  (in bytes) long. For example, if the curve is secp256r1, public_key must be 64
+                  bytes long.
+    private_key - Will be filled in with the private key. Must be as long as the curve order; this
+                  is typically the same as the curve size, except for secp160r1. For example, if the
+                  curve is secp256r1, private_key must be 32 bytes long.
+                  
+                  For secp160r1, private_key must be 21 bytes long! Note that the first byte will 
+                  almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero).
 
 Returns 1 if the key pair was generated successfully, 0 if an error occurred.
 */
@@ -130,7 +137,8 @@
     private_key - Your private key.
 
 Outputs:
-    secret - Will be filled in with the shared secret value.
+    secret - Will be filled in with the shared secret value. Must be the same size as the
+             curve size; for example, if the curve is secp256r1, secret must be 32 bytes long.
 
 Returns 1 if the shared secret was generated successfully, 0 if an error occurred.
 */
@@ -147,7 +155,9 @@
     public_key - The public key to compress.
 
 Outputs:
-    compressed - Will be filled in with the compressed public key.
+    compressed - Will be filled in with the compressed public key. Must be at least
+                 (curve size + 1) bytes long; for example, if the curve is secp256r1,
+                 compressed must be 33 bytes long.
 */
 void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve);
 
@@ -201,7 +211,8 @@
     message_hash - The hash of the message to sign.
 
 Outputs:
-    signature - Will be filled in with the signature value.
+    signature - Will be filled in with the signature value. Must be at least 2 * curve size long.
+                For example, if the curve is secp256r1, signature must be 64 bytes long.
 
 Returns 1 if the signature generated successfully, 0 if an error occurred.
 */
diff --git a/uECC_vli.h b/uECC_vli.h
index e445888..21df281 100644
--- a/uECC_vli.h
+++ b/uECC_vli.h
@@ -59,11 +59,13 @@
                          const uECC_word_t *right,
                          wordcount_t num_words);
 
+/* Computes result = left * right. Result must be 2 * num_words long. */
 void uECC_vli_mult(uECC_word_t *result,
                    const uECC_word_t *left,
                    const uECC_word_t *right,
                    wordcount_t num_words);
 
+/* Computes result = left^2. Result must be 2 * num_words long. */
 void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words);
 
 /* Computes result = (left + right) % mod.
@@ -128,12 +130,15 @@
 void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve);
 #endif
 
-void uECC_vli_nativeToBytes(uint8_t *bytes, const uECC_word_t *native, uECC_Curve curve);
-void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, uECC_Curve curve);
+/* Converts an integer in uECC native format to big-endian bytes. */
+void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes, const uECC_word_t *native, uECC_Curve curve);
+/* Converts big-endian bytes to an integer in uECC native format. */
+void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, int num_bytes, uECC_Curve curve);
 
 unsigned uECC_curve_num_words(uECC_Curve curve);
 unsigned uECC_curve_num_bits(uECC_Curve curve);
 unsigned uECC_curve_num_n_words(uECC_Curve curve);
+unsigned uECC_curve_num_n_bits(uECC_Curve curve);
 
 const uECC_word_t *uECC_curve_p(uECC_Curve curve);
 const uECC_word_t *uECC_curve_n(uECC_Curve curve);