Skip to content

Commit

Permalink
opentimestamps: address comments and improve things.
Browse files Browse the repository at this point in the history
  • Loading branch information
fiatjaf committed Sep 26, 2023
1 parent 0a22a32 commit 5e7c01a
Show file tree
Hide file tree
Showing 8 changed files with 1,750 additions and 1,734 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ mpeg_ts,
[msgpack](doc/formats.md#msgpack),
ogg,
ogg_page,
opentimestamps,
opus_packet,
[pcap](doc/formats.md#pcap),
pcapng,
Expand Down
3 changes: 2 additions & 1 deletion doc/formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
|[`msgpack`](#msgpack) |MessagePack |<sub></sub>|
|`ogg` |OGG&nbsp;file |<sub>`ogg_page` `vorbis_packet` `opus_packet` `flac_metadatablock` `flac_frame`</sub>|
|`ogg_page` |OGG&nbsp;page |<sub></sub>|
|`opentimestamps` |OpenTimestamps&nbsp;file |<sub></sub>|
|`opus_packet` |Opus&nbsp;packet |<sub>`vorbis_comment`</sub>|
|[`pcap`](#pcap) |PCAP&nbsp;packet&nbsp;capture |<sub>`link_frame` `tcp_stream` `ipv4_packet`</sub>|
|`pcapng` |PCAPNG&nbsp;packet&nbsp;capture |<sub>`link_frame` `tcp_stream` `ipv4_packet`</sub>|
Expand Down Expand Up @@ -130,7 +131,7 @@
|`ip_packet` |Group |<sub>`icmp` `icmpv6` `tcp_segment` `udp_datagram`</sub>|
|`link_frame` |Group |<sub>`bsd_loopback_frame` `ether8023_frame` `ipv4_packet` `ipv6_packet` `sll2_packet` `sll_packet`</sub>|
|`mp3_frame_tags` |Group |<sub>`mp3_frame_vbri` `mp3_frame_xing`</sub>|
|`probe` |Group |<sub>`adts` `aiff` `apple_bookmark` `ar` `avi` `avro_ocf` `bitcoin_blkdat` `bplist` `bzip2` `caff` `elf` `flac` `gif` `gzip` `html` `jpeg` `json` `jsonl` `luajit` `macho` `macho_fat` `matroska` `moc3` `mp3` `mp4` `mpeg_ts` `ogg` `pcap` `pcapng` `png` `tar` `tiff` `toml` `tzif` `wasm` `wav` `webp` `xml` `yaml` `zip`</sub>|
|`probe` |Group |<sub>`adts` `aiff` `apple_bookmark` `ar` `avi` `avro_ocf` `bitcoin_blkdat` `bplist` `bzip2` `caff` `elf` `flac` `gif` `gzip` `html` `jpeg` `json` `jsonl` `luajit` `macho` `macho_fat` `matroska` `moc3` `mp3` `mp4` `mpeg_ts` `ogg` `opentimestamps` `pcap` `pcapng` `png` `tar` `tiff` `toml` `tzif` `wasm` `wav` `webp` `xml` `yaml` `zip`</sub>|
|`tcp_stream` |Group |<sub>`dns_tcp` `rtmp` `tls`</sub>|
|`udp_payload` |Group |<sub>`dns`</sub>|

Expand Down
1,872 changes: 942 additions & 930 deletions doc/formats.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions format/all/all.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ $ fq -n _registry.groups.probe
"moc3",
"mp4",
"ogg",
"opentimestamps",
"pcap",
"pcapng",
"png",
Expand Down Expand Up @@ -130,6 +131,7 @@ mpeg_ts MPEG Transport Stream
msgpack MessagePack
ogg OGG file
ogg_page OGG page
opentimestamps OpenTimestamps file
opus_packet Opus packet
pcap PCAP packet capture
pcapng PCAPNG packet capture
Expand Down
2 changes: 1 addition & 1 deletion format/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ var (
Bitcoin_Block = &decode.Group{Name: "bitcoin_block"}
Bitcoin_Script = &decode.Group{Name: "bitcoin_script"}
Bitcoin_Transaction = &decode.Group{Name: "bitcoin_transaction"}
OpenTimestamps = &decode.Group{Name: "ots"}
Opentimestamps = &decode.Group{Name: "opentimestamps"}
Bplist = &decode.Group{Name: "bplist"}
BSD_Loopback_Frame = &decode.Group{Name: "bsd_loopback_frame"}
BSON = &decode.Group{Name: "bson"}
Expand Down
144 changes: 72 additions & 72 deletions format/opentimestamps/ots.go
Original file line number Diff line number Diff line change
@@ -1,123 +1,123 @@
package opentimestamps

import (
"encoding/binary"
"errors"
"io"
// https://opentimestamps.org/

import (
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
"github.com/wader/fq/pkg/scalar"
"golang.org/x/exp/slices"
)

func init() {
interp.RegisterFormat(
format.OpenTimestamps,
format.Opentimestamps,
&decode.Format{
Description: "OpenTimestamps file",
Dependencies: nil,
DecodeFn: decodeOTSFile,
Description: "OpenTimestamps file",
DecodeFn: decodeOTSFile,
Groups: []*decode.Group{format.Probe},
})
}

func decodeVarInt(d *decode.D) uint64 {
var value uint64 = 0
var shift uint64 = 0

for {
b := d.U8()
value |= (b & 0b01111111) << shift
shift += 7
if b&0b10000000 == 0 {
break
}
}

return value
}
const (
continuationByte = 0xff
attestationTag = 0x00
appendTag = 0xf0
prependTag = 0xf1
reverseTag = 0xf2
hexlifyTag = 0xf3
sha1Tag = 0x02
ripemd160Tag = 0x03
sha256Tag = 0x08
keccak256Tag = 0x67
)

var (
headerMagic = []byte{0x00, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x00, 0x00, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x00, 0xbf, 0x89, 0xe2, 0xe8, 0x84, 0xe8, 0x92, 0x94}
pendingMagic = binary.BigEndian.Uint64([]byte{0x83, 0xdf, 0xe3, 0x0d, 0x2e, 0xf9, 0x0c, 0x8e})
bitcoinMagic = binary.BigEndian.Uint64([]byte{0x05, 0x88, 0x96, 0x0d, 0x73, 0xd7, 0x19, 0x01})
headerMagic = []byte{0x00, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x73, 0x00, 0x00, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x00, 0xbf, 0x89, 0xe2, 0xe8, 0x84, 0xe8, 0x92, 0x94}
calendarMagic uint64 = 0x83_df_e3_0d_2e_f9_0c_8e
bitcoinMagic uint64 = 0x05_88_96_0d_73_d7_19_01

binaryTags = []byte{appendTag, prependTag}
)

var attestationMapper = scalar.UintMapSymStr{
pendingMagic: "calendar",
bitcoinMagic: "bitcoin",
calendarMagic: "calendar",
bitcoinMagic: "bitcoin",
}

var opMapper = scalar.UintMapSymStr{
0xf0: "append",
0xf1: "prepend",
0xf2: "reverse",
0xf3: "hexlify",
0x02: "sha1",
0x03: "ripemd160",
0x08: "sha256",
0x67: "keccak256",
0x00: "attestation",
0xff: "continuation_byte",
var tagMapper = scalar.UintMapSymStr{
continuationByte: "continuation_byte",
attestationTag: "attestation",
appendTag: "append",
prependTag: "prepend",
reverseTag: "reverse",
hexlifyTag: "hexlify",
sha1Tag: "sha1",
ripemd160Tag: "ripemd160",
sha256Tag: "sha256",
keccak256Tag: "keccak256",
}

func decodeOTSFile(d *decode.D) any {
d.Endian = decode.BigEndian

d.FieldRawLen("magic_bytes", int64(8*len(headerMagic)), d.AssertBitBuf(headerMagic))
d.FieldUintFn("version", decodeVarInt)
tag := d.FieldU8("digest_hash_algorithm", opMapper,
scalar.UintDescription("algorithm used to hash the source file"))
tag := d.FieldU8("digest_hash_algorithm", tagMapper)
if tag != 8 {
name := opMapper[tag]
d.Errorf("only sha256 supported, got %x: %s", tag, name)
name := tagMapper[tag]
d.Fatalf("only sha256 supported, got %x: %s", tag, name)
return nil
}
d.FieldRawLen("digest", 8*32, scalar.RawHex,
scalar.BitBufDescription("hash of the source file"))
d.FieldRawLen("digest", 8*32, scalar.RawHex)

d.FieldArray("instructions", func(d *decode.D) {
for {
if b, err := d.TryPeekBytes(1); errors.Is(err, io.EOF) {
break
} else if b[0] == 0x00 {
d.FieldStruct("attestation", func(d *decode.D) {
d.FieldU8("attestation_tag", scalar.UintMapSymBool{0x00: true})
d.FieldArray("operations", func(d *decode.D) {
for d.NotEnd() {
d.FieldStruct("operation", func(d *decode.D) {
tag := d.FieldU8("tag", tagMapper)
if tag == attestationTag {
val := d.FieldU64BE("attestation_type", attestationMapper)
d.FieldUintFn("attestation_varbytes_size", decodeVarInt)
switch val {
case bitcoinMagic:
d.FieldUintFn("block", decodeVarInt,
scalar.UintDescription("bitcoin block height to check for the merkle root"))
case pendingMagic:
d.FieldUintFn("block", decodeVarInt)
case calendarMagic:
nurl := d.FieldUintFn("url_size", decodeVarInt)
d.FieldUTF8("url", int(nurl),
scalar.StrDescription("url of the calendar server to get the final proof"))
d.FieldUTF8("url", int(nurl))
default:
d.Errorf("unknown attestation tag %x", val)
d.Fatalf("unknown attestation tag %x", val)
}
})
} else if b[0] == 0xff {
d.FieldStruct("continuation_byte", func(d *decode.D) {
d.FieldU8("continuation_byte", scalar.UintMapSymBool{0xff: true},
scalar.UintDescription("tells we should continue reading after the next attestation block"))
})
} else {
d.FieldStruct("instruction", func(d *decode.D) {
tag := d.FieldU8("op", opMapper)
if name, ok := opMapper[tag]; ok {
} else {
if _, ok := tagMapper[tag]; ok {
// read var bytes if argument
if name == "append" || name == "prepend" {
if slices.Contains(binaryTags, byte(tag)) {
n := d.FieldUintFn("argument_size", decodeVarInt)
d.FieldRawLen("argument", int64(8*n), scalar.RawHex)
}
} else {
d.Errorf("unknown operation tag %x", tag)
d.Fatalf("unknown operation tag %x", tag)
}
})
}
}
})
}
})

return nil
}

func decodeVarInt(d *decode.D) uint64 {
var value uint64 = 0
var shift uint64 = 0

for {
b := d.U8()
value |= (b & 0b01111111) << shift
shift += 7
if b&0b10000000 == 0 {
break
}
}

return value
}

0 comments on commit 5e7c01a

Please sign in to comment.