interledgerjs / five-bells-condition

JavaScript implementation of Crypto Conditions validation and fulfillment
https://github.com/rfcs/crypto-conditions
Other
31 stars 21 forks source link

Diffeculty in fulfilling a ed25519 signature #51

Closed inacali closed 8 years ago

inacali commented 8 years ago

Hi guys I am playing around with interledger at the moment, and am trying to better understand crypto conditions by building a simple client using ilp-core and five bells ledger ilp plugin, so far I've got the example to work with the pre-image 256, but having difficulty in getting an ed25519 signature to fulfill, the transaction is failing due to condition not being fulfilled, Am i right in thinking the fulfillment serialized uri is what is required to fulfill the condition of an ed25519 signature or is it something else? Whilst fulfilling the condition on the reciever client I am getting an UnmetConditionError.

Here are the steps I've taken so far

  1. First I created the ed25519 condition like in the readme section of FB conditons, by creating a ed25519() and setting a public key.
  2. The sender then sends crypto condition along with the other transfer details to receiver.
  3. The receiver receives the transaction, and signs a message with his privateKey to fulfill the condition.
  4. The receiver calls the serializeUri() method after signing the message with his private key to get the fulfillmentUri.
  5. The receiver then then tries to fulfill the condition by using this fulfillCondition method, with fulfillment being the fulfillmentUri.

receiver.on('receive', function(transfer){ console.log("Here is the transfer", transfer ) receiver.fulfillCondition(transfer.id, fulfillment) .then(() => { console.log('Successfully submitted fulfillment' + fulfillment) return 'sent' }) .catch((err) => { console.log('Error submitting fulfillment', err) }) })

  1. instead of fulfilling like in the preimage example. I get the following error. ExternalError: Remote error: status=422 body={"id":"UnmetConditionError","message":"Invalid fulfillment: ValidationError: Invalid ed25519 signature"}
  2. Even though when validate the condition and fulfillment using const result = cc.validateFulfillment(fulfillment, condition, message) I get true.

Am i missing a step in fulfilling a signature? or is something else incorrect. Sorry in advance if this is wrong forum for these type of questions?

emschwartz commented 8 years ago

This is definitely the right place to ask questions!

Could you share the code sample you're using so I can try to reproduce the error?

inacali commented 8 years ago

Sure here is a gist of the sender and receiver clients.

https://gist.github.com/inacali/b14864b2ed91c3e9b9b4b55f3630d0f7

emschwartz commented 8 years ago

I think this is actually a bug in the five-bells-ledger. cc.validateFulfillment expects a message to be passed in as the last parameter but the ledger is only passing the fulfillment and condition.

If you run the following and leave out the message from the second to last line you'll see the same ValidationError: Invalid ed25519 signature error:

const cc = require('five-bells-condition')
const ed25519 = require('ed25519')

const seed =  Buffer.from('833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42', 'hex')
const keypair = ed25519.MakeKeypair(seed)
const edff = new cc.Ed25519()
edff.setPublicKey(keypair.publicKey)
const condition = edff.getConditionUri()
const message = new Buffer('Hello World! Conditions are here!')
edff.sign(message, seed)
const fulfillment = edff.serializeUri()
const valid = cc.validateFulfillment(fulfillment, condition, message)
console.log('valid', valid)
inacali commented 8 years ago

Thanks for quick reply mate, makes a lot of sense now.

justmoon commented 8 years ago

@emschwartz is incorrect - we're using crypto-conditions as a simple trigger, so the ledger is right in not passing a message.

Basically, all the ledger cares about is that you tell it what it should be waiting for (condition) and when it gets that thing (fulfillment). There is no need for a message to verify.

If you would like to verify a signature with a message in a condition, you need to somehow bake the message into the condition. Fortunately, there is a way to do just that: Use a prefix condition! Basically, you create your ed25519 condition as normal, and then you wrap it in a prefix condition.

In effect the ledger will call validateFulfillment(prefixFulfillment, prefixCondition, message = '') and the prefix condition with prefix 'your message' in turn will prepend that to the empty message and call validateFulfillment(edFulfillment, edCondition, message = 'your message') which is what you wanted.

I've updated your gist for you. Untested, but this should work: https://gist.github.com/justmoon/2a1b7b4e0138a20be415c2607fd94c0a

inacali commented 8 years ago

Was working down the different types didn't get to the prefix type yet, now very clear how useful it is. Thanks a bunch to both of you. I will close this issue now.