DigiByte-DigiID

 view release on metacpan or  search on metacpan

lib/DigiByte/DigiID.pm  view on Meta::CPAN


sub extract_nonce {
    my ($uri)   = @_;
    my ($nonce) = ( $uri =~ m/[\?\&]x=([^\&]+)/ );
    return $nonce;
}

sub verify_signature {
    my ( $address, $signature, $message, $testnet ) = @_;

    my $decoded_address = _base58check_decode( $address, $testnet );
    my @decoded_address = split //, $decoded_address;

    if (   length($decoded_address) != 21
        || ( $decoded_address[0] ne "\x1E" && !$testnet )
        || ( $decoded_address[0] ne "\x6F" && $testnet ) )
    {
        die "invalid DigiByte address";
    }

    my $decoded_signature = decode_base64($signature);
    my @decoded_signature = split //, $decoded_signature;

    if ( length($decoded_signature) != 65 ) {
        die "invalid signature";
    }

    my $recovery_flags = ord( $decoded_signature[0] ) - 27;

    if ( $recovery_flags < 0 || $recovery_flags > 7 ) {
        die "invalid signature type";
    }

    my $is_compressed = ( $recovery_flags & 4 ) != 0;

    my $message_hash = sha256(
        sha256(
                "\x19DigiByte Signed Message:\n"
              . _num_to_var_int_string( length($message) )
              . $message
        )
    );

    my $pubkey = do {
        my $r = _bin2gmp( substr( $decoded_signature, 1,  32 ) );
        my $s = _bin2gmp( substr( $decoded_signature, 33, 32 ) );
        my $e = _bin2gmp($message_hash);
        my $g = $Point->new(%SECP256K1);

        _recover_pubkey( $r, $s, $e, $recovery_flags, $g );
    };

    if ( !$pubkey ) {
        die 'unable to recover key';
    }

lib/DigiByte/DigiID.pm  view on Meta::CPAN


    my $derived_address;

    if ($testnet) {
        $derived_address = "\x6F" . $ripemd160->hash( sha256($pub_bin_str) );
    }
    else {
        $derived_address = "\x1E" . $ripemd160->hash( sha256($pub_bin_str) );
    }

    return $decoded_address eq $derived_address;
}

sub _base58check_decode {
    my ( $address, $testnet ) = @_;

    my $decoded_address = $address;

    $decoded_address =~
      tr{123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz}
                          {0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv};

    $decoded_address =~ s/^0+//;

    my $v = Math::BigInt->from_base( $decoded_address, 58 );

    $v = _gmp2bin($v);

    foreach my $chr ( split //, $address ) {
        if ( $chr ne '1' ) {
            last;
        }
        if ($testnet) {
            $v = "\x6F$v";
        }



( run in 1.420 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )