TODO: Continue removing footer / renaming sigils. 33 examples, 17 failures

This commit is contained in:
Netscape Navigator 2020-06-02 08:53:42 -05:00
parent 351f7db3e7
commit c10b809193
19 changed files with 33 additions and 50 deletions

View File

@ -46,10 +46,8 @@ module Pigeon
BLOB_SIGIL = "FILE." BLOB_SIGIL = "FILE."
MESSAGE_SIGIL = "TEXT." MESSAGE_SIGIL = "TEXT."
IDENTITY_SIGIL = "TEXT." IDENTITY_SIGIL = "USER."
STRING_SIGIL = "\"" STRING_SIGIL = "\""
IDENTITY_FOOTER = ".ed25519"
SIG_FOOTER = ".sig.ed25519"
# Error messages # Error messages
PREV_REQUIRES_SAVE = "Can't fetch `prev` on unsaved messages" PREV_REQUIRES_SAVE = "Can't fetch `prev` on unsaved messages"
@ -61,8 +59,6 @@ module Pigeon
RUNAWAY_LOOP = "RUNAWAY LOOP DETECTED" RUNAWAY_LOOP = "RUNAWAY LOOP DETECTED"
# Constants for internal use only: # Constants for internal use only:
FOOTERS_REGEX = Regexp.new("#{SIG_FOOTER}|#{IDENTITY_FOOTER}")
SIG_RANGE = (SIG_FOOTER.length * -1)..-1
BLOB_BYTE_LIMIT = 360_000 BLOB_BYTE_LIMIT = 360_000
class Helpers class Helpers
@ -270,11 +266,8 @@ module Pigeon
end end
def self.decode_multihash(string) def self.decode_multihash(string)
if string[SIG_RANGE] == SIG_FOOTER # "FEED.", "FILE.", "USER." etc..
return b32_decode(string.gsub(SIG_FOOTER, "")) return b32_decode(string[5..])
else
return b32_decode(string[1..].gsub(FOOTERS_REGEX, ""))
end
end end
end end
end end

View File

@ -23,7 +23,7 @@ module Pigeon
def []=(key, value) def []=(key, value)
raise STRING_KEYS_ONLY unless key.is_a?(String) raise STRING_KEYS_ONLY unless key.is_a?(String)
case value[0] case value[0..4]
when BLOB_SIGIL, MESSAGE_SIGIL, IDENTITY_SIGIL, STRING_SIGIL when BLOB_SIGIL, MESSAGE_SIGIL, IDENTITY_SIGIL, STRING_SIGIL
body[key] = value body[key] = value
else else

View File

@ -58,7 +58,7 @@ module Pigeon
# TODO: Create regexes using string and Regexp.new() for cleaner regexes. # TODO: Create regexes using string and Regexp.new() for cleaner regexes.
NUMERIC = /\d{1,7}/ NUMERIC = /\d{1,7}/
NULL_VALUE = /NONE/ NULL_VALUE = /NONE/
FEED_VALUE = /FEED.{52}/ FEED_VALUE = /USER.{52}/
MESG_VALUE = /TEXT.{52}/ MESG_VALUE = /TEXT.{52}/
BLOB_VALUE = /FILE.{52}/ BLOB_VALUE = /FILE.{52}/
STRG_VALUE = /".{1,128}"/ STRG_VALUE = /".{1,128}"/
@ -80,7 +80,7 @@ module Pigeon
PREV = /prev (#{MESG_VALUE}|#{NULL_VALUE})\n/ PREV = /prev (#{MESG_VALUE}|#{NULL_VALUE})\n/
KIND = /kind #{ALPHANUMERICISH}\n/ KIND = /kind #{ALPHANUMERICISH}\n/
BODY_ENTRY = /#{ALPHANUMERICISH}:#{ANY_VALUE}\n/ BODY_ENTRY = /#{ALPHANUMERICISH}:#{ANY_VALUE}\n/
FOOTER_ENTRY = /signature .*{103}\.sig\.ed25519\n?/ FOOTER_ENTRY = /signature .*{103}\n?/
LEXER_STATES = [HEADER = :header, BODY = :body, FOOTER = :footer] LEXER_STATES = [HEADER = :header, BODY = :body, FOOTER = :footer]

View File

@ -21,13 +21,12 @@ module Pigeon
bytes = @signing_key.verify_key.to_bytes bytes = @signing_key.verify_key.to_bytes
b64 = Helpers.b32_encode(bytes) b64 = Helpers.b32_encode(bytes)
@multihash ||= [IDENTITY_SIGIL, b64, IDENTITY_FOOTER].join("") @multihash ||= [IDENTITY_SIGIL, b64].join("")
end end
def sign(string) def sign(string)
hex = @signing_key.sign(string) hex = @signing_key.sign(string)
b64 = Helpers.b32_encode(hex) Helpers.b32_encode(hex)
b64 + SIG_FOOTER
end end
end end
end end

View File

@ -12,7 +12,7 @@ module Pigeon
tpl = render tpl = render
digest = Digest::SHA256.digest(tpl) digest = Digest::SHA256.digest(tpl)
sha256 = Helpers.b32_encode(digest) sha256 = Helpers.b32_encode(digest)
"#{MESSAGE_SIGIL}#{sha256}#{BLOB_FOOTER}" "#{MESSAGE_SIGIL}#{sha256}"
end end
def initialize(author:, def initialize(author:,

View File

@ -60,7 +60,7 @@ module Pigeon
raw_digest = Digest::SHA256.digest(data) raw_digest = Digest::SHA256.digest(data)
b32_hash = Helpers.b32_encode(raw_digest) b32_hash = Helpers.b32_encode(raw_digest)
multihash = [BLOB_SIGIL, b32_hash, BLOB_FOOTER].join("") multihash = "#{BLOB_SIGIL}#{b32_hash}"
write_to_disk(multihash, data) write_to_disk(multihash, data)
multihash multihash
end end

View File

@ -40,7 +40,7 @@ RSpec.describe Pigeon::Message do
it "does not ingest messages from blocked peers" do it "does not ingest messages from blocked peers" do
db.reset_database db.reset_database
antagonist = "TEXT.YDVX7JWTVNRFEVYC8E8DS9MVWW9KB66F1XQYMNB2FQ6QBPXKAQX0.ed25519" antagonist = "TEXT.YDVX7JWTVNRFEVYC8E8DS9MVWW9KB66F1XQYMNB2FQ6QBPXKAQX0"
db.block_peer(antagonist) db.block_peer(antagonist)
db.import_bundle(BLOCKED_PEER_FIXTURE_PATH) db.import_bundle(BLOCKED_PEER_FIXTURE_PATH)
expect(db.all_messages.count).to eq(0) expect(db.all_messages.count).to eq(0)

View File

@ -23,7 +23,7 @@ RSpec.describe Pigeon::Draft do
"lipmaa DRAFT", "lipmaa DRAFT",
"prev DRAFT", "prev DRAFT",
"\na:\"bar\"", "\na:\"bar\"",
"b:&CHHABX8Q9D9Q0BY2BBZ6FA7SMAFNE9GGMSDTZVZZC9TK2N9F15QG.sha256", "b:FILE.CHHABX8Q9D9Q0BY2BBZ6FA7SMAFNE9GGMSDTZVZZC9TK2N9F15QG",
"\n", "\n",
].join("\n") ].join("\n")
@ -40,10 +40,7 @@ RSpec.describe Pigeon::Draft do
hash = db.add_blob(File.read("./logo.png")) hash = db.add_blob(File.read("./logo.png"))
expectations = { expectations = {
kind: "unit_test", kind: "unit_test",
body: { body: { "a" => "bar".to_json, "b" => hash },
"a" => "bar".to_json,
"b" => hash,
},
} }
db.update_draft("a", "bar") db.update_draft("a", "bar")
db.update_draft("b", hash) db.update_draft("b", hash)

View File

@ -2,7 +2,7 @@ require "spec_helper"
RSpec.describe Pigeon::Lexer do RSpec.describe Pigeon::Lexer do
EXPECTED_TOKENS1 = [ EXPECTED_TOKENS1 = [
[:AUTHOR, "TEXT.3DWXGXHXCB02WV1TEA47J43HHTTBNMM496ANME7FZ2SYPGA9KTZG.ed25519", 69], [:AUTHOR, "TEXT.3DWXGXHXCB02WV1TEA47J43HHTTBNMM496ANME7FZ2SYPGA9KTZG", 69],
[:DEPTH, 0, 77], [:DEPTH, 0, 77],
[:KIND, "unit_test1", 93], [:KIND, "unit_test1", 93],
[:LIPMAA, "NONE", 105], [:LIPMAA, "NONE", 105],
@ -10,32 +10,32 @@ RSpec.describe Pigeon::Lexer do
[:HEADER_END, 116], [:HEADER_END, 116],
[:BODY_ENTRY, "foo", "\"bar\"", 126], [:BODY_ENTRY, "foo", "\"bar\"", 126],
[:BODY_END, 127], [:BODY_END, 127],
[:SIGNATURE, "2BTX69F6E30BBDNQ0XTT20NCG8C0B393SGQSW5M00G8KF33CAE1YB1MPT760KSTRV2ZJCCNJ883JXEWTTTEEJ8JBHNWEJQFSZ035P0R.sig.ed25519", 253], [:SIGNATURE, "2BTX69F6E30BBDNQ0XTT20NCG8C0B393SGQSW5M00G8KF33CAE1YB1MPT760KSTRV2ZJCCNJ883JXEWTTTEEJ8JBHNWEJQFSZ035P0R", 253],
[:MESSAGE_DELIM, 254], [:MESSAGE_DELIM, 254],
[:AUTHOR, "TEXT.3DWXGXHXCB02WV1TEA47J43HHTTBNMM496ANME7FZ2SYPGA9KTZG.ed25519", 323], [:AUTHOR, "TEXT.3DWXGXHXCB02WV1TEA47J43HHTTBNMM496ANME7FZ2SYPGA9KTZG", 323],
[:DEPTH, 1, 331], [:DEPTH, 1, 331],
[:KIND, "unit_test2", 347], [:KIND, "unit_test2", 347],
[:LIPMAA, "NONE", 359], [:LIPMAA, "NONE", 359],
[:PREV, "TEXT.RW61BRVRAAM31RFPQ8W6MTYBN840Y898MQ2GTDRSMQES84RPJKHG.sha256", 425], [:PREV, "TEXT.RW61BRVRAAM31RFPQ8W6MTYBN840Y898MQ2GTDRSMQES84RPJKHG", 425],
[:HEADER_END, 426], [:HEADER_END, 426],
[:BODY_ENTRY, "bar", "\"baz\"", 436], [:BODY_ENTRY, "bar", "\"baz\"", 436],
[:BODY_END, 437], [:BODY_END, 437],
[:SIGNATURE, "TXC15FZZVK30Q5ZRERFR9VXAJ8KKE58ZGF1JEBNETJN1MHN9EGRQJP7PX99NBZMX177XZWE3M2PCPPF4VBN4J93W2H5FTNJ7K7VG818.sig.ed25519", 563], [:SIGNATURE, "TXC15FZZVK30Q5ZRERFR9VXAJ8KKE58ZGF1JEBNETJN1MHN9EGRQJP7PX99NBZMX177XZWE3M2PCPPF4VBN4J93W2H5FTNJ7K7VG818", 563],
[:MESSAGE_DELIM, 564], [:MESSAGE_DELIM, 564],
[:AUTHOR, "TEXT.3DWXGXHXCB02WV1TEA47J43HHTTBNMM496ANME7FZ2SYPGA9KTZG.ed25519", 633], [:AUTHOR, "TEXT.3DWXGXHXCB02WV1TEA47J43HHTTBNMM496ANME7FZ2SYPGA9KTZG", 633],
[:DEPTH, 2, 641], [:DEPTH, 2, 641],
[:KIND, "unit_test3", 657], [:KIND, "unit_test3", 657],
[:LIPMAA, "NONE", 669], [:LIPMAA, "NONE", 669],
[:PREV, "TEXT.CSX0CDPY96DGTGT9V0TNZJ4S84JTSK4AYNE193VXF8AH9ZJHT82G.sha256", 735], [:PREV, "TEXT.CSX0CDPY96DGTGT9V0TNZJ4S84JTSK4AYNE193VXF8AH9ZJHT82G", 735],
[:HEADER_END, 736], [:HEADER_END, 736],
[:BODY_ENTRY, "cats", "\"meow\"", 748], [:BODY_ENTRY, "cats", "\"meow\"", 748],
[:BODY_END, 749], [:BODY_END, 749],
[:SIGNATURE, "91TBR3H90720KGA8FPSSEPHB1R6QGZ0YGTC2T6RT1GBWV9TNR95CWHF0KB4P57RMJQPSC6EA6D5FDN5PC8VM7V8BC32F17V9R9VDR0G.sig.ed25519", 875], [:SIGNATURE, "91TBR3H90720KGA8FPSSEPHB1R6QGZ0YGTC2T6RT1GBWV9TNR95CWHF0KB4P57RMJQPSC6EA6D5FDN5PC8VM7V8BC32F17V9R9VDR0G", 875],
[:MESSAGE_DELIM, 875], [:MESSAGE_DELIM, 875],
].freeze ].freeze
MESSAGE_LINES = [ MESSAGE_LINES = [
"author @VG44QCHKA38E7754RQ5DAFBMMD2CCZQRZ8BR2J4MRHHGVTHGW670.ed25519", "author @VG44QCHKA38E7754RQ5DAFBMMD2CCZQRZ8BR2J4MRHHGVTHGW670",
"depth 0", "depth 0",
"kind unit_test", "kind unit_test",
"lipmaa NONE", "lipmaa NONE",
@ -43,7 +43,7 @@ RSpec.describe Pigeon::Lexer do
"", "",
"foo:\"bar\"", "foo:\"bar\"",
"", "",
"signature hHvhdvUcrabhFPz52GSGa9_iuudOsGEEE7S0o0WJLqjQyhLfgUy72yppHXsG6T4E21p6EEI6B3yRcjfurxegCA==.sig.ed25519", "signature hHvhdvUcrabhFPz52GSGa9_iuudOsGEEE7S0o0WJLqjQyhLfgUy72yppHXsG6T4E21p6EEI6B3yRcjfurxegCA==",
].freeze ].freeze
let(:db) do let(:db) do
@ -86,7 +86,7 @@ RSpec.describe Pigeon::Lexer do
expect(hash[:DEPTH]).to eq(message.depth) expect(hash[:DEPTH]).to eq(message.depth)
expect(hash[:KIND]).to eq(message.kind) expect(hash[:KIND]).to eq(message.kind)
expect(hash[:PREV]).to eq Pigeon::NOTHING expect(hash[:PREV]).to eq Pigeon::NOTHING
expect(hash[:SIGNATURE]).to eq(message.signature) expect(hash[:SIGNATURE]).to eq(messagenature)
end end
it "catches syntax errors" do it "catches syntax errors" do

View File

@ -9,14 +9,13 @@ RSpec.describe Pigeon::LocalIdentity do
HELLO_SIGNATURE = [ HELLO_SIGNATURE = [
"FARSW9ENM9DK1JD4M9ES1D4WWVG5SXT8Z6VXT6HXRV17M4Q9X5W2", "FARSW9ENM9DK1JD4M9ES1D4WWVG5SXT8Z6VXT6HXRV17M4Q9X5W2",
"T5Y7ZZC0C5JYBTMBQ2HAQBRGWGAK42PK3BHQXAX1FPTKBFJQJ1R", "T5Y7ZZC0C5JYBTMBQ2HAQBRGWGAK42PK3BHQXAX1FPTKBFJQJ1R",
".sig.ed25519",
].join("") ].join("")
it "signs arbitrary data" do it "signs arbitrary data" do
expect(kp.sign("hello")).to eq(HELLO_SIGNATURE) expect(kp.sign("hello")).to eq(HELLO_SIGNATURE)
end end
it "generates a pair from a seed" do it "generates a pair from a seed" do
x = "TEXT.XSZY1ME6QMA5BBSJ8QSDJCSG6EVDTCKYNMV221SB7B2NZR5K09J0.ed25519" x = "USER.XSZY1ME6QMA5BBSJ8QSDJCSG6EVDTCKYNMV221SB7B2NZR5K09J0"
expect(kp.multihash).to eq(x) expect(kp.multihash).to eq(x)
y = "2PRTG7F13HWF1HPW9FF9NDSYGSQS5VXQ2WMZY0A510J64AE9G840" y = "2PRTG7F13HWF1HPW9FF9NDSYGSQS5VXQ2WMZY0A510J64AE9G840"
expect(kp.private_key).to eq(y) expect(kp.private_key).to eq(y)
@ -24,11 +23,7 @@ RSpec.describe Pigeon::LocalIdentity do
it "strips headers" do it "strips headers" do
whatever = "af697f3063d46fe9546f651c08c378f8" whatever = "af697f3063d46fe9546f651c08c378f8"
example = [ example = [Pigeon::IDENTITY_SIGIL, whatever].join("")
Pigeon::IDENTITY_SIGIL,
whatever,
Pigeon::IDENTITY_FOOTER,
].join("")
result = Pigeon::Helpers.decode_multihash(example) result = Pigeon::Helpers.decode_multihash(example)
expect(result).to eq(Pigeon::Helpers.b32_decode(whatever)) expect(result).to eq(Pigeon::Helpers.b32_decode(whatever))
end end

View File

@ -42,7 +42,6 @@ RSpec.describe Pigeon::Message do
expect(message.depth).to eq(0) expect(message.depth).to eq(0)
expect(message.kind).to eq("unit_test") expect(message.kind).to eq("unit_test")
expect(message.prev).to eq(Pigeon::NOTHING) expect(message.prev).to eq(Pigeon::NOTHING)
expect(message.signature.include?(Pigeon::SIG_FOOTER)).to eq(true)
expect(message.signature.length).to be > 99 expect(message.signature.length).to be > 99
actual = message.render actual = message.render
expected = [ expected = [
@ -124,8 +123,8 @@ RSpec.describe Pigeon::Message do
combinations = [[key1, sig1], [key1, sig2], [key2, sig1], [key2, sig2]] combinations = [[key1, sig1], [key1, sig2], [key2, sig1], [key2, sig2]]
combinations.map { |(key, sig)| key.verify_key.verify(sig, plaintext) } combinations.map { |(key, sig)| key.verify_key.verify(sig, plaintext) }
sig1_b64 = Pigeon::Helpers.b32_encode(sig1) + Pigeon::SIG_FOOTER sig1_b64 = Pigeon::Helpers.b32_encode(sig1)
sig2_b64 = Pigeon::Helpers.b32_encode(sig2) + Pigeon::SIG_FOOTER sig2_b64 = Pigeon::Helpers.b32_encode(sig2)
expect(message.signature).to eq(sig1_b64) expect(message.signature).to eq(sig1_b64)
expect(message.signature).to eq(sig2_b64) expect(message.signature).to eq(sig2_b64)
end end
@ -139,7 +138,7 @@ RSpec.describe Pigeon::Message do
[:LIPMAA, "TEXT.4PE7S4XCCAYPQ42S98K730CEW6ME5HRWJKHHEGYVYPFHSJWXEY1G"], [:LIPMAA, "TEXT.4PE7S4XCCAYPQ42S98K730CEW6ME5HRWJKHHEGYVYPFHSJWXEY1G"],
[:HEADER_END], [:HEADER_END],
[:BODY_ENTRY, "duplicate", "This key is a duplicate."], [:BODY_ENTRY, "duplicate", "This key is a duplicate."],
[:SIGNATURE, "DN7yPTE-m433ND3jBL4oM23XGxBKafjq0Dp9ArBQa_TIGU7DmCxTumieuPBN-NKxlx_0N7-c5zjLb5XXVHYPCQ==.sig.ed25519"], [:SIGNATURE, "DN7yPTE-m433ND3jBL4oM23XGxBKafjq0Dp9ArBQa_TIGU7DmCxTumieuPBN-NKxlx_0N7-c5zjLb5XXVHYPCQ=="],
[:MESSAGE_DELIM], [:MESSAGE_DELIM],
] ]
e = Pigeon::Helpers::VerificationError e = Pigeon::Helpers::VerificationError

View File

@ -10,7 +10,7 @@ RSpec.describe Pigeon::Lexer do
let(:tokens) { Pigeon::Lexer.tokenize(example_bundle) } let(:tokens) { Pigeon::Lexer.tokenize(example_bundle) }
BAD_TOKENS = [ BAD_TOKENS = [
[:AUTHOR, "TEXT.DYdgK1KUInVtG3lS45hA1HZ-jTuvfLKsxDpXPFCve04=.ed25519"], [:AUTHOR, "FEED.DYdgK1KUInVtG3lS45hA1HZ-jTuvfLKsxDpXPFCve04="],
[:KIND, "invalid"], [:KIND, "invalid"],
[:PREV, "NONE"], [:PREV, "NONE"],
[:DEPTH, 0], [:DEPTH, 0],
@ -18,7 +18,7 @@ RSpec.describe Pigeon::Lexer do
[:HEADER_END], [:HEADER_END],
[:BODY_ENTRY, "duplicate", "Pigeon does not allow duplicate keys."], [:BODY_ENTRY, "duplicate", "Pigeon does not allow duplicate keys."],
[:BODY_ENTRY, "duplicate", "This key is a duplicate."], [:BODY_ENTRY, "duplicate", "This key is a duplicate."],
[:SIGNATURE, "DN7yPTE-m433ND3jBL4oM23XGxBKafjq0Dp9ArBQa_TIGU7DmCxTumieuPBN-NKxlx_0N7-c5zjLb5XXVHYPCQ==.sig.ed25519"], [:SIGNATURE, "DN7yPTE-m433ND3jBL4oM23XGxBKafjq0Dp9ArBQa_TIGU7DmCxTumieuPBN-NKxlx_0N7-c5zjLb5XXVHYPCQ=="],
[:MESSAGE_DELIM], [:MESSAGE_DELIM],
].freeze ].freeze

View File

@ -2,8 +2,8 @@ require "spec_helper"
RSpec.describe Pigeon::Storage do RSpec.describe Pigeon::Storage do
LOGO_BLOB = File.read("./logo.png") LOGO_BLOB = File.read("./logo.png")
IDS = %w[@ZMWM5PSXRN7RFRMSWW1E3V5DNGC4XGGJTHKCAGB48SNRG4XXE5NG.ed25519 IDS = %w[USER.ZMWM5PSXRN7RFRMSWW1E3V5DNGC4XGGJTHKCAGB48SNRG4XXE5NG
@VF0Q4KXQNY6WCAXF17GAZGDPAX8XKM70SB8N7V0NSD1H370ZCJBG.ed25519].freeze USER.VF0Q4KXQNY6WCAXF17GAZGDPAX8XKM70SB8N7V0NSD1H370ZCJBG].freeze
let(:db) do let(:db) do
db = Pigeon::Database.new db = Pigeon::Database.new