Help language development. Donate to The Perl Foundation

Bitcoin::Core::Secp256k1 zef:knarkhov last updated on 2021-12-11

t/02.t
use v6.d;
use Test;
use Test::Mock;

use Bitcoin::Core::Secp256k1;

plan 3;

my $secp256k1 = Bitcoin::Core::Secp256k1.new;

subtest {
    plan 2;

    my $data = {
        key => 'e87c09fe1e33f5bd846e51a14ccbdf1d583de3eed34558f14406133fa5176195',
        recover => {
            0 => '445228b342475e525b26adc8587a6086fab77d33f4c40b00ed418f5243f24cdb',
            1 => 'a1bf4f16de2c0c5790593cf22333fef48502b228ff59118aa44539dab425ec49'
        }
    };

    for $data<recover>.keys -> $key {
        my $signature  = $secp256k1.ecdsa_sign(:privkey($data<key>), :msg($data<recover>{$key}), :recover(True));
        my $serialized = $secp256k1.recoverable_signature_serialize(:sig($signature));

        is $serialized<recovery>, $key.Int, 'recovery ' ~ $key.Int.Bool;
    }
}, 'Secp256k1 recovery bit';

subtest {
    plan 1;

    my $data = {
        key => 'e87c09fe1e33f5bd846e51a14ccbdf1d583de3eed34558f14406133fa5176195',
        msg => '445228b342475e525b26adc8587a6086fab77d33f4c40b00ed418f5243f24cdb'
    };

    my $sig_regular = $secp256k1.ecdsa_sign(:privkey($data<key>), :msg($data<msg>), :recover(False));
    my $sig_recover = $secp256k1.ecdsa_sign(:privkey($data<key>), :msg($data<msg>), :recover(True));

    my $converted = $secp256k1.recoverable_signature_convert(:sig($sig_recover));

    is-deeply $sig_regular, $converted, 'recoverable to regular convert';

}, 'Secp256k1 serialize verify';

subtest {
    plan 1;

    my UInt $iterations = 100;
    my Bool $subtestok  = True;

    for ^$iterations {
        my $data = {
            key => 'e87c09fe1e33f5bd846e51a14ccbdf1d583de3eed34558f14406133fa5176195',
            msg => random32bytes()
        };

        my $pubkey = $secp256k1.create_public_key(:privkey($data<key>));
        my $sig    = $secp256k1.ecdsa_sign(:privkey($data<key>), :msg($data<msg>), :recover(True));

        if !$secp256k1.ecdsa_recover(:pubkey($pubkey), :sig($sig), :msg($data<msg>)) {
            $subtestok = False;

            last;
        }
    }

    ok $subtestok, sprintf("recover %d messages by signatures", $iterations);
}, 'Secp256k1 recover messages';

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;
}