Skip to content

Commit

Permalink
Add a test for edge cases
Browse files Browse the repository at this point in the history
  • Loading branch information
bbrtj committed Sep 17, 2024
1 parent b2e4cbc commit acb33a2
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
6 changes: 5 additions & 1 deletion Secp256k1.xs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ void secp256k1_perl_replace_signature(secp256k1_perl *perl_ctx, secp256k1_ecdsa_

secp256k1_perl* ctx_from_sv(SV* self)
{
if (!(sv_isobject(self) && sv_derived_from(self, "Bitcoin::Secp256k1"))) {
croak("calling Bitcoin::Secp256k1 methods is only valid in object context");
}

return (secp256k1_perl*) SvIV(SvRV(self));
}

Expand Down Expand Up @@ -88,7 +92,7 @@ new(classname)
SPAGAIN;

if (count != 1) {
croak("Calling Bytes::Random::Secure::random_bytes went wrong in Bitcoin::Secp256k1::new");
croak("calling Bytes::Random::Secure::random_bytes went wrong in Bitcoin::Secp256k1::new");
}

tmp = POPs;
Expand Down
60 changes: 60 additions & 0 deletions t/edge-cases.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use Test2::V0;
use Bitcoin::Secp256k1;

use lib 't/lib';
use Secp256k1Test;

################################################################################
# This tests if all foreseeable edge cases are handled correctly
################################################################################

my $secp = Bitcoin::Secp256k1->new;
my %t = Secp256k1Test->test_data;

subtest 'should die on constructor with arguments' => sub {
my $ex = dies { Bitcoin::Secp256k1->new('argument') };
like $ex, qr/\QUsage: Bitcoin::Secp256k1::new(classname)\E/, 'exception ok';
};

subtest 'should die on low level methods without constructed object' => sub {
my $ex = dies { Bitcoin::Secp256k1->_pubkey };
like $ex, qr/calling Bitcoin::Secp256k1 methods is only valid in object context/, 'exception ok';
};

subtest 'should die on high level methods without constructed object' => sub {
my $ex = dies { Bitcoin::Secp256k1->create_public_key("\x12" x 32) };
like $ex, qr/calling Bitcoin::Secp256k1 methods is only valid in object context/, 'exception ok';
};

subtest 'should die with reference private key' => sub {
my $ex = dies { $secp->create_public_key([]) };
like $ex, qr/requires a 32-byte secret key/, 'exception ok';
};

subtest 'should die with invalid length private key' => sub {
my $ex;

$ex = dies { $secp->create_public_key("\x12" x 31) };
like $ex, qr/requires a 32-byte secret key/, 'too short ok';

$ex = dies { $secp->create_public_key("\x12" x 33) };
like $ex, qr/requires a 32-byte secret key/, 'too long ok';
};

subtest 'should die with invalid public key' => sub {
my $ex = dies { $secp->verify_digest("\x12" x 65, $t{sig}, "\x12" x 32) };
like $ex, qr/the input does not appear to be a valid public key/, 'exception ok';
};

subtest 'should die with invalid signature' => sub {
my $ex = dies { $secp->verify_digest($t{pubkey}, "\x12" x 65, "\x12" x 32) };
like $ex, qr/the input does not appear to be a valid signature/, 'exception ok';
};

subtest 'should die with invalid digest' => sub {
my $ex = dies { $secp->verify_digest($t{pubkey}, $t{sig}, "\x12" x 35) };
like $ex, qr/requires a 32-byte message hash/, 'exception ok';
};

done_testing;

0 comments on commit acb33a2

Please sign in to comment.