Set `prev` to Pigeon::EMPTY_MESSAGE rather than `nil`

This commit is contained in:
Netscape Navigator 2020-03-30 08:49:29 -05:00
parent b5089bb905
commit 3a03d1b589
4 changed files with 47 additions and 14 deletions

View File

@ -35,6 +35,7 @@ Eg: `pigeon identity show` becomes `./pigeon-cli show`.
- [X] Move literals into `Pigeon` module as constants, again.
- [X] pigeon message find
- [X] pigeon message find-all for local feed.
- [ ] Fork detection?
- [ ] Use URNs instead of multihash?
- [ ] pigeon bundle consume (We are minimally feature complete at this point)
- [ ] Fix the diagram in the spec document

26
dist/pigeon.rb vendored
View File

@ -60,10 +60,28 @@ module Pigeon
# /Constants for internal use only
class Helpers
def self.verify_string(identity, signature, string)
key = Ed25519::VerifyKey.new(decode_multihash(identity.public_key))
raw_sig = decode_multihash(signature)
key.verify(raw_sig, string)
def self.verify_string(identity, string_signature, string)
binary_signature = decode_multihash(string_signature)
string_key = identity.public_key
binary_key = decode_multihash(string_key)
verify_key = Ed25519::VerifyKey.new(binary_key)
# puts "=" * 200
# puts string
# puts "=" * 200
# puts "binary_key: #{binary_key.inspect[0..150]}"
# puts "binary_signature: #{binary_signature.inspect[0..150]}"
# puts "identity: #{identity.inspect[0..150]}"
# puts "string_key: #{string_key.inspect[0..150]}"
# puts "string_signature: #{string_signature.inspect[0..150]}"
# puts "string: #{string.inspect[0..150]}"
# puts "verify_key: #{verify_key.inspect[0..150]}"
verify_key.verify(binary_signature, string)
# rescue => e
# key1 = identity.instance_variable_get(:@signing_key).verify_key
# binding.pry
end
def self.decode_multihash(string)

View File

@ -9,13 +9,16 @@ module Pigeon
VERFIY_ERROR = "Expected field `%s` to equal %s, got: %s"
# Author a new message.
def self.publish(draft)
author = LocalIdentity.current
depth = Pigeon::Storage
.current
.get_message_count_for(LocalIdentity.current.public_key)
msg = self.new(author: LocalIdentity.current,
.get_message_count_for(author.public_key)
count = store.get_message_count_for(author.public_key)
msg = self.new(author: author,
kind: draft.kind,
body: draft.body,
depth: depth)
depth: depth,
prev: store.get_message_by_depth(author.public_key, count - 1))
# We might need to add conditional logic here
# Currently YAGNI since all Drafts we handle today
# are authored by LocalIdentity.current
@ -29,6 +32,7 @@ module Pigeon
new(author: RemoteIdentity.new(author),
kind: kind,
body: body,
prev: prev,
signature: signature,
depth: depth)
end
@ -59,7 +63,7 @@ module Pigeon
def verify_depth_prev_and_depth
count = store.get_message_count_for(author.public_key)
expected_prev = store.get_message_by_depth(author.public_key, count - 1)
expected_prev = store.get_message_by_depth(author.public_key, count - 1) || Pigeon::EMPTY_MESSAGE
assert("depth", depth, count)
assert("prev", prev, expected_prev)
@ -70,15 +74,14 @@ module Pigeon
Helpers.verify_string(author, signature, tpl)
end
def initialize(author:, kind:, body:, signature: nil, depth:)
def initialize(author:, kind:, body:, signature: nil, depth:, prev:)
raise MISSING_BODY if body.empty?
@author = author
@kind = kind
@body = body
# Side effects in a constructor? Hmm...
@depth = depth
@signature = author.is_a?(LocalIdentity) ? calculate_signature : signature
@prev = store.get_message_by_depth(@author.public_key, @depth - 1)
@prev = prev || Pigeon::EMPTY_MESSAGE
verify!
store.save_message(self)
end
@ -91,8 +94,12 @@ module Pigeon
@author.sign(template.render_without_signature)
end
def store
def self.store
Pigeon::Storage.current
end
def store
self.class.store
end
end
end

View File

@ -39,7 +39,7 @@ RSpec.describe Pigeon::Message do
expect(message.body).to eq(draft.body)
expect(message.depth).to eq(0)
expect(message.kind).to eq("unit_test")
expect(message.prev).to eq(nil)
expect(message.prev).to eq(Pigeon::EMPTY_MESSAGE)
expect(message.signature.include?(Pigeon::SIG_FOOTER)).to eq(true)
expect(message.signature.length).to be > 99
actual = message.render
@ -68,7 +68,7 @@ RSpec.describe Pigeon::Message do
all.push(message)
expect(message.depth).to eq(expected_depth)
if expected_depth == 0
expect(message.prev).to be nil
expect(message.prev).to eq(Pigeon::EMPTY_MESSAGE)
else
expect(message.prev).to eq(all[expected_depth - 1].multihash)
end
@ -78,6 +78,11 @@ RSpec.describe Pigeon::Message do
it "verifies accuracy of hash chain" do
m1 = create_message({ "a" => "b" })
m2 = create_message({ "c" => "d" })
# ./dist/pigeon.rb:66:in `verify_string'
# ./dist/pigeon/message.rb:70:in `verify_signature'
# ./dist/pigeon/message.rb:47:in `verify!'
# ./dist/pigeon/message.rb:82:in `initialize'
m3 = create_message({ "e" => "f" })
m4 = create_message({ "g" => "h" })
expect(m1.prev).to eq(nil)
@ -109,6 +114,8 @@ RSpec.describe Pigeon::Message do
expect(key1.seed).to eq(key2.seed)
expect(sig1).to eq(sig2)
combinations = [[key1, sig1], [key1, sig2], [key2, sig1], [key2, sig2]]
combinations.map { |(key, sig)| key.verify_key.verify(sig, plaintext) }
sig1_b64 = Base64.urlsafe_encode64(sig1) + Pigeon::SIG_FOOTER
sig2_b64 = Base64.urlsafe_encode64(sig2) + Pigeon::SIG_FOOTER