After accomplishing Task 2, see Codex_Response... for details.
This commit is contained in:
parent
fab12ad9bf
commit
d483d40d5c
16 changed files with 888 additions and 0 deletions
88
tools/verify_examples.pl
Executable file
88
tools/verify_examples.pl
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Digest::SHA qw(sha256);
|
||||
use FindBin qw($Bin);
|
||||
use JSON::PP;
|
||||
use lib "$Bin";
|
||||
use LXMF::MessagePack qw(pack_array parse_item);
|
||||
|
||||
my $examples_dir = "$Bin/../examples";
|
||||
my $manifest = read_json("$examples_dir/lxmf_message_vectors.json");
|
||||
my $minimal = read_hex("$examples_dir/lxmf_message_minimal.hex");
|
||||
my $stamped = read_hex("$examples_dir/lxmf_message_stamped.hex");
|
||||
|
||||
verify_lxmessage("minimal", $minimal, $manifest, 4);
|
||||
verify_lxmessage("stamped", $stamped, $manifest, 5);
|
||||
|
||||
check(unpack("H*", $minimal) eq $manifest->{minimal_lxmf_hex}, "minimal full bytes match manifest");
|
||||
check(unpack("H*", $stamped) eq $manifest->{stamped_lxmf_hex}, "stamped full bytes match manifest");
|
||||
|
||||
print "All LXMessage test-vector checks passed.\n";
|
||||
|
||||
sub verify_lxmessage {
|
||||
my ($name, $bytes, $expected, $expected_count) = @_;
|
||||
|
||||
check(length($bytes) > 96, "$name vector has fixed prefix and payload");
|
||||
my $destination_hash = substr($bytes, 0, 16);
|
||||
my $source_hash = substr($bytes, 16, 16);
|
||||
my $signature = substr($bytes, 32, 64);
|
||||
my $packed_payload = substr($bytes, 96);
|
||||
|
||||
check(unpack("H*", $destination_hash) eq $expected->{destination_hash_hex}, "$name destination hash");
|
||||
check(unpack("H*", $source_hash) eq $expected->{source_hash_hex}, "$name source hash");
|
||||
check(unpack("H*", $signature) eq $expected->{signature_hex}, "$name signature position and length");
|
||||
|
||||
my $offset = 0;
|
||||
my $payload = parse_item($packed_payload, \$offset);
|
||||
check($offset == length($packed_payload), "$name payload consumes all remaining bytes");
|
||||
check($payload->{type} eq "array", "$name payload is a MessagePack array");
|
||||
check(@{$payload->{items}} == $expected_count, "$name payload has $expected_count entries");
|
||||
|
||||
my @items = @{$payload->{items}};
|
||||
check($items[0]{type} eq "float64", "$name payload[0] timestamp is float64");
|
||||
check($items[0]{value} == $expected->{timestamp}, "$name payload[0] timestamp value");
|
||||
check($items[1]{type} eq "binary", "$name payload[1] title is binary");
|
||||
check(unpack("H*", $items[1]{value}) eq $expected->{title_hex}, "$name payload[1] title value");
|
||||
check($items[2]{type} eq "binary", "$name payload[2] content is binary");
|
||||
check(unpack("H*", $items[2]{value}) eq $expected->{content_hex}, "$name payload[2] content value");
|
||||
check($items[3]{type} eq "map", "$name payload[3] fields is a map");
|
||||
check(@{$items[3]{entries}} == 0, "$name payload[3] fields map is empty");
|
||||
|
||||
my $unstamped_payload = pack_array(map { $_->{raw} } @items[0 .. 3]);
|
||||
my $message_id = sha256($destination_hash . $source_hash . $unstamped_payload);
|
||||
my $signed_part = $destination_hash . $source_hash . $unstamped_payload . $message_id;
|
||||
|
||||
check(unpack("H*", $unstamped_payload) eq $expected->{payload_without_stamp_hex}, "$name canonical unstamped payload");
|
||||
check(unpack("H*", $message_id) eq $expected->{message_id_hex}, "$name message ID excludes optional stamp");
|
||||
check(unpack("H*", $signed_part) eq $expected->{signed_part_hex}, "$name signature input excludes optional stamp");
|
||||
|
||||
if ($expected_count == 5) {
|
||||
check($items[4]{type} eq "binary", "$name payload[4] stamp is binary");
|
||||
check(unpack("H*", $items[4]{value}) eq $expected->{stamp_hex}, "$name payload[4] stamp value");
|
||||
}
|
||||
}
|
||||
|
||||
sub read_json {
|
||||
my ($path) = @_;
|
||||
open my $fh, "<:raw", $path or die "cannot read $path: $!\n";
|
||||
local $/;
|
||||
return JSON::PP->new->decode(<$fh>);
|
||||
}
|
||||
|
||||
sub read_hex {
|
||||
my ($path) = @_;
|
||||
open my $fh, "<:raw", $path or die "cannot read $path: $!\n";
|
||||
local $/;
|
||||
my $hex = <$fh>;
|
||||
$hex =~ s/\s+//g;
|
||||
die "$path contains non-hexadecimal data\n" if $hex =~ /[^0-9a-fA-F]/;
|
||||
return pack("H*", $hex);
|
||||
}
|
||||
|
||||
sub check {
|
||||
my ($condition, $description) = @_;
|
||||
die "not ok - $description\n" unless $condition;
|
||||
print "ok - $description\n";
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue