-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4e4119e
Showing
12 changed files
with
1,949 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# Typescript v1 declaration files | ||
typings/ | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
|
||
# MacOS | ||
.DS_Store | ||
|
||
wallet.dat | ||
*.key |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
This project has several examples of onion packets. Each example builds off prior examples to improve security and privacy. | ||
|
||
## Getting Started | ||
|
||
1. Install dependencies | ||
``` | ||
npm install | ||
``` | ||
|
||
2. Run example | ||
``` | ||
npm start ex1 | ||
npm start ex2 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { OnionPayload } from "./OnionPayload"; | ||
|
||
export class OnionPacket { | ||
constructor( | ||
readonly version: number, | ||
readonly payload: OnionPayload, | ||
readonly ephemeralPoint?: Buffer, | ||
readonly hmac?: Buffer | ||
) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export class OnionPayload { | ||
constructor(readonly data?: Buffer, readonly nextPayload?: Buffer, readonly nextHmac?: Buffer) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import * as crypto from "@node-lightning/crypto"; | ||
|
||
export function encryptData(key: Buffer, data: Buffer): Buffer { | ||
const iv = Buffer.alloc(16); | ||
const zeros = Buffer.alloc(data.length); | ||
const stream = crypto.chachaEncrypt(key, iv, zeros); | ||
return crypto.xor(data, stream); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Stupid Example | ||
|
||
This is an example construction that provides zero confidentiality, | ||
integrity, or privacy. | ||
|
||
The onion construction simply "wraps" the prior data by prepending the | ||
new data to it. | ||
|
||
There is no confidentiality as no obfuscation of data is used. | ||
There is no integrity as no MACs are used. | ||
There is no privacy because you can see how many hops exist in the path. | ||
|
||
## Building | ||
|
||
If you have data parts that are each 4-bytes: `11111111` and `22222222` | ||
for hops 1 and 2 respectively... | ||
|
||
Inner onion: `0422222222` | ||
Outer onion: `0411111111` + `0422222222` | ||
|
||
## Reading | ||
|
||
To read is quite simple. Each hop strips and reads the length byte and | ||
associated data from the front of the packet. It then forwards the | ||
remainder of the data. | ||
|
||
Hop1 input: `04111111110422222222` | ||
Hop1 extracts: `0411111111` | ||
Hop1 forwards: `0422222222` | ||
|
||
Hop2 input: `0422222222` | ||
Hop2 extracts: `0422222222` | ||
Hop2 forwards: N/A |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import { BufferReader, BufferWriter } from "@node-lightning/bufio"; | ||
import { OnionPacket } from "../OnionPacket"; | ||
import { OnionPayload } from "../OnionPayload"; | ||
|
||
/** | ||
* Reads info from the packet. No verification of information is | ||
* performed. This code simply reads from the front of the packet, | ||
* removes its information and then forwards on the remainder of the | ||
* packet. | ||
* | ||
* Any node could tamper with information along the way. And since there | ||
* is no decryption, anyone can see the information (no confidentiality). | ||
* | ||
* @param packet | ||
*/ | ||
export function read(packet: Buffer): Buffer { | ||
// Read the packet which usually is constructed as: | ||
// version|eph_key|payload|hmac | ||
|
||
const packetReader = new BufferReader(packet); | ||
console.log("read packet: ", packet.toString("hex")); | ||
|
||
// read version | ||
const version = packetReader.readUInt8(); // expect version 1 | ||
console.log("version: ", version); | ||
|
||
// NO ephemeral key | ||
|
||
// read payload | ||
const payload = packetReader.readBytes(); | ||
console.log("payload: ", payload.toString("hex")); | ||
|
||
// NO HMAC | ||
|
||
// Next we read the payload which is constructed as: | ||
// len|data|next_data|next_hmac | ||
const payloadReader = new BufferReader(payload); | ||
|
||
// read len | ||
const len = payloadReader.readUInt8(); | ||
console.log("payload len: ", len); | ||
|
||
// read data | ||
const data = payloadReader.readBytes(len); | ||
console.log("payload data:", data.toString("hex")); | ||
|
||
// read next payload | ||
const nextPayload = payloadReader.eof ? Buffer.alloc(0) : payloadReader.readBytes(); | ||
console.log("next payload:", nextPayload.toString("hex")); | ||
|
||
// NO NEXT HMAC | ||
console.log(""); | ||
|
||
// Abort when we don't have any more data | ||
if (!nextPayload.length) { | ||
return; | ||
} | ||
|
||
// Return the next packet | ||
const nextPacket = new BufferWriter(); | ||
nextPacket.writeUInt8(version); | ||
// nextPacket.writeBytes(ephemeralPoint); - no ephemeral point | ||
nextPacket.writeBytes(nextPayload); | ||
// nextPacket.writeBytes(nextHmac); - no hmac | ||
return nextPacket.toBuffer(); | ||
} | ||
|
||
/** | ||
* This example is really stupid but it acts as the foundation for | ||
* building cryptographic onions that actually protect information. This | ||
* construction simply takes the data and builds a linear ordering of | ||
* the data. There is no MAC, no shared secrets, nothing. | ||
* | ||
* As a result, any observer can see the data. Any observer can see | ||
* how many hops there are. Any hop can tamper with the data. So we | ||
* completely lack anonymity, confidentiality, and integrity. | ||
* | ||
* @param data - data to wrap in onion for each hop | ||
*/ | ||
export function build(version: number, data: Buffer[]): Buffer { | ||
let lastHopData: Buffer = Buffer.alloc(0); | ||
|
||
// Iterate in reverse order to construct our onion from the center | ||
// to the outside. This is not required for this implementation since | ||
// there is no cryptographic wrapping, however we can use a similar | ||
// construct in future implementations that improve on how things work. | ||
while (data.length) { | ||
// Extract the currrent hop information | ||
const currentHopData = data.pop(); | ||
|
||
// Prepend the current hop information to the existing information | ||
const w = new BufferWriter(); | ||
|
||
// write length | ||
w.writeBigSize(currentHopData.length); | ||
console.log("data size:", currentHopData.length); | ||
|
||
// write data | ||
w.writeBytes(currentHopData); | ||
console.log("data: ", currentHopData.toString("hex")); | ||
|
||
// write prior data | ||
w.writeBytes(lastHopData); | ||
console.log("last data:", lastHopData.toString("hex")); | ||
|
||
lastHopData = w.toBuffer(); | ||
console.log("onion: ", lastHopData.toString("hex")); | ||
console.log(""); | ||
} | ||
|
||
// Return the outer layer of the onion | ||
const packet = new BufferWriter(); | ||
packet.writeUInt8(version); | ||
packet.writeBytes(lastHopData); | ||
return packet.toBuffer(); | ||
} |
Oops, something went wrong.