Skip to content

Commit

Permalink
export Role and add dynamic server example to readme
Browse files Browse the repository at this point in the history
  • Loading branch information
arik-so committed Nov 26, 2019
1 parent 84a0c9d commit d493286
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 5 deletions.
94 changes: 94 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,100 @@ const message = Buffer.from('Welcome!', 'ascii');
const serializedMessage = transmissionHandler.send(message); // serializedMessage is what we send over TCP
```

### Dynamically Process and Decrypt

You can set up a local TCP server with node and test the connection with a real Lightning node.
For this setup, we're gonna use a local public key `036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7`,
and we will initiate the handshake using `lncli`.

```typescript
import * as net from 'net';
import {Socket} from 'net';
import {Handshake, Role, TransmissionHandler} from 'bolt08';

// publicKey: 036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7
const privateKey = Buffer.from('1212121212121212121212121212121212121212121212121212121212121212', 'hex');
const port = 1337;

const handshakeHandler = new Handshake({privateKey});
let transmissionHandler: TransmissionHandler;
let pendingData = Buffer.alloc(0);

function processIncomingData(data, client: Socket) {
// there is some unprocessed data that we will prepend to the newly received data for processing
const inputData = Buffer.concat([pendingData, data]);
pendingData = Buffer.alloc(0);

console.log('Processing:');
console.log(inputData.toString('hex'));

if (transmissionHandler instanceof TransmissionHandler) {
const decryptedResponse = transmissionHandler.receive(inputData);
console.log('Decrypted:');
console.log(decryptedResponse.toString('hex'));
} else {
const output = handshakeHandler.actDynamically({role: Role.RECEIVER, incomingBuffer: inputData});
if (output.responseBuffer && output.responseBuffer.length > 0) {
const response = output.responseBuffer;

console.log('Responding:');
console.log(response.toString('hex'));
client.write(response)
}
if (output.transmissionHandler && output.transmissionHandler instanceof TransmissionHandler) {
transmissionHandler = output.transmissionHandler;
}
if (output.unreadBuffer && output.unreadBuffer.length > 0) {
pendingData = output.unreadBuffer;
// let's immediately process the remaining data in this case
processIncomingData(Buffer.alloc(0), client);
}
}
}

const server = net.createServer(function (client) {

client.on('data', (data: Buffer) => {
console.log('Received:');
console.log(data.toString('hex'));
processIncomingData(data, client);
});

client.on('error', (error) => {
console.log('Error:');
console.log(error);
});

client.on('close', function () {
console.log('Connection closed');
});

});

server.listen(port, '127.0.0.1');
```

```shell script
lncli connect 036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7@127.0.0.1:10154
```

The output might then look something like this:

> Received:
> 00026ef8318ce2124ef03deeb243e28b92befc76db39de95d2809470e9be7ab26fa41b1183c3133c3803c64a271690abb911
> Processing:
> 00026ef8318ce2124ef03deeb243e28b92befc76db39de95d2809470e9be7ab26fa41b1183c3133c3803c64a271690abb911
> Responding:
> 0003a30c775f2f6734d4a179a4ec78116f3a419f5baecc5a62632bf7d83ea080c7884f4c054fb88119f9812d5c2988f881b0
> Received:
> 0039c112d508c1e26d5088e64467e8a57c087e5eae357aa7fa63f48d165b2ff5b8381a21fe79bed61d6454444ba36cf478b0ad22ff53c5bbb34cf42ef4c284549f7a2a83fc6cc9f85eda787ca725fa0c2b89a2dca947ce9ddc5cd629c4c2202252cfc6b96ba06a3f8b1cec7ec3db
> Processing:
> 0039c112d508c1e26d5088e64467e8a57c087e5eae357aa7fa63f48d165b2ff5b8381a21fe79bed61d6454444ba36cf478b0ad22ff53c5bbb34cf42ef4c284549f7a2a83fc6cc9f85eda787ca725fa0c2b89a2dca947ce9ddc5cd629c4c2202252cfc6b96ba06a3f8b1cec7ec3db
> Processing:
> 2a83fc6cc9f85eda787ca725fa0c2b89a2dca947ce9ddc5cd629c4c2202252cfc6b96ba06a3f8b1cec7ec3db
> Decrypted received:
> 00100002220000022281
## License

MIT
3 changes: 2 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import Handshake from './src/handshake';
import Handshake, {Role} from './src/handshake';
import TransmissionHandler from './src/transmission_handler';

export {
Handshake,
Role,
TransmissionHandler
};
17 changes: 13 additions & 4 deletions src/handshake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class Handshake {
this.hash = new HandshakeHash(Buffer.concat([this.chainingKey, prologue]));
}

public actDynamically({role, incomingBuffer, ephemeralPrivateKey, remotePublicKey}: { role?: Role, incomingBuffer?: Buffer, ephemeralPrivateKey?: Buffer, remotePublicKey?: Buffer }): { responseBuffer?: Buffer, transmissionHandler?: TransmissionHandler } {
public actDynamically({role, incomingBuffer, ephemeralPrivateKey, remotePublicKey}: { role?: Role, incomingBuffer?: Buffer, ephemeralPrivateKey?: Buffer, remotePublicKey?: Buffer }): { responseBuffer?: Buffer, transmissionHandler?: TransmissionHandler, unreadBuffer?: Buffer } {
if (!(this.role in Role)) {
if (!(role in Role)) {
throw new Error('invalid role');
Expand All @@ -63,6 +63,7 @@ export default class Handshake {
this.nextActIndex = 0;
}

let unreadBuffer: Buffer = null;
let responseBuffer: Buffer = null;
let txHander: TransmissionHandler;

Expand Down Expand Up @@ -92,7 +93,9 @@ export default class Handshake {
if (!incomingBuffer) {
throw new Error('incoming message must be known to receive handshake');
}
this.processActOne(incomingBuffer);

unreadBuffer = incomingBuffer.slice(50);
this.processActOne(incomingBuffer.slice(0, 50));

responseBuffer = this.serializeActTwo({ephemeralPrivateKey: this.ephemeralPrivateKey.toBuffer(32)});

Expand All @@ -103,7 +106,9 @@ export default class Handshake {
if (!incomingBuffer) {
throw new Error('incoming message must be known to receive handshake');
}
this.processActTwo(incomingBuffer);

unreadBuffer = incomingBuffer.slice(50);
this.processActTwo(incomingBuffer.slice(0, 50));

responseBuffer = this.serializeActThree();
txHander = this.transmissionHandler;
Expand All @@ -112,7 +117,10 @@ export default class Handshake {
if (!incomingBuffer) {
throw new Error('incoming message must be known to receive handshake');
}
this.processActThree(incomingBuffer);

unreadBuffer = incomingBuffer.slice(66);
this.processActThree(incomingBuffer.slice(0, 66));

txHander = this.transmissionHandler;
this.nextActIndex = -1; // we are done
} else {
Expand All @@ -121,6 +129,7 @@ export default class Handshake {

return {
responseBuffer,
unreadBuffer,
transmissionHandler: txHander
};
}
Expand Down

0 comments on commit d493286

Please sign in to comment.