Assertion `a->limbs + b->limbs <= 2*((256+(64 - 0)-1)/(64 - 0))+1' failed. #43

issue dpc opened this issue on July 3, 2014
  1. dpc commented at 11:24 PM on July 3, 2014: none

    Hi,

    I'm trying to write Rust (rust-lang.org) wrappers for this library. I'm not a cryptography expert and Rust is still under heavy development, so this might not be problem with a secp256k1 library itself, but when I'm giving random array as inputs like this (Rust syntax):

      #[test]                                                                                           
      fn sign_and_verify_fail() {                                                                       
          let s = Secp256k1::new();                                                                     
    
          let mut msg = Vec::from_elem(64, 0u8);                                                        
          let mut seckey = [0u8, ..32];                                                                 
          let mut nonce = [0u8, ..32];                                                                  
          rand::task_rng().fill_bytes(msg.as_mut_slice());                                              
          rand::task_rng().fill_bytes(nonce);                                                           
          rand::task_rng().fill_bytes(seckey);                                                          
    
          let pubkey = s.pubkey_create(seckey, false).unwrap();                                         
          let sig = s.sign(&msg, seckey, nonce).unwrap();                                               
    
          rand::task_rng().fill_bytes(msg.as_mut_slice());                                              
          assert_eq!(s.verify(msg, sig, pubkey), Ok(false));                                            
      } 
    

    I'm getting assert abort:

    secp256k1: src/num_gmp_impl.h:200: secp256k1_num_mul: Assertion `a->limbs + b->limbs <= 2*((256+(64 - 0)-1)/(64 - 0))+1' failed.

    Generally, it seems the randomness of msg is triggering the problem. Are there some messages / private keys that are not valid? Is this assert ringing a bell what is possibly wrong?

  2. dpc renamed this:
    secp256k1: src/num_gmp_impl.h:200: secp256k1_num_mul: Assertion `a->limbs + b->limbs <= 2*((256+(64 - 0)-1)/(64 - 0))+1' failed.
    Assertion `a->limbs + b->limbs <= 2*((256+(64 - 0)-1)/(64 - 0))+1' failed.
    on Jul 3, 2014
  3. gmaxwell commented at 11:32 PM on July 3, 2014: contributor

    secp256k1's order is 115792089237316195423570985008687907852837564279074904382605163141518161494337, which is slightly smaller than 2^256. A valid private key should be in the range 1 to the order. (However, I haven't checked that the private key is the source of your error).

    It would be helpful if you could capture the inputs in a failure case (or post your complete rust code someplace so I could reproduce).

  4. sipa commented at 11:44 PM on July 3, 2014: contributor

    The message can only be 32 bytes. If it's larger, you need to hash it before passing in.

  5. dpc commented at 11:45 PM on July 3, 2014: none

    I did a dump of arrays:

    msg:
    [29, 43, 58, 27, 190, 113, 99, 144, 140, 147, 49, 159, 205, 130, 73, 25, 4, 247, 222, 238, 232, 32, 252, 208, 19, 229, 51, 100, 215, 127, 102, 39, 53, 218, 167, 244, 216, 50, 200, 229, 115, 214, 36, 91, 195, 167, 176, 159, 80, 143, 37, 170, 39, 97, 108, 174, 15, 93, 92, 46, 9, 123, 99, 19]
    non:
    [142, 145, 0, 2, 12, 122, 33, 14, 3, 87, 129, 205, 241, 47, 3, 63, 225, 234, 0, 128, 215, 216, 236, 67, 53, 191, 158, 194, 34, 141, 190, 10]
    sec:
    [174, 208, 0, 194, 217, 116, 26, 129, 129, 154, 241, 63, 101, 52, 22, 23, 233, 114, 13, 158, 149, 59, 27, 25, 211, 155, 207, 69, 214, 56, 7, 143]
    secp256k1: src/num_gmp_impl.h:200: secp256k1_num_mul: Assertion `a->limbs + b->limbs <= 2*((256+(64 - 0)-1)/(64 - 0))+1' failed.
    

    I'll publish the whole source once I have some more time.

  6. dpc commented at 11:48 PM on July 3, 2014: none

    @sipa: Thank you. That seems to be the problem.

    As a post-issue: Shouldn't the API check that and return something? Or at least have an assert to fail with more clear message.

  7. sipa commented at 11:49 PM on July 3, 2014: contributor

    Agree, it should. Or at least it should be documented.

  8. dpc commented at 11:51 PM on July 3, 2014: none

    I actually remember reading about 32-byte limit somewhere and completely forgot about it, and it was not appearing anywhere I was looking at (main *.h file mostly).

  9. dpc commented at 11:56 PM on July 3, 2014: none

    While we're at it. How "slightly" is this order smaller than 2^256 (@gmaxwell comment) ? Should I validate for it somewhere?

  10. sipa commented at 11:58 PM on July 3, 2014: contributor

    The method to convert to a pubkey checks this and returns failure if it's invalid.

  11. gmaxwell commented at 12:00 AM on July 4, 2014: contributor

    It's very unlikely that a random secret key will be out of range. (It's roughly 2^32 out of 2^256 that is out of range). Wrt to the message, I do worry that an unhashed message interface is a pretty big liability (E.g. sign 0).

  12. dpc commented at 12:06 AM on July 4, 2014: none

    Does signing zero filled message breaks or weakenes the security? I'm not sure if I understand.

  13. dpc commented at 12:11 AM on July 4, 2014: none

    Since I'm receiving so much support, there's one more thing that is unclear to me from the API. Does sizes of all the structures/arrays (compressed signatures, uncompressed signatures, public key, etc.) fixed? The API is not clear about it. Especially signature: is it 33/65 or can it be of any size? <= 72 is all I understood.

  14. gmaxwell commented at 12:12 AM on July 4, 2014: contributor

    An ECDSA signature of zero can be trivially forged, just due to how the algebra works out ( r,s = pubkey.x,pubkey.x is a valid signature of 0). ECDSA should never be used without hashing the message. The libsecp256k1 interface doesn't, so that an application specific hash function can be used.

  15. dpc commented at 5:46 AM on July 7, 2014: none

    I'm not sure if I should open a new issue, but I can't get any more information on how to use compact signatures. My two last tests: https://github.com/dpc/bitcoin-secp256k1-rs/blob/master/src/secp256k1.rs#L352 are failing on Err(InvalidSignature) returned by s.verify.

  16. sipa commented at 12:59 AM on August 28, 2014: contributor

    #54 added input validation checks. Closing this; ping if you need it reopened.

  17. sipa closed this on Aug 28, 2014

  18. Kagami cross-referenced this on Jan 13, 2015 from issue Validate keys and input by Kagami
  19. Kagami cross-referenced this on Jan 20, 2015 from issue Check for empty message by Kagami

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/secp256k1. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-14 14:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me