bitauth / libauth

An ultra-lightweight, zero-dependency TypeScript library for Bitcoin Cash, Bitcoin, and Bitauth applications.

Home Page:https://libauth.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Validating signature creation against pyca/cryptography test vectors

webmaster128 opened this issue · comments

  • I'm submitting a ...
    [x] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository
    [ ] question about how to use this project

  • Summary

I created a set of 20 test vectors from pyca/cryptography and in 12/20 cases, the resulting signatures are valid but not equal to the signature in the test vectors.

When I change the implementation from bitcoin-ts to elliptic, the exact same tests pass.

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

I created a set of test vectors from pyca/cryptography by doing

$ git clone https://github.com/pyca/cryptography.git && cd cryptography
$ python2 -m virtualenv venv
$ source venv/bin/activate
$ pip install cryptography cryptography_vectors pytest ecdsa
$ curl https://patch-diff.githubusercontent.com/raw/webmaster128/cryptography/pull/1.diff | git apply
$ python ./docs/development/custom-vectors/secp256k1/generate_secp256k1.py > secp256k1_test_vectors.txt

and used the following 20 data sets:

{
  message: fromHex("5c868fedb8026979ebd26f1ba07c27eedf4ff6d10443505a96ecaf21ba8c4f0937b3cd23ffdc3dd429d4cd1905fb8dbcceeff1350020e18b58d2ba70887baa3a9b783ad30d3fbf210331cdd7df8d77defa398cdacdfc2e359c7ba4cae46bb74401deb417f8b912a1aa966aeeba9c39c7dd22479ae2b30719dca2f2206c5eb4b7"),
  privkey: fromHex("21142a7e90031ea750c9fa1ba1beae16782386be438133bd43195826ae2e25f0"),
  signature: fromHex("30440220207082eb2c3dfa0b454e0906051270ba4074ac93760ba9e7110cd94714751111022051eb0dbbc9920e72146fb564f99d039802bf6ef2561446eb126ef364d21ee9c4"),
},
{
  message: fromHex("17cd4a74d724d55355b6fb2b0759ca095298e3fd1856b87ca1cb2df5409058022736d21be071d820b16dfc441be97fbcea5df787edc886e759475469e2128b22f26b82ca993be6695ab190e673285d561d3b6d42fcc1edd6d12db12dcda0823e9d6079e7bc5ff54cd452dad308d52a15ce9c7edd6ef3dad6a27becd8e001e80f"),
  privkey: fromHex("824282b6069fe3df857ce37204df4312c35750ee7a0f5e5fd8181666d5e46fb2"),
  signature: fromHex("30440220626d61b7be1488b563e8a85bfb623b2331903964b5c0476c9f9ad29144f076fe02202002a2c0ab5e48626bf761cf677dfeede9c7309d2436d4b8c2b89f21ee2ebc6a"),
},
{
  message: fromHex("db0d31717b04802adbbae1997487da8773440923c09b869e12a57c36dda34af11b8897f266cd81c02a762c6b74ea6aaf45aaa3c52867eb8f270f5092a36b498f88b65b2ebda24afe675da6f25379d1e194d093e7a2f66e450568dbdffebff97c4597a00c96a5be9ba26deefcca8761c1354429622c8db269d6a0ec0cc7a8585c"),
  privkey: fromHex("5c0da42cec87a6b7a173514965343c30013386c0fe9b39203ed7af43ea425944"),
  signature: fromHex("304602210083de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda2780221009747932122b93cec42cad8ee4630a8f6cbe127578b8c495b4ab927275f657658"),
},
{
  message: fromHex("47c9deddfd8c841a63a99be96e972e40fa035ae10d929babfc86c437b9d5d495577a45b7f8a35ce3f880e7d8ae8cd8eb685cf41f0506e68046ccf5559232c674abb9c3683829dcc8002683c4f4ca3a29a7bfde20d96dd0f1a0ead847dea18f297f220f94932536ca4deacedc2c6701c3ee50e28e358dcc54cdbf69daf0eb87f6"),
  privkey: fromHex("ab30a326599165b48c65ab8d3c77d312d7b2ea4853f721e18cc278628a866980"),
  signature: fromHex("30440220723da69da81c8f6b081a9a728b9bba785d2067e0ed769675f8a7563d22ed8a1602203a993793cf39b96b3cd625df0e06f206e17579cd8ebcb7e704174c3d94dba684"),
},
{
  message: fromHex("f15433188c2bbc93b2150bb2f34d36ba8ae49f8f7e4e81aed651c8fb2022b2a7e851c4dbbbc21c14e27380316bfdebb0a049246349537dba687581c1344e40f75afd2735bb21ea074861de6801d28b22e8beb76fdd25598812b2061ca3fba229daf59a4ab416704543b02e16b8136c22acc7e197748ae19b5cbbc160fdc3a8cd"),
  privkey: fromHex("1560b9fa5229f623a9c556132da4fc0e58633f39ce6421d25b5a6cde4ad7e019"),
  signature: fromHex("304502200e0c5228e6783bee4d0406f4f7b7d79f705f0dbb55126966f79e631bd8b23079022100faae33aec5b0fafd3413c14bfdef9c7c9ac6abd06c923c48ab136a2c56826118"),
},
{
  message: fromHex("1bc796124b87793b7f7fdd53b896f8f0d0f2d2be36d1944e3c2a0ac5c6b2839f59a4b4fad200f8035ec98630c51ef0d40863a5ddd69b703d73f06b4afae8ad1a88e19b1b26e8c10b7bff953c05eccc82fd771b220910165f3a906b7c931683e431998d1fd06c32dd11b4f872bf980d547942f22124c7e50c9523321aee23a36d"),
  privkey: fromHex("42f7d48e1c90f3d20252713f7c7c6ce8492c2b99bcef198927de334cda6bad00"),
  signature: fromHex("3046022100b9d3962edadc893f8eeff379f136c7b8fc6ea824a5afc6cbda7e3cb4c7a1e860022100bb1c1f901cf450edfdce20686352bb0cf0a643301123140ec87c92480d7f9d6a"),
},
{
  message: fromHex("18e55ac264031da435b613fc9dc6c4aafc49aae8ddf6f220d523415896ff915fae5c5b2e6aed61d88e5721823f089c46173afc5d9b47fd917834c85284f62dda6ed2d7a6ff10eb553b9312b05dad7decf7f73b69479c02f14ea0a2aa9e05ec07396cd37c28795c90e590631137102315635d702278e352aa41d0826adadff5e1"),
  privkey: fromHex("6fe5b986c18da5d4fbcea6f602f469ac039085247ccb97b6292992363ea1d21c"),
  signature: fromHex("30460221009369ab86afae5e22ed5f4012964804d2a19c36b8b58cf2855205b1cfcc937422022100a27dfc38d899b78edcf38a1b2b53578e72270b083d7d69424c4b4a7d25d39f4d"),
},
{
  message: fromHex("a5290666c97294d090f8da898e555cbd33990579e5e95498444bfb318b4aa1643e0d4348425e21c7c6f99f9955f3048f56c22b68c4a516af5c90ed5268acc9c5a20fec0200c2a282a90e20d3c46d4ecdda18ba18b803b19263de2b79238da921707a0864799cdee9f02913b40681c02c6923070688844b58fe415b7d71ea6845"),
  privkey: fromHex("fbf02ff086b215d057130a509346b64eb63bec0e38db692e07ad24c6ca8fe210"),
  signature: fromHex("3045022100c5e439cef76b28dc0fe9d260763bec05b5e795ac8d90b25d9fccbc1918bc32f302201b06144e6b191224d5eda822a5b3b2026af6aa7f25a9061c9e81c312728aa94a"),
},
{
  message: fromHex("13ad0600229c2a66b2f11617f69c7210ad044c49265dc98ec3c64f56e56a083234d277d404e2c40523c414ad23af5cc2f91a47fe59e7ca572f7fe1d3d3cfceaedadac4396749a292a38e92727273272335f12b2acea21cf069682e67d7e7d7a31ab5bb8e472298a9451aeae6f160f36e6623c9b632b9c93371a002818addc243"),
  privkey: fromHex("474a7dc7f5033b6bf5e3027254cd0dbd956f16f61874b2992839a867f607d0dd"),
  signature: fromHex("3045022100ee8615a5fab6fc674e6d3d9cde8da2b18dece076ae94d96662e16109db12d72002203171705cdab2b3d34c58e556c80358c105807e98243f5754b70b771071308b94"),
},
{
  message: fromHex("51ad843da5eafc177d49a50a82609555e52773c5dfa14d7c02db5879c11a6b6e2e0860df38452dc579d763f91a83ade23b73f4fcbd703f35dd6ecfbb4c9578d5b604ed809c8633e6ac5679a5f742ce94fea3b97b5ba8a29ea28101a7b35f9eaa894dda54e3431f2464d18faf8342b7c59dfe0598c0ab29a14622a08eea70126b"),
  privkey: fromHex("e8a2939a46e6bb7e706e419c0101d39f0494935b17fe3ca907b2ea3558d6ab3a"),
  signature: fromHex("3046022100f753c447161aa3a58e5deeca31797f21484fb0ec3a7fe6e464ab1914896f253b02210099640fbcce1f25fd66744b046e0dfd57fa23070555f438af6c5e5828d47e9fa7"),
},
{
  message: fromHex("678b505467d55ce01aec23fd4851957137c3a1de3ff2c673ec95a577aa9fb011b4b4a8eb7a0e6f391d4236a35b7e769692ace5851d7c53700e180fa522d3d37dbaa496163f3de6d96391e38ff83271e621f2458729ff74de462cdce6b3029f308d4eb8aef036357b9de06d68558e0388a6e88af91340c875050b8c91c4e26fc8"),
  privkey: fromHex("08ce8f7118eda55b008f6eb3281a445a3ddbc5209d5ac16c09dbf40fe4bbc22c"),
  signature: fromHex("30440220439fd0423bde36a1616a6fa4343bb7e07a6b3f6dc629aa8c93c91831055e476c022020998a26ae4b96ef36d48d83e8af0288f0bbc2db5ca5c8271a42f3fdc478fcb2"),
},
{
  message: fromHex("9bf457159f0d44b78d0e151ee53c41cecd98fb4e4129fcda8cc84a758636f84dcad9032f3ec422219d8a7ec61ea89f45d19cab3c3d451de1a634e3d2532231bc03031973d7150cf8e83d8b6a34f25fc136446878e3851b780abdca069c8e981b3ea3f1bf1ff6e47a03f97aed64c1cc90dd00389fa21bb973f142af5e8ceccef4"),
  privkey: fromHex("820be5c5e14e802300ca024fce318910f00470f6c3eabb12e7f3fac9383cf247"),
  signature: fromHex("304502204ce72a83cf1d148db4d1e46e2f773c677f72933c40d7100b9192750a1c8222a80221009d5fbd67ce89ba8c79df9dc3b42922026a8498921c2bdb4ea8f36496d88c2cfb"),
},
{
  message: fromHex("2469172b7a046e6112dfe365590dfddb7c045cccd4ab353edc3076091aad1c780a9a73ff93f3dbf9e2189c5d1fdd6f6167d0ae8cc0f53dc8950e60dd0410e23589999d4ce4fa49e268774defd4edce01c05b205014b63591a041745bfffc6ae4d72d3add353e49478106653cc735b07b0fe665c42d0e6766e525bb9718264c87"),
  privkey: fromHex("d92d6170e63bc33647e6dcdf1981771ecd57e11d47d73138696fbf49a430c3ab"),
  signature: fromHex("304502201f1e1fb673e9a7dee09961c6824b473189904deb4f0d8e28da51f77f4de2efe6022100ae8df1fcdb226fac8b46e494720e45f6d9a5350174faaf22e47b6329ee6c5e1b"),
},
{
  message: fromHex("6f8983e74f304c3657cffde0682b42699cb2c3475b925058ff37292c40a0aa296690ad129730339ac60cf784225b2fd3db58297c8ce5889df7a48d3e74a363ae4135e8a234cab53ca4c11c031d561a6cf7dd47b925ed5bc4c2794ba7b74a868b0c3da31ff1e4540d0768612192a236d86f74fb8c73f375b71c62f1648c0e6126"),
  privkey: fromHex("a70eb435feaeb6ccda7d3ebd3c4ae40b60643bc933f37ad1aca41dd086e8ae50"),
  signature: fromHex("30460221009cf7d941dcbbbe61c2a6f5112cb518094e79e5d203891de2247e75fd532c3f21022100fc5a04579b2526f2543efd2a57e82b647da08b6924bff39cf021398a56ad70de"),
},
{
  message: fromHex("6fbe6f0f178fdc8a3ad1a8eecb02d37108c5831281fe85e3ff8eeb66ca1082a217b6d602439948f828e140140412544f994da75b6efc203b295235deca060ecfc7b71f05e5af2acc564596772ddbfb4078b4665f6b85f4e70641af26e31f6a14e5c88604459df4eeeed9b77b33c4b82a3c1458bd2fd1dc7214c04f9c79c8f09b"),
  privkey: fromHex("34a677d6f0c132eeffc3451b61e5d55969399699019ac929e6fdb5215d37be5e"),
  signature: fromHex("3045022059cd6c2a30227afbd693d87b201d0989435d6e116c144276a5223466a822c0f2022100b01495efda969b3fd3a2c05aa098a4e04b0d0e748726fc6174627da15b143799"),
},
{
  message: fromHex("2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e"),
  privkey: fromHex("2258cdecaf3510bc398d08c000245cadceadcf149022730d93b176b4844713e1"),
  signature: fromHex("30460221009eaf69170aeba44966afe957295526ee9852b5034c18dc5aeef3255c8567838a022100ebd4c8de2c22b5cb8803d6e070186786f6d5dae2202b9f899276fa31a66cb3bb"),
},
{
  message: fromHex("1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407"),
  privkey: fromHex("a67cf8cead99827c7956327aa04ab30cfd2d67f21b78f28a35694ece51052a61"),
  signature: fromHex("304402210091058d1b912514940e1002855cc930c01a21234bad88f607f213af495c32b69f021f5d387ce3de25f1b9bad1fb180de110686d91b461ae2972fa4e4a7018519870"),
},
{
  message: fromHex("74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb"),
  privkey: fromHex("4f1050422c4fce146bab0d735a70a91d6447210964b064309f90315c986be400"),
  signature: fromHex("3046022100fe43eb9c38b506d118e20f8605ac8954fc0406efd306ba7ea5b07577a2735d15022100d589e91bf5014c7c360342ad135259dd7ae684e2c21234d7a912b43d148fcf19"),
},
{
  message: fromHex("d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560"),
  privkey: fromHex("79506f5f68941c60a0d7c62595652a5f42f2b9f5aa2b6456af1c56a79a346c2f"),
  signature: fromHex("3046022100ccdbbd2500043bf7f705536d5984ab5f05fdc0fa3cf464d8c88f861e3fc8e54c022100d5c6342c08dcd8242e1daf3595cae968e320a025aa45ec4bc725795da3d1becb"),
},
{
  message: fromHex("ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db"),
  privkey: fromHex("4c53b8e372f70593afb08fb0f3ba228e1bd2430f562414e9bd1b89e53becbac8"),
  signature: fromHex("304402205c707b6df7667324f950216b933d28e307a0223b24d161bc5887208d7f880b3a02204b7bc56586dc51d806ac3ad72807bc62d1d06d0812f121bd91e9770d84885c39"),
},

All those signatures are successfully validated by bitcoin-ts. But when I calculate the signatures from message and privkey, I get different (also valid) signatures for the 0-based list indices 2,4,5,6,9,11,12,13,14,15,17,18:

   (index 02) Expected '304502210083de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda278022068b86cdedd46c313bd352711b9cf5707eecdb58f23bc56e07519376570d0cae9'
              to equal '304602210083de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda2780221009747932122b93cec42cad8ee4630a8f6cbe127578b8c495b4ab927275f657658'.
   (index 04) Expected '304402200e0c5228e6783bee4d0406f4f7b7d79f705f0dbb55126966f79e631bd8b2307902200551cc513a4f0502cbec3eb4021063821fe8311642b663f314bef46079b3e029'
              to equal '304502200e0c5228e6783bee4d0406f4f7b7d79f705f0dbb55126966f79e631bd8b23079022100faae33aec5b0fafd3413c14bfdef9c7c9ac6abd06c923c48ab136a2c56826118'.
   (index 05) Expected '3045022100b9d3962edadc893f8eeff379f136c7b8fc6ea824a5afc6cbda7e3cb4c7a1e860022044e3e06fe30baf120231df979cad44f1ca0899b69e258c2cf755cc44c2b6a3d7'
              to equal '3046022100b9d3962edadc893f8eeff379f136c7b8fc6ea824a5afc6cbda7e3cb4c7a1e860022100bb1c1f901cf450edfdce20686352bb0cf0a643301123140ec87c92480d7f9d6a'.
   (index 06) Expected '30450221009369ab86afae5e22ed5f4012964804d2a19c36b8b58cf2855205b1cfcc93742202205d8203c727664871230c75e4d4aca8704887d1de71cb36f97387140faa62a1f4'
              to equal '30460221009369ab86afae5e22ed5f4012964804d2a19c36b8b58cf2855205b1cfcc937422022100a27dfc38d899b78edcf38a1b2b53578e72270b083d7d69424c4b4a7d25d39f4d'.
   (index 09) Expected '3045022100f753c447161aa3a58e5deeca31797f21484fb0ec3a7fe6e464ab1914896f253b0220669bf04331e0da02998bb4fb91f202a6c08bd5e15954678c53740663fbb7a19a'
              to equal '3046022100f753c447161aa3a58e5deeca31797f21484fb0ec3a7fe6e464ab1914896f253b02210099640fbcce1f25fd66744b046e0dfd57fa23070555f438af6c5e5828d47e9fa7'.
   (index 11) Expected '304402204ce72a83cf1d148db4d1e46e2f773c677f72933c40d7100b9192750a1c8222a8022062a04298317645738620623c4bd6ddfc502a4454931cc4ed16def9f5f7aa1446'
              to equal '304502204ce72a83cf1d148db4d1e46e2f773c677f72933c40d7100b9192750a1c8222a80221009d5fbd67ce89ba8c79df9dc3b42922026a8498921c2bdb4ea8f36496d88c2cfb'.
   (index 12) Expected '304402201f1e1fb673e9a7dee09961c6824b473189904deb4f0d8e28da51f77f4de2efe6022051720e0324dd905374b91b6b8df1ba07e109a7e53a4df118db56fb62e1c9e326'
              to equal '304502201f1e1fb673e9a7dee09961c6824b473189904deb4f0d8e28da51f77f4de2efe6022100ae8df1fcdb226fac8b46e494720e45f6d9a5350174faaf22e47b6329ee6c5e1b'.
   (index 13) Expected '30450221009cf7d941dcbbbe61c2a6f5112cb518094e79e5d203891de2247e75fd532c3f21022003a5fba864dad90dabc102d5a817d49a3d0e517d8a88ac9ecfb125027988d063'
              to equal '30460221009cf7d941dcbbbe61c2a6f5112cb518094e79e5d203891de2247e75fd532c3f21022100fc5a04579b2526f2543efd2a57e82b647da08b6924bff39cf021398a56ad70de'.
   (index 14) Expected '3044022059cd6c2a30227afbd693d87b201d0989435d6e116c144276a5223466a822c0f202204feb6a10256964c02c5d3fa55f675b1e6fa1ce722821a3da4b6fe0eb752209a8'
              to equal '3045022059cd6c2a30227afbd693d87b201d0989435d6e116c144276a5223466a822c0f2022100b01495efda969b3fd3a2c05aa098a4e04b0d0e748726fc6174627da15b143799'.
   (index 15) Expected '30450221009eaf69170aeba44966afe957295526ee9852b5034c18dc5aeef3255c8567838a0220142b3721d3dd4a3477fc291f8fe79877c3d902048f1d00b22d5b645b29c98d86'
              to equal '30460221009eaf69170aeba44966afe957295526ee9852b5034c18dc5aeef3255c8567838a022100ebd4c8de2c22b5cb8803d6e070186786f6d5dae2202b9f899276fa31a66cb3bb'.
   (index 17) Expected '3045022100fe43eb9c38b506d118e20f8605ac8954fc0406efd306ba7ea5b07577a2735d1502202a7616e40afeb383c9fcbd52ecada6213fc85803ed366b6416bfaa4fbba67228'
              to equal '3046022100fe43eb9c38b506d118e20f8605ac8954fc0406efd306ba7ea5b07577a2735d15022100d589e91bf5014c7c360342ad135259dd7ae684e2c21234d7a912b43d148fcf19'.
   (index 18) Expected '3045022100ccdbbd2500043bf7f705536d5984ab5f05fdc0fa3cf464d8c88f861e3fc8e54c02202a39cbd3f72327dbd1e250ca6a351695d78e3cc10502b3eff8ace52f2c648276'
              to equal '3046022100ccdbbd2500043bf7f705536d5984ab5f05fdc0fa3cf464d8c88f861e3fc8e54c022100d5c6342c08dcd8242e1daf3595cae968e320a025aa45ec4bc725795da3d1becb'.

Looks like the first part of the signature is always okay.

Hey @webmaster128 – thank you for this work! I'm looking into this now. Could you share the code which you used to try this with bitcoin-ts?

My initial hunch is that you'll need to hash the messages before trying to sign them. This library doesn't yet expose a sha256 method, so unless you're bringing in a different one, I suspect your test code is signing the first 32 bytes of the message as if it is the 32-byte message hash.

Elliptic's sign method takes a message, rather than a messageHash like the Secp256k1 C library (and this library), so that may explain why it's working there. If you use secp256k1-node, do you get the same result as this library?

To summarize – right now you can only sign message hashes with this library, to get the 32-byte message hash, you'll need a hashing function too. (I'm working on WebAssembly versions of the hashing functions used in Bitcoin, but it may be a little while still.)

I saw the documentation with messageHash and thus I am always signing sha256 hashes. This is how elliptic works as well:

// Sign the message's hash (input must be an array, or a hex-string)
var msgHash = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
var signature = key.sign(msgHash);

I am using sha.js for hashing, which is fine. Don't think you need to blow up this library with hashing.

The only thing that elliptic does to the input message hash is truncating, which should be a noop for sha256 hashes:

EC.prototype._truncateToN = function truncateToN(msg, truncOnly) {
  var delta = msg.byteLength() * 8 - this.n.bitLength();
  if (delta > 0)
    msg = msg.ushrn(delta);
  if (!truncOnly && msg.cmp(this.n) >= 0)
    return msg.sub(this.n);
  else
    return msg;
};

However, I don't think this is the core of the issue. bitcoin-ts validates all my signatures and signatures created by bitcoin-ts are valid. The only thing is that the S parameter in the signatures created by bitcoin-ts differs. E.g. in the first failing test we have

expected

sig = 304602210083de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda2780221009747932122b93cec42cad8ee4630a8f6cbe127578b8c495b4ab927275f657658
R = 83de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda278
S = 9747932122b93cec42cad8ee4630a8f6cbe127578b8c495b4ab927275f657658
R_10 = 59646299137473946001508533510278632412745961454606399588753206345566535918200
S_10 = 68425701727720528562443687873036783529947755421899013291680423567791537616472

bitcoin-ts

sig = 304502210083de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda278022068b86cdedd46c313bd352711b9cf5707eecdb58f23bc56e07519376570d0cae9
R = 83de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda278
S = 68b86cdedd46c313bd352711b9cf5707eecdb58f23bc56e07519376570d0cae9
R_10 = 59646299137473946001508533510278632412745961454606399588753206345566535918200
S_10 = 47366387509595666861127297135651124322889808857175891090924739573726623877865

So the S is indeed low as documented in signMessageHashDER. But does RFC 6979 not fix any specific behavior for S?

The two competing value for S are actually S and -S on that curve:

$ python3
>>> N = int('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16)
>>> N - 68425701727720528562443687873036783529947755421899013291680423567791537616472
47366387509595666861127297135651124322889808857175891090924739573726623877865
>>> N - 47366387509595666861127297135651124322889808857175891090924739573726623877865
68425701727720528562443687873036783529947755421899013291680423567791537616472

As described in https://docs.rs/secp256k1/0.5.2/secp256k1/struct.Signature.html#method.normalize_s, the two signatures are (r, s) and (r, -s), which are both valid.

So the question is if RFC 6979 requires one of those representations.

The successor of BIP0062 also required low S: https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki

Looks like this well documented feature makes perfect sense for a Bitcoin focused library. My test data and elliptic do not normalize to low S. If you want this normalization or not is the caller's problem.

Closing this as out of scope for this library. Feel free to continue this very interesting discussion anyway.

Ah – sorry, I definitely should have picked up on the issue. Somehow missed the Looks like the first part of the signature is always okay. Long day. 😆

Thanks @rudi-cilibrasi!

For future reference, are a few related useful methods:

also worth noting that there are two different validation functions (verifySignatureDER/Compact and verifySignatureDERLowS/verifySignatureCompactLowS), for strict Low-S validation and non-strict, respectively.

So in this case, if you malleateSignatureDER the signatures produced by this library, you'll get the result you were expecting. 👍