use v6.d; use Test; use Test::Mock; use Bitcoin::Core::Secp256k1; plan 4; use-ok 'Bitcoin::Core::Secp256k1'; my $secp256k1 = Bitcoin::Core::Secp256k1.new; subtest { plan 7; my $data = { key => '6fcc37ea5e9e09fec6c83e5fbd7a745e3eee81d16ebd861c9e66f55518c19798', msg => '1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8' }; ok $secp256k1.verify_private_key(:privkey($data)), 'privkey verified'; my $pubkey = $secp256k1.create_public_key(:privkey($data)); my $pk = $secp256k1.compressed_public_key(:pubkey($pubkey)); ok $pk, 'compressed pubkey defined'; is $pk.bytes, 33, 'compressed pubkey length'; is-deeply $pk, buf8.new(0x03, 0x1d, 0xd0, 0xa4, 0xe0, 0xdd, 0x8f, 0xf0, 0x95, 0xd9, 0xea, 0x3c, 0xc7, 0x41, 0xc9, 0x77, 0x37, 0x58, 0xf3, 0xb3, 0x90, 0xbd, 0x69, 0xd8, 0x2e, 0x89, 0x31, 0xd2, 0xb2, 0x76, 0xca, 0xd1, 0x86), 'compressed pubkey verified'; my $signature = $secp256k1.ecdsa_sign(:privkey($data), :msg($data)); my $normalized_sig = $secp256k1.signature_normalize(:sig($signature)); ok $secp256k1.verify_ecdsa_sign(:pubkey($pubkey), :msg($data), :sig($normalized_sig)), 'signature verified'; my $compact_sig = $secp256k1.signature_serialize(:sig($normalized_sig)); is-deeply $normalized_sig, buf8.new(0x76, 0x97, 0x61, 0xB5, 0xE2, 0x48, 0x8E, 0x38, 0x72, 0x6B, 0x8E, 0xB0, 0xD4, 0xE3, 0xFA, 0x80, 0xDF, 0xFE, 0x46, 0x53, 0x80, 0x74, 0xCB, 0x1C, 0x29, 0x5C, 0x1D, 0x7C, 0x6F, 0x64, 0x1F, 0x2F, 0x02, 0x50, 0x7D, 0x2D, 0x0B, 0x3D, 0x3B, 0xB1, 0x91, 0x6E, 0xF6, 0x5F, 0x4C, 0x2D, 0x37, 0x9A, 0x37, 0x8A, 0x07, 0xC2, 0x0A, 0x30, 0xD4, 0x3C, 0x4E, 0x0C, 0xC2, 0x89, 0xAE, 0x50, 0xFB, 0x1C), 'signature buffer verified'; is-deeply $compact_sig, buf8.new(0x2f, 0x1f, 0x64, 0x6f, 0x7c, 0x1d, 0x5c, 0x29, 0x1c, 0xcb, 0x74, 0x80, 0x53, 0x46, 0xfe, 0xdf, 0x80, 0xfa, 0xe3, 0xd4, 0xb0, 0x8e, 0x6b, 0x72, 0x38, 0x8e, 0x48, 0xe2, 0xb5, 0x61, 0x97, 0x76, 0x1c, 0xfb, 0x50, 0xae, 0x89, 0xc2, 0x0c, 0x4e, 0x3c, 0xd4, 0x30, 0x0a, 0xc2, 0x07, 0x8a, 0x37, 0x9a, 0x37, 0x2d, 0x4c, 0x5f, 0xf6, 0x6e, 0x91, 0xb1, 0x3b, 0x3d, 0x0b, 0x2d, 0x7d, 0x50, 0x02), 'compact signature buffer verified'; }, 'Secp256k1 create, sign, verify tests on predefined pubkey and msg'; subtest { plan 1; my UInt $iterations = 100; my Bool $subtestok = True; for ^$iterations { my $data = { key => random32bytes(), msg => random32bytes() }; if $secp256k1.verify_private_key(:privkey($data)) { my $pubkey = $secp256k1.create_public_key(:privkey($data)); my $pk = $secp256k1.compressed_public_key(:pubkey($pubkey)); my $signature = $secp256k1.ecdsa_sign(:privkey($data), :msg($data)); my $normalized_sig = $secp256k1.signature_normalize(:sig($signature)); if !$secp256k1.verify_ecdsa_sign(:pubkey($pubkey), :msg($data), :sig($normalized_sig)) { $subtestok = False; last; } } else { $subtestok = False; last; } } ok $subtestok, sprintf("checked %d random private keys and signatures", $iterations); }, 'Secp256k1 create, sign, verify tests on pre-defined privkey and msg'; subtest { plan 1; my $data = { key => '6fcc37ea5e9e09fec6c83e5fbd7a745e3eee81d16ebd861c9e66f55518c19798', msg => '1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8' }; my $secp256k1 = Bitcoin::Core::Secp256k1.new; my $signature = $secp256k1.ecdsa_sign(:privkey($data), :msg($data)); is $signature.bytes, 64, 'signature length'; }, 'README Synopsys'; done-testing; sub random32bytes returns Str { my $buffer = buf8.new; while $buffer.bytes < 32 { $buffer.push(255.rand.Int || 0xff); } return $buffer.map({$_ < 16 ?? '0' ~ $_.base(16) !! $_.base(16)}).join(q{}).lc; }