diff --git a/ecdsa.pm b/ecdsa.pm index 962b6a7..9368b28 100644 --- a/ecdsa.pm +++ b/ecdsa.pm @@ -213,20 +213,29 @@ sub pub_decode { sub hash_decode { my ($hash) = @_; - - my $s = length ($hash) * 8 - $EC_SIZE; + my $s = length ($hash) * 8 - $EC_SIZE; my $e = i_decode ($hash); $e = $e->brsft ($s) if $s > 0; return $e; } +sub ber_hex { + # like i_encode() but doesn't attempt to pad it out to any length and makes sure there is a leading null if otherwise the first high bit would be set (which would indicate negative, but these are never neg) + # standardizing on exactly this formatting of numbers was the main part of the "canonicalization" fix for the transaction mutability bug + my $i = shift; + my $bin = $i->as_hex; + $bin =~ s/^0x// or die $i; + $bin = '00' . $bin if hex( substr($bin, 0, 2) ) >= 0x80; + return pack 'H*', $bin; +} + sub sig_encode { my ($sig) = @_; my ($r, $s) = @$sig; - return pack 'C w/a', 0x30, - pack ('C w/a', 0x02, i_encode ($r)) . - pack ('C w/a', 0x02, i_encode ($s)); + return pack 'C C/a', 0x30, + pack ('C C/a', 0x02, ber_hex($r) ) . + pack ('C C/a', 0x02, ber_hex($s) ); } sub sig_decode { diff --git a/test/ecdsa b/test/ecdsa index c4cbac7..05406ef 100644 --- a/test/ecdsa +++ b/test/ecdsa @@ -1,50 +1,65 @@ -#! /usr/bin/perl -l -BEGIN { chdir '..' } - -use warnings; -use strict; - -use ecdsa; - -$ecdsa::PROB_VERIFY = 1; - -print ecdsa::version; - -ecdsa::p_oncurve ([ - ecdsa::i '0x11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c', - ecdsa::i '0xb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3', -]) or die; -print "ok 1"; - -ecdsa::ec_verify ([ - ecdsa::i '0x11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c', - ecdsa::i '0xb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3', -], ecdsa::hash_decode (pack 'H*', - '7a05c6145f10101e9d6325494245adf1297d80f8f38d4d576d57cdba220bcb19', -), [ - ecdsa::i '0x4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41', - ecdsa::i '0x181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09', -]) or die; -print "ok 2"; - -my $k = ecdsa::GenKey (); -my $h = 123; -my $s = ecdsa::Sign ($k, $h); -ecdsa::Verify ($k, $h, $s) or die; -print "ok 3"; - -while () { - my ($p, $h, $s) = /(\S+) (\S+) (\S+)/ or die; - $_ = pack 'H*', $_ for $p, $h, $s; - ecdsa::Verify ({ pub => $p }, $h, $s) or die $_; - print "ok"; -} - -__DATA__ -04c22551f7ada4ff0652684301e2a96748b6ab3371ee0cf574734f81a46cb43ca524a75b25c8e63243d46da91c9086dd5a7fc52112ae3853f7950a3f1e17fb664f a194083fee9582252f32bd8dabd226785725d1e7e178c1c5dd702bc8500a4bd5 304502202f9ef0928d14d3e8d8d38b84789dfee5fb2ad22d55e4198e9d3521c8cfe5a911022100f72915c2093025ae9e74da59bb9582476519b014bef9f9afa8e7892db0df701a -04e663fe1050fa91973f961c5f4c0602addb0264880a2246fdbfb5bce665687106b22fed361329c5cffad52b2efd543c5bcc6e7d8d41f4c8b7771c42d3a155eb36 303a1e60c51be64119b696ad10d03070ebfff2738133e5cd3df0e23faf899a8a 3045022100bcf1743c11fcd45a1e997c248719d38420c78017c770c2ce572d9df49b7721f402203cf012836205c60cbf32cff63781deb48cb4dbcc08a5d5a1b13c4c09351211e8 -04d8cd505bd4211bf09b419c0751b05e19877e1b49ee7d6dbd572eac7645c16c0316f5eb2cf2f74c533e8954cc2a6436889bbe81f9fff5570357eafa9537f88cc2 496dc279152521900ecc6dd25726bfbcbdd8602681209930c4f39ca21d330018 3045022100bd7a7fc3439fe8a949e957ccfffb657559d7fa8246d5c82dfd0d2b67fbd1ef170220188a2d3a3efec9cb60b0d2b873bedb6a80ed2b5ae24d03e2320ac856cb5a5141 -0452075f5c1e75fab286b37cafb30618ef108214b31ae42e4536977a7018d1551921d845ac69b0276236b3a70d64c65127413b8153c760f13bb22331af7671b73e 3380547d4eefdf3eaacfda0814afc8666771de21627905352f69b8437fd33d63 3046022100b44df2447333b183389314cb515d838f3e6660c500db5704f9e1c9773b0e2f4e022100da5aa03be11b7a49efaad6ccd94e2bd34e1907408ce78a9be7df8c2085fe81cd -04fe89ab4c34918953794aeade72310a52f653d33d38be8c7d552a06626ba3d97b17600383a2f7f9d38da16d29430e730944daebff34b1643fb453d7cc777554f6 48d27ba16fb410099ddb15ee6bbd04cecbd537e906d885f560fc8ab49aa06826 30450220290880d98d82f6a084d30e79724057d0a75225e45afd711c236346709eb56cdb022100ec91216b99fdbd66b9d501a7985801f545f8f90bbbb8e5e9393f120f12d643c0 -049bb20bd89b275d654c8a3bde8262b7b98b939f93a76929332c090ed0606661c90697c0f910206ef9caa136f9557122f5229e1e028324bc69197f6ba6f9c4603a 9a240baddbc2297e63c59cd273b8412e83e27da9aa90d7bbbf31a2338d208d67 30450220044944a8bd3c6a252ad2c50b66b66b32a7bd736d433eaff44c13b9f850d15b93022100fa300df45dd00ab84a743210d41704e0a23705fbbd95fb103cfdc98c2e9b5137 -04987df80fccecc297c66f84821279648f0868ca30beea4231eb7bf189071055abbf61a75469d379ae09245ebb39d584d9f67a83130ee95c45bd76b5d9e01aa7aa 17e5410cd8db696e37aaae85d3e687852305ac9540d553dc414fd362bdaf2dd6 3045022038d52df4f8a494be36aee617ca5fb28e585895190fa58e5aba199ccf1c90371b022100bb2960426f8e196d9a42fb02579f85ae26ab9956918241bd77f02bb6dfab3a6a +#! /usr/bin/perl -l +BEGIN { chdir '..' } + +use warnings; +use strict; + +use ecdsa; + +$ecdsa::PROB_VERIFY = 1; + +print ecdsa::version; + +ecdsa::p_oncurve ([ + ecdsa::i '0x11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c', + ecdsa::i '0xb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3', +]) or die; +print "ok 1"; + +ecdsa::ec_verify ([ + ecdsa::i '0x11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c', + ecdsa::i '0xb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3', +], ecdsa::hash_decode (pack 'H*', + '7a05c6145f10101e9d6325494245adf1297d80f8f38d4d576d57cdba220bcb19', +), [ + ecdsa::i '0x4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41', + ecdsa::i '0x181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09', +]) or die; +print "ok 2"; + +my $k = ecdsa::GenKey (); +my $h = 123; + +use Data::Dumper; +# warn Dumper $k; + +my $s = ecdsa::Sign ($k, $h); +ecdsa::Verify ($k, $h, $s) or die; +print "ok 3"; + +# test that DER encoded strings are correctly conicalized when generating ASN.1 encoded signitures + +$k = { priv => from_hex('313032373533323531323539343134313833383035303734333633333334323835323731373732313039363835353931393535383338383833343439313231383132383635343632323238343132') }; +$h = from_hex('3939363234303634303238353836333033343037373931303937393038383131303238343535373730383533333735323730343932343437383735303330383235333634313733373734343532'); +$s = ecdsa::Sign( $k, $h ); +print "ok 4" if $s eq from_hex('30460221009bb961c94162063af38f24fc058f66144d723f16a1896612151f763984e8e8750221009c8b8aa577b5a72b5e32114983c0c0bd02a788ea70c91fb49138b44945a99b00'); + +while () { + my ($p, $h, $s) = /(\S+) (\S+) (\S+)/ or die; + $_ = pack 'H*', $_ for $p, $h, $s; + ecdsa::Verify ({ pub => $p }, $h, $s) or die $_; + print "ok"; +} + +sub from_hex { + pack( "H*", $_[0] ); +} + +__DATA__ +04c22551f7ada4ff0652684301e2a96748b6ab3371ee0cf574734f81a46cb43ca524a75b25c8e63243d46da91c9086dd5a7fc52112ae3853f7950a3f1e17fb664f a194083fee9582252f32bd8dabd226785725d1e7e178c1c5dd702bc8500a4bd5 304502202f9ef0928d14d3e8d8d38b84789dfee5fb2ad22d55e4198e9d3521c8cfe5a911022100f72915c2093025ae9e74da59bb9582476519b014bef9f9afa8e7892db0df701a +04e663fe1050fa91973f961c5f4c0602addb0264880a2246fdbfb5bce665687106b22fed361329c5cffad52b2efd543c5bcc6e7d8d41f4c8b7771c42d3a155eb36 303a1e60c51be64119b696ad10d03070ebfff2738133e5cd3df0e23faf899a8a 3045022100bcf1743c11fcd45a1e997c248719d38420c78017c770c2ce572d9df49b7721f402203cf012836205c60cbf32cff63781deb48cb4dbcc08a5d5a1b13c4c09351211e8 +04d8cd505bd4211bf09b419c0751b05e19877e1b49ee7d6dbd572eac7645c16c0316f5eb2cf2f74c533e8954cc2a6436889bbe81f9fff5570357eafa9537f88cc2 496dc279152521900ecc6dd25726bfbcbdd8602681209930c4f39ca21d330018 3045022100bd7a7fc3439fe8a949e957ccfffb657559d7fa8246d5c82dfd0d2b67fbd1ef170220188a2d3a3efec9cb60b0d2b873bedb6a80ed2b5ae24d03e2320ac856cb5a5141 +0452075f5c1e75fab286b37cafb30618ef108214b31ae42e4536977a7018d1551921d845ac69b0276236b3a70d64c65127413b8153c760f13bb22331af7671b73e 3380547d4eefdf3eaacfda0814afc8666771de21627905352f69b8437fd33d63 3046022100b44df2447333b183389314cb515d838f3e6660c500db5704f9e1c9773b0e2f4e022100da5aa03be11b7a49efaad6ccd94e2bd34e1907408ce78a9be7df8c2085fe81cd +04fe89ab4c34918953794aeade72310a52f653d33d38be8c7d552a06626ba3d97b17600383a2f7f9d38da16d29430e730944daebff34b1643fb453d7cc777554f6 48d27ba16fb410099ddb15ee6bbd04cecbd537e906d885f560fc8ab49aa06826 30450220290880d98d82f6a084d30e79724057d0a75225e45afd711c236346709eb56cdb022100ec91216b99fdbd66b9d501a7985801f545f8f90bbbb8e5e9393f120f12d643c0 +049bb20bd89b275d654c8a3bde8262b7b98b939f93a76929332c090ed0606661c90697c0f910206ef9caa136f9557122f5229e1e028324bc69197f6ba6f9c4603a 9a240baddbc2297e63c59cd273b8412e83e27da9aa90d7bbbf31a2338d208d67 30450220044944a8bd3c6a252ad2c50b66b66b32a7bd736d433eaff44c13b9f850d15b93022100fa300df45dd00ab84a743210d41704e0a23705fbbd95fb103cfdc98c2e9b5137 +04987df80fccecc297c66f84821279648f0868ca30beea4231eb7bf189071055abbf61a75469d379ae09245ebb39d584d9f67a83130ee95c45bd76b5d9e01aa7aa 17e5410cd8db696e37aaae85d3e687852305ac9540d553dc414fd362bdaf2dd6 3045022038d52df4f8a494be36aee617ca5fb28e585895190fa58e5aba199ccf1c90371b022100bb2960426f8e196d9a42fb02579f85ae26ab9956918241bd77f02bb6dfab3a6a