dot.dot.dot.exampol
This commit is contained in:
commit
a0bc2d79de
406 changed files with 34577 additions and 0 deletions
6
node_modules/lnsocket/.envrc
generated
vendored
Normal file
6
node_modules/lnsocket/.envrc
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
#use nix
|
||||
|
||||
export PATH=$PWD:$PATH
|
||||
export TODO_FILE=$PWD/TODO
|
||||
|
||||
todo.sh ls || :
|
3
node_modules/lnsocket/.gitmodules
generated
vendored
Normal file
3
node_modules/lnsocket/.gitmodules
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "deps/secp256k1"]
|
||||
path = deps/secp256k1
|
||||
url = https://github.com/bitcoin-core/secp256k1
|
22
node_modules/lnsocket/LICENSE
generated
vendored
Normal file
22
node_modules/lnsocket/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
Copyright 2022 William Casarin. MIT license
|
||||
|
||||
This license applies to everywhere in the codebase, but files with licenses at
|
||||
the top of the file override this for those files.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
210
node_modules/lnsocket/Makefile
generated
vendored
Normal file
210
node_modules/lnsocket/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,210 @@
|
|||
|
||||
CFLAGS=-Wall -Os -Ideps/secp256k1/include -Ideps/libsodium/src/libsodium/include -Ideps
|
||||
LDFLAGS=
|
||||
|
||||
SUBMODULES=deps/secp256k1
|
||||
|
||||
# Build for the simulator
|
||||
XCODEDIR=$(shell xcode-select -p)
|
||||
SIM_SDK=$(XCODEDIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
|
||||
IOS_SDK=$(XCODEDIR)/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
|
||||
|
||||
HEADERS=config.h deps/secp256k1/include/secp256k1.h deps/libsodium/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h
|
||||
ARS=libsecp256k1.a libsodium.a lnsocket.a
|
||||
WASM_ARS=target/js/libsecp256k1.a target/js/libsodium.a target/js/lnsocket.a
|
||||
OBJS=sha256.o hkdf.o hmac.o sha512.o lnsocket.o error.o handshake.o crypto.o bigsize.o commando.o bech32.o
|
||||
ARM64_OBJS=$(OBJS:.o=-arm64.o)
|
||||
X86_64_OBJS=$(OBJS:.o=-x86_64.o)
|
||||
WASM_OBJS=$(OBJS:.o=-wasm.o) lnsocket_wasm-wasm.o
|
||||
BINS=test lnrpc
|
||||
|
||||
DEPS=$(OBJS) $(ARS) $(HEADERS)
|
||||
|
||||
all: $(BINS) $(ARS)
|
||||
|
||||
ios: target/ios/lnsocket.a target/ios/libsodium.a target/ios/libsecp256k1.a
|
||||
|
||||
js: target/js/lnsocket.js target/js/lnsocket.wasm
|
||||
|
||||
node: target/node/lnsocket.js target/node/lnsocket.wasm
|
||||
|
||||
target/node/lnsocket.js: target/tmp/node/lnsocket.js lnsocket_lib.js
|
||||
@mkdir -p target/node
|
||||
cat $^ > $@
|
||||
|
||||
target/js/lnsocket.js: target/tmp/js/lnsocket.js lnsocket_lib.js
|
||||
@mkdir -p target/js
|
||||
cat $^ > $@
|
||||
|
||||
libsodium-1.0.18-stable.tar.gz:
|
||||
wget https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable.tar.gz
|
||||
|
||||
deps/libsodium/configure: libsodium-1.0.18-stable.tar.gz
|
||||
tar xvf $^; \
|
||||
mkdir -p deps; \
|
||||
mv libsodium-stable deps/libsodium
|
||||
|
||||
deps/secp256k1/.git:
|
||||
@tools/refresh-submodules.sh $(SUBMODULES)
|
||||
|
||||
lnsocket.a: $(OBJS)
|
||||
ar rcs $@ $(OBJS)
|
||||
|
||||
target/arm64/lnsocket.a: $(ARM64_OBJS)
|
||||
@mkdir -p target/arm64
|
||||
ar rcs $@ $^
|
||||
|
||||
target/x86_64/lnsocket.a: $(X86_64_OBJS)
|
||||
@mkdir -p target/x86_64
|
||||
ar rcs $@ $^
|
||||
|
||||
target/js/lnsocket.a: $(WASM_OBJS)
|
||||
@mkdir -p target/js
|
||||
emar rcs $@ $^
|
||||
|
||||
target/ios/lnsocket.a: target/x86_64/lnsocket.a target/arm64/lnsocket.a
|
||||
@mkdir -p target/ios
|
||||
lipo -create $^ -output $@
|
||||
|
||||
%-arm64.o: %.c config.h
|
||||
@echo "cc $@"
|
||||
@$(CC) $(CFLAGS) -c $< -o $@ -arch arm64 -isysroot $(IOS_SDK) -target arm64-apple-ios -fembed-bitcode
|
||||
|
||||
%-wasm.o: %.c config.h
|
||||
@echo "emcc $@"
|
||||
@emcc $(CFLAGS) -c $< -o $@
|
||||
|
||||
%-x86_64.o: %.c config.h
|
||||
@echo "cc $@"
|
||||
@$(CC) $(CFLAGS) -c $< -o $@ -arch x86_64 -isysroot $(SIM_SDK) -mios-simulator-version-min=6.0.0 -target x86_64-apple-ios-simulator
|
||||
|
||||
# TODO cross compiled config??
|
||||
config.h: configurator
|
||||
./configurator > $@
|
||||
|
||||
configurator: configurator.c
|
||||
$(CC) $< -o $@
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
@echo "cc $@"
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
deps/secp256k1/include/secp256k1.h: deps/secp256k1/.git
|
||||
|
||||
deps/libsodium/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h: deps/libsodium/configure
|
||||
|
||||
deps/secp256k1/config.log: deps/secp256k1/configure
|
||||
cd deps/secp256k1; \
|
||||
./configure --disable-shared --enable-module-ecdh
|
||||
|
||||
deps/libsodium/config.status: deps/libsodium/configure
|
||||
cd deps/libsodium; \
|
||||
./configure --disable-shared --enable-minimal
|
||||
|
||||
deps/secp256k1/configure: deps/secp256k1/.git
|
||||
cd deps/secp256k1; \
|
||||
patch -p1 < ../../tools/0001-configure-customizable-AR-and-RANLIB.patch; \
|
||||
./autogen.sh
|
||||
|
||||
deps/libsodium/config.log: deps/libsodium/configure
|
||||
cd deps/libsodium; \
|
||||
./configure
|
||||
|
||||
deps/secp256k1/.libs/libsecp256k1.a: deps/secp256k1/config.log
|
||||
cd deps/secp256k1; \
|
||||
make -j libsecp256k1.la
|
||||
|
||||
libsecp256k1.a: deps/secp256k1/.libs/libsecp256k1.a
|
||||
cp $< $@
|
||||
|
||||
libsodium.a: deps/libsodium/src/libsodium/.libs/libsodium.a
|
||||
cp $< $@
|
||||
|
||||
target/ios/libsodium.a: deps/libsodium/libsodium-ios/lib/libsodium.a
|
||||
@mkdir -p target/ios
|
||||
cp $< $@
|
||||
|
||||
target/ios/libsecp256k1.a: deps/secp256k1/libsecp256k1-ios/lib/libsecp256k1.a
|
||||
@mkdir -p target/ios
|
||||
cp $< $@
|
||||
|
||||
target/js/libsecp256k1.a: deps/secp256k1/libsecp256k1-wasm/lib/libsecp256k1.a
|
||||
@mkdir -p target/js
|
||||
cp $< $@
|
||||
|
||||
target/js/libsodium.a: deps/libsodium/libsodium-js/lib/libsodium.a
|
||||
@mkdir -p target/js
|
||||
cp $< $@
|
||||
|
||||
deps/libsodium/libsodium-ios/lib/libsodium.a: deps/libsodium/configure
|
||||
cd deps/libsodium; \
|
||||
./dist-build/ios.sh
|
||||
|
||||
deps/secp256k1/libsecp256k1-ios/lib/libsecp256k1.a: deps/secp256k1/configure
|
||||
./tools/secp-ios.sh
|
||||
|
||||
deps/secp256k1/libsecp256k1-wasm/lib/libsecp256k1.a: deps/secp256k1/configure
|
||||
./tools/secp-wasm.sh
|
||||
|
||||
deps/libsodium/libsodium-js/lib/libsodium.a: deps/libsodium/configure
|
||||
cd deps/libsodium; \
|
||||
./dist-build/emscripten.sh --standard
|
||||
|
||||
deps/libsodium/src/libsodium/.libs/libsodium.a: deps/libsodium/config.log
|
||||
cd deps/libsodium/src/libsodium; \
|
||||
make -j libsodium.la
|
||||
|
||||
install: $(DEPS)
|
||||
mkdir -p $(PREFIX)/lib $(PREFIX)/include
|
||||
cp lnsocket.h $(PREFIX)/include
|
||||
cp lnsocket.a libsecp256k1.a libsodium.a $(PREFIX)/lib
|
||||
|
||||
install-js: js
|
||||
mkdir -p $(PREFIX)/share/lnsocket
|
||||
cp target/js/lnsocket.wasm target/js/lnsocket.js $(PREFIX)/share/lnsocket
|
||||
|
||||
dist-node: node
|
||||
@mkdir -p dist/node
|
||||
cp target/node/lnsocket.wasm target/node/lnsocket.js dist/node
|
||||
|
||||
install-all: install install-js
|
||||
|
||||
check: test
|
||||
@./test
|
||||
|
||||
gocheck:
|
||||
go test ./lnsocket.go
|
||||
|
||||
test: test.o $(DEPS)
|
||||
@echo "ld test"
|
||||
@$(CC) $(CFLAGS) test.o $(OBJS) $(ARS) $(LDFLAGS) -o $@
|
||||
|
||||
lnrpc: lnrpc.o $(DEPS)
|
||||
@echo "ld lnrpc"
|
||||
@$(CC) $(CFLAGS) lnrpc.o $(OBJS) $(ARS) $(LDFLAGS) -o $@
|
||||
|
||||
target/js/lnsocket.wasm: target/tmp/js/lnsocket.js
|
||||
cp target/tmp/js/lnsocket.wasm target/js/lnsocket.wasm
|
||||
|
||||
target/node/lnsocket.wasm: target/tmp/node/lnsocket.js
|
||||
cp target/tmp/node/lnsocket.wasm target/node/lnsocket.wasm
|
||||
|
||||
target/tmp/node/lnsocket.js: $(WASM_ARS) lnsocket_pre.js
|
||||
@mkdir -p target/tmp/node
|
||||
emcc --pre-js lnsocket_pre.js -s MODULARIZE -flto -s 'EXPORTED_FUNCTIONS=["_malloc", "_free"]' -s EXPORTED_RUNTIME_METHODS=ccall,cwrap $(CFLAGS) -Wl,-whole-archive $(WASM_ARS) -Wl,-no-whole-archive -o $@
|
||||
|
||||
target/tmp/js/lnsocket.js: $(WASM_ARS) lnsocket_pre.js
|
||||
@mkdir -p target/tmp/js
|
||||
emcc --pre-js lnsocket_pre.js -s ENVIRONMENT=web -s MODULARIZE -flto -s 'EXPORTED_FUNCTIONS=["_malloc", "_free"]' -s EXPORTED_RUNTIME_METHODS=ccall,cwrap $(CFLAGS) -Wl,-whole-archive $(WASM_ARS) -Wl,-no-whole-archive -o $@
|
||||
|
||||
tags: fake
|
||||
find . -name '*.c' -or -name '*.h' | xargs ctags
|
||||
|
||||
clean: fake
|
||||
rm -rf $(BINS) config.h $(OBJS) $(ARM64_OBJS) $(X86_64_OBJS) $(WASM_OBJS) target
|
||||
|
||||
distclean: clean
|
||||
rm -rf $(ARS) deps target
|
||||
|
||||
|
||||
.PHONY: fake
|
82
node_modules/lnsocket/README.md
generated
vendored
Normal file
82
node_modules/lnsocket/README.md
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
|
||||
# lnsocket
|
||||
|
||||
A simple C library for sending messages over the lightning network
|
||||
|
||||
Thanks to Rusty and the clightning project for much of this code, I have
|
||||
adapted it to be more library friendly.
|
||||
|
||||
|
||||
## Motivation
|
||||
|
||||
I wanted a way to send custom messages to my lightning node, such as RPC.
|
||||
Building this as a simple C library will allow you to speak the lightning
|
||||
network in native applications, like on mobile.
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
You'll need `libtool`, `autoconf`, and `automake` for the `libsodium` &
|
||||
`secp256k1` submodules, but otherwise there are no dependencies.
|
||||
|
||||
You'll need `emscripten` for the `wasm` build.
|
||||
|
||||
## Building
|
||||
|
||||
$ make
|
||||
|
||||
### iOS
|
||||
|
||||
$ make ios
|
||||
|
||||
This will build `lnsocket.a`, `libsodium.a` and `libsecp256k1.a` under
|
||||
`target/ios` for `arm64` and `ios-sim-x86`.
|
||||
|
||||
|
||||
### WASM/JS/Web
|
||||
|
||||
$ make js
|
||||
|
||||
This will build `lnsocket.js` and `lnsocket.wasm` in `target/js` so that you
|
||||
can connect to the lightning network from your browser via websockets. See
|
||||
[examples/websockets.js](examples/websockets.js) for a demo.
|
||||
|
||||
### NodeJS
|
||||
|
||||
$ npm install --save lnsocket
|
||||
|
||||
See [examples/node.js](examples/node.js)
|
||||
|
||||
### Go
|
||||
|
||||
There is a Go version of lnsocket written using lnd's brontide[^3].
|
||||
|
||||
You can import it via:
|
||||
|
||||
import "github.com/jb55/lnsocket/go"
|
||||
|
||||
It is currently used in fiatjaf's makeinvoice go library[^4] if you want an
|
||||
example of its usage.
|
||||
|
||||
## C Examples
|
||||
|
||||
* See [test.c](test.c) for a ping/pong example
|
||||
|
||||
* See [lnrpc.c](lnrpc.c) for an RPC example
|
||||
|
||||
## Contributing
|
||||
|
||||
Send patches to `jb55@jb55.com`
|
||||
|
||||
$ git config format.subjectPrefix 'PATCH lnsocket'
|
||||
$ git config sendemail.to 'William Casarin <jb55@jb55.com>'
|
||||
$ git send-email --annotate HEAD^
|
||||
|
||||
See git-send-email.io[^1] for configuring your mailer
|
||||
|
||||
You can open a PR on github[^2] as well
|
||||
|
||||
[^1]: https://git-send-email.io/
|
||||
[^2]: https://github.com/jb55/lnsocket
|
||||
[^3]: https://github.com/lightningnetwork/lnd/tree/master/brontide
|
||||
[^4]: https://github.com/fiatjaf/makeinvoice/blob/d523b35084af04883f94323dc11a50c2a99d253d/makeinvoice.go#L366
|
7
node_modules/lnsocket/TODO
generated
vendored
Normal file
7
node_modules/lnsocket/TODO
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
dynamic lib
|
||||
automatic towire/fromwire serialization
|
||||
better helpers for building tlvs
|
||||
(C) python bindings
|
||||
(A) websocket test suite
|
||||
(B) nodejs tests
|
||||
C tests
|
211
node_modules/lnsocket/bech32.c
generated
vendored
Normal file
211
node_modules/lnsocket/bech32.c
generated
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
/* Stolen from https://github.com/sipa/bech32/blob/master/ref/c/segwit_addr.c,
|
||||
* with only the two ' > 90' checks hoisted, and more internals exposed */
|
||||
|
||||
/* Copyright (c) 2017, 2021 Pieter Wuille
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "bech32.h"
|
||||
|
||||
static uint32_t bech32_polymod_step(uint32_t pre) {
|
||||
uint8_t b = pre >> 25;
|
||||
return ((pre & 0x1FFFFFF) << 5) ^
|
||||
(-((b >> 0) & 1) & 0x3b6a57b2UL) ^
|
||||
(-((b >> 1) & 1) & 0x26508e6dUL) ^
|
||||
(-((b >> 2) & 1) & 0x1ea119faUL) ^
|
||||
(-((b >> 3) & 1) & 0x3d4233ddUL) ^
|
||||
(-((b >> 4) & 1) & 0x2a1462b3UL);
|
||||
}
|
||||
|
||||
static uint32_t bech32_final_constant(bech32_encoding enc) {
|
||||
if (enc == BECH32_ENCODING_BECH32) return 1;
|
||||
if (enc == BECH32_ENCODING_BECH32M) return 0x2bc830a3;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
const char bech32_charset[] = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
||||
|
||||
const int8_t bech32_charset_rev[128] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
|
||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
|
||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
int bech32_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len, size_t max_input_len, bech32_encoding enc) {
|
||||
uint32_t chk = 1;
|
||||
size_t i = 0;
|
||||
while (hrp[i] != 0) {
|
||||
int ch = hrp[i];
|
||||
if (ch < 33 || ch > 126) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ch >= 'A' && ch <= 'Z') return 0;
|
||||
chk = bech32_polymod_step(chk) ^ (ch >> 5);
|
||||
++i;
|
||||
}
|
||||
if (i + 7 + data_len > max_input_len) return 0;
|
||||
chk = bech32_polymod_step(chk);
|
||||
while (*hrp != 0) {
|
||||
chk = bech32_polymod_step(chk) ^ (*hrp & 0x1f);
|
||||
*(output++) = *(hrp++);
|
||||
}
|
||||
*(output++) = '1';
|
||||
for (i = 0; i < data_len; ++i) {
|
||||
if (*data >> 5) return 0;
|
||||
chk = bech32_polymod_step(chk) ^ (*data);
|
||||
*(output++) = bech32_charset[*(data++)];
|
||||
}
|
||||
for (i = 0; i < 6; ++i) {
|
||||
chk = bech32_polymod_step(chk);
|
||||
}
|
||||
chk ^= bech32_final_constant(enc);
|
||||
for (i = 0; i < 6; ++i) {
|
||||
*(output++) = bech32_charset[(chk >> ((5 - i) * 5)) & 0x1f];
|
||||
}
|
||||
*output = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bech32_encoding bech32_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input, size_t max_input_len) {
|
||||
uint32_t chk = 1;
|
||||
size_t i;
|
||||
size_t input_len = strlen(input);
|
||||
size_t hrp_len;
|
||||
int have_lower = 0, have_upper = 0;
|
||||
if (input_len < 8 || input_len > max_input_len) {
|
||||
return BECH32_ENCODING_NONE;
|
||||
}
|
||||
*data_len = 0;
|
||||
while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') {
|
||||
++(*data_len);
|
||||
}
|
||||
hrp_len = input_len - (1 + *data_len);
|
||||
if (1 + *data_len >= input_len || *data_len < 6) {
|
||||
return BECH32_ENCODING_NONE;
|
||||
}
|
||||
*(data_len) -= 6;
|
||||
for (i = 0; i < hrp_len; ++i) {
|
||||
int ch = input[i];
|
||||
if (ch < 33 || ch > 126) {
|
||||
return BECH32_ENCODING_NONE;
|
||||
}
|
||||
if (ch >= 'a' && ch <= 'z') {
|
||||
have_lower = 1;
|
||||
} else if (ch >= 'A' && ch <= 'Z') {
|
||||
have_upper = 1;
|
||||
ch = (ch - 'A') + 'a';
|
||||
}
|
||||
hrp[i] = ch;
|
||||
chk = bech32_polymod_step(chk) ^ (ch >> 5);
|
||||
}
|
||||
hrp[i] = 0;
|
||||
chk = bech32_polymod_step(chk);
|
||||
for (i = 0; i < hrp_len; ++i) {
|
||||
chk = bech32_polymod_step(chk) ^ (input[i] & 0x1f);
|
||||
}
|
||||
++i;
|
||||
while (i < input_len) {
|
||||
int v = (input[i] & 0x80) ? -1 : bech32_charset_rev[(int)input[i]];
|
||||
if (input[i] >= 'a' && input[i] <= 'z') have_lower = 1;
|
||||
if (input[i] >= 'A' && input[i] <= 'Z') have_upper = 1;
|
||||
if (v == -1) {
|
||||
return BECH32_ENCODING_NONE;
|
||||
}
|
||||
chk = bech32_polymod_step(chk) ^ v;
|
||||
if (i + 6 < input_len) {
|
||||
data[i - (1 + hrp_len)] = v;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (have_lower && have_upper) {
|
||||
return BECH32_ENCODING_NONE;
|
||||
}
|
||||
if (chk == bech32_final_constant(BECH32_ENCODING_BECH32)) {
|
||||
return BECH32_ENCODING_BECH32;
|
||||
} else if (chk == bech32_final_constant(BECH32_ENCODING_BECH32M)) {
|
||||
return BECH32_ENCODING_BECH32M;
|
||||
} else {
|
||||
return BECH32_ENCODING_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
int bech32_convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) {
|
||||
uint32_t val = 0;
|
||||
int bits = 0;
|
||||
uint32_t maxv = (((uint32_t)1) << outbits) - 1;
|
||||
while (inlen--) {
|
||||
val = (val << inbits) | *(in++);
|
||||
bits += inbits;
|
||||
while (bits >= outbits) {
|
||||
bits -= outbits;
|
||||
out[(*outlen)++] = (val >> bits) & maxv;
|
||||
}
|
||||
}
|
||||
if (pad) {
|
||||
if (bits) {
|
||||
out[(*outlen)++] = (val << (outbits - bits)) & maxv;
|
||||
}
|
||||
} else if (((val << (outbits - bits)) & maxv) || bits >= inbits) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int segwit_addr_encode(char *output, const char *hrp, int witver, const uint8_t *witprog, size_t witprog_len) {
|
||||
uint8_t data[65];
|
||||
size_t datalen = 0;
|
||||
bech32_encoding enc = BECH32_ENCODING_BECH32;
|
||||
if (witver > 16) return 0;
|
||||
if (witver == 0 && witprog_len != 20 && witprog_len != 32) return 0;
|
||||
if (witprog_len < 2 || witprog_len > 40) return 0;
|
||||
if (witver > 0) enc = BECH32_ENCODING_BECH32M;
|
||||
data[0] = witver;
|
||||
bech32_convert_bits(data + 1, &datalen, 5, witprog, witprog_len, 8, 1);
|
||||
++datalen;
|
||||
return bech32_encode(output, hrp, data, datalen, 90, enc);
|
||||
}
|
||||
|
||||
int segwit_addr_decode(int* witver, uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) {
|
||||
uint8_t data[84];
|
||||
char hrp_actual[84];
|
||||
size_t data_len;
|
||||
bech32_encoding enc = bech32_decode(hrp_actual, data, &data_len, addr, 90);
|
||||
if (enc == BECH32_ENCODING_NONE) return 0;
|
||||
if (data_len == 0 || data_len > 65) return 0;
|
||||
if (strncmp(hrp, hrp_actual, 84) != 0) return 0;
|
||||
if (data[0] > 16) return 0;
|
||||
if (data[0] == 0 && enc != BECH32_ENCODING_BECH32) return 0;
|
||||
if (data[0] > 0 && enc != BECH32_ENCODING_BECH32M) return 0;
|
||||
*witdata_len = 0;
|
||||
if (!bech32_convert_bits(witdata, witdata_len, 8, data + 1, data_len - 1, 5, 0)) return 0;
|
||||
if (*witdata_len < 2 || *witdata_len > 40) return 0;
|
||||
if (data[0] == 0 && *witdata_len != 20 && *witdata_len != 32) return 0;
|
||||
*witver = data[0];
|
||||
return 1;
|
||||
}
|
134
node_modules/lnsocket/bech32.h
generated
vendored
Normal file
134
node_modules/lnsocket/bech32.h
generated
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
/* Stolen from https://github.com/sipa/bech32/blob/master/ref/c/segwit_addr.h,
|
||||
* with only the two ' > 90' checks hoisted */
|
||||
|
||||
/* Copyright (c) 2017, 2021 Pieter Wuille
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LIGHTNING_COMMON_BECH32_H
|
||||
#define LIGHTNING_COMMON_BECH32_H
|
||||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** Encode a SegWit address
|
||||
*
|
||||
* Out: output: Pointer to a buffer of size 73 + strlen(hrp) that will be
|
||||
* updated to contain the null-terminated address.
|
||||
* In: hrp: Pointer to the null-terminated human readable part to use
|
||||
* (chain/network specific).
|
||||
* ver: Version of the witness program (between 0 and 16 inclusive).
|
||||
* prog: Data bytes for the witness program (between 2 and 40 bytes).
|
||||
* prog_len: Number of data bytes in prog.
|
||||
* Returns 1 if successful.
|
||||
*/
|
||||
int segwit_addr_encode(
|
||||
char *output,
|
||||
const char *hrp,
|
||||
int ver,
|
||||
const uint8_t *prog,
|
||||
size_t prog_len
|
||||
);
|
||||
|
||||
/** Decode a SegWit address
|
||||
*
|
||||
* Out: ver: Pointer to an int that will be updated to contain the witness
|
||||
* program version (between 0 and 16 inclusive).
|
||||
* prog: Pointer to a buffer of size 40 that will be updated to
|
||||
* contain the witness program bytes.
|
||||
* prog_len: Pointer to a size_t that will be updated to contain the length
|
||||
* of bytes in prog.
|
||||
* hrp: Pointer to the null-terminated human readable part that is
|
||||
* expected (chain/network specific).
|
||||
* addr: Pointer to the null-terminated address.
|
||||
* Returns 1 if successful.
|
||||
*/
|
||||
int segwit_addr_decode(
|
||||
int* ver,
|
||||
uint8_t* prog,
|
||||
size_t* prog_len,
|
||||
const char* hrp,
|
||||
const char* addr
|
||||
);
|
||||
|
||||
/** Supported encodings. */
|
||||
typedef enum {
|
||||
BECH32_ENCODING_NONE,
|
||||
BECH32_ENCODING_BECH32,
|
||||
BECH32_ENCODING_BECH32M
|
||||
} bech32_encoding;
|
||||
|
||||
/** Encode a Bech32 or Bech32m string
|
||||
*
|
||||
* Out: output: Pointer to a buffer of size strlen(hrp) + data_len + 8 that
|
||||
* will be updated to contain the null-terminated Bech32 string.
|
||||
* In: hrp : Pointer to the null-terminated human readable part.
|
||||
* data : Pointer to an array of 5-bit values.
|
||||
* data_len: Length of the data array.
|
||||
* max_input_len: Maximum valid length of input (90 for segwit usage).
|
||||
* enc: Which encoding to use (BECH32_ENCODING_BECH32{,M}).
|
||||
* Returns 1 if successful.
|
||||
*/
|
||||
int bech32_encode(
|
||||
char *output,
|
||||
const char *hrp,
|
||||
const uint8_t *data,
|
||||
size_t data_len,
|
||||
size_t max_input_len,
|
||||
bech32_encoding enc
|
||||
);
|
||||
|
||||
/** Decode a Bech32 or Bech32m string
|
||||
*
|
||||
* Out: hrp: Pointer to a buffer of size strlen(input) - 6. Will be
|
||||
* updated to contain the null-terminated human readable part.
|
||||
* data: Pointer to a buffer of size strlen(input) - 8 that will
|
||||
* hold the encoded 5-bit data values.
|
||||
* data_len: Pointer to a size_t that will be updated to be the number
|
||||
* of entries in data.
|
||||
* In: input: Pointer to a null-terminated Bech32 string.
|
||||
* max_input_len: Maximum valid length of input (90 for segwit usage).
|
||||
* Returns BECH32_ENCODING_BECH32{,M} to indicate decoding was successful
|
||||
* with the specified encoding standard. BECH32_ENCODING_NONE is returned if
|
||||
* decoding failed.
|
||||
*/
|
||||
bech32_encoding bech32_decode(
|
||||
char *hrp,
|
||||
uint8_t *data,
|
||||
size_t *data_len,
|
||||
const char *input,
|
||||
size_t max_input_len
|
||||
);
|
||||
|
||||
/* Helper from bech32: translates inbits-bit bytes to outbits-bit bytes.
|
||||
* @outlen is incremented as bytes are added.
|
||||
* @pad is true if we're to pad, otherwise truncate last byte if necessary
|
||||
*/
|
||||
int bech32_convert_bits(uint8_t* out, size_t* outlen, int outbits,
|
||||
const uint8_t* in, size_t inlen, int inbits,
|
||||
int pad);
|
||||
|
||||
/* The charset, and reverse mapping */
|
||||
extern const char bech32_charset[32];
|
||||
extern const int8_t bech32_charset_rev[128];
|
||||
|
||||
#endif /* LIGHTNING_COMMON_BECH32_H */
|
||||
|
140
node_modules/lnsocket/bigsize.c
generated
vendored
Normal file
140
node_modules/lnsocket/bigsize.c
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
|||
/* Copyright Rusty Russell (Blockstream) 2015.
|
||||
William Casarin 2022
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include "config.h"
|
||||
#include "bigsize.h"
|
||||
|
||||
#ifndef SUPERVERBOSE
|
||||
#define SUPERVERBOSE(...)
|
||||
#endif
|
||||
|
||||
size_t bigsize_len(bigsize_t v)
|
||||
{
|
||||
if (v < 0xfd) {
|
||||
return 1;
|
||||
} else if (v <= 0xffff) {
|
||||
return 3;
|
||||
} else if (v <= 0xffffffff) {
|
||||
return 5;
|
||||
} else {
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
|
||||
size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN], bigsize_t v)
|
||||
{
|
||||
u8 *p = buf;
|
||||
|
||||
if (v < 0xfd) {
|
||||
*(p++) = v;
|
||||
} else if (v <= 0xffff) {
|
||||
(*p++) = 0xfd;
|
||||
(*p++) = v >> 8;
|
||||
(*p++) = v;
|
||||
} else if (v <= 0xffffffff) {
|
||||
(*p++) = 0xfe;
|
||||
(*p++) = v >> 24;
|
||||
(*p++) = v >> 16;
|
||||
(*p++) = v >> 8;
|
||||
(*p++) = v;
|
||||
} else {
|
||||
(*p++) = 0xff;
|
||||
(*p++) = v >> 56;
|
||||
(*p++) = v >> 48;
|
||||
(*p++) = v >> 40;
|
||||
(*p++) = v >> 32;
|
||||
(*p++) = v >> 24;
|
||||
(*p++) = v >> 16;
|
||||
(*p++) = v >> 8;
|
||||
(*p++) = v;
|
||||
}
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
size_t bigsize_get(const u8 *p, size_t max, bigsize_t *val)
|
||||
{
|
||||
if (max < 1) {
|
||||
SUPERVERBOSE("EOF");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (*p) {
|
||||
case 0xfd:
|
||||
if (max < 3) {
|
||||
SUPERVERBOSE("unexpected EOF");
|
||||
return 0;
|
||||
}
|
||||
*val = ((u64)p[1] << 8) + p[2];
|
||||
if (*val < 0xfd) {
|
||||
SUPERVERBOSE("decoded bigsize is not canonical");
|
||||
return 0;
|
||||
}
|
||||
return 3;
|
||||
case 0xfe:
|
||||
if (max < 5) {
|
||||
SUPERVERBOSE("unexpected EOF");
|
||||
return 0;
|
||||
}
|
||||
*val = ((u64)p[1] << 24) + ((u64)p[2] << 16)
|
||||
+ ((u64)p[3] << 8) + p[4];
|
||||
if ((*val >> 16) == 0) {
|
||||
SUPERVERBOSE("decoded bigsize is not canonical");
|
||||
return 0;
|
||||
}
|
||||
return 5;
|
||||
case 0xff:
|
||||
if (max < 9) {
|
||||
SUPERVERBOSE("unexpected EOF");
|
||||
return 0;
|
||||
}
|
||||
*val = ((u64)p[1] << 56) + ((u64)p[2] << 48)
|
||||
+ ((u64)p[3] << 40) + ((u64)p[4] << 32)
|
||||
+ ((u64)p[5] << 24) + ((u64)p[6] << 16)
|
||||
+ ((u64)p[7] << 8) + p[8];
|
||||
if ((*val >> 32) == 0) {
|
||||
SUPERVERBOSE("decoded bigsize is not canonical");
|
||||
return 0;
|
||||
}
|
||||
return 9;
|
||||
default:
|
||||
*val = *p;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int cursor_pull_bigsize(struct cursor *cur, bigsize_t *out)
|
||||
{
|
||||
return bigsize_get(cur->p, cur->end - cur->p, out);
|
||||
}
|
||||
|
||||
int cursor_push_bigsize(struct cursor *cur, const bigsize_t val)
|
||||
{
|
||||
u8 buf[BIGSIZE_MAX_LEN];
|
||||
size_t len;
|
||||
|
||||
len = bigsize_put(buf, val);
|
||||
|
||||
return cursor_push(cur, buf, len);
|
||||
}
|
||||
|
31
node_modules/lnsocket/bigsize.h
generated
vendored
Normal file
31
node_modules/lnsocket/bigsize.h
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef LNSOCKET_BIGSIZE_H
|
||||
#define LNSOCKET_BIGSIZE_H
|
||||
#include "config.h"
|
||||
#include "cursor.h"
|
||||
#include <stddef.h>
|
||||
|
||||
/* typedef for clarity. */
|
||||
typedef u64 bigsize_t;
|
||||
|
||||
#define BIGSIZE_MAX_LEN 9
|
||||
|
||||
/* Returns length of buf used. */
|
||||
size_t bigsize_put(unsigned char buf[BIGSIZE_MAX_LEN], bigsize_t v);
|
||||
|
||||
/* Returns 0 on failure, otherwise length (<= max) used. */
|
||||
size_t bigsize_get(const unsigned char *p, size_t max, bigsize_t *val);
|
||||
|
||||
/* How many bytes does it take to encode v? */
|
||||
size_t bigsize_len(bigsize_t v);
|
||||
|
||||
/* Used for wire generation */
|
||||
typedef bigsize_t bigsize;
|
||||
|
||||
/* marshal/unmarshal functions */
|
||||
void towire_bigsize(unsigned char **pptr, const bigsize_t val);
|
||||
bigsize_t fromwire_bigsize(const unsigned char **cursor, size_t *max);
|
||||
|
||||
int cursor_pull_bigsize(struct cursor *cur, bigsize_t *out);
|
||||
int cursor_push_bigsize(struct cursor *cur, const bigsize_t val);
|
||||
|
||||
#endif /* LNSOCKET_BIGSIZE_H */
|
36
node_modules/lnsocket/commando.c
generated
vendored
Normal file
36
node_modules/lnsocket/commando.c
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include "lnsocket.h"
|
||||
#include "cursor.h"
|
||||
#include "endian.h"
|
||||
#include "commando.h"
|
||||
#include "export.h"
|
||||
|
||||
int EXPORT commando_make_rpc_msg(const char *method, const char *params,
|
||||
const char *rune, unsigned int req_id, unsigned char *buf, int buflen)
|
||||
{
|
||||
struct cursor msgbuf;
|
||||
int ok;
|
||||
|
||||
make_cursor(buf, buf+buflen, &msgbuf);
|
||||
|
||||
params = (params == NULL || params[0] == '\0') ? "[]" : params;
|
||||
|
||||
if (!cursor_push_u16(&msgbuf, COMMANDO_CMD))
|
||||
return 0;
|
||||
|
||||
if (!cursor_push_u64(&msgbuf, (u64)req_id))
|
||||
return 0;
|
||||
|
||||
ok = cursor_push_str(&msgbuf, "{\"method\":\"") &&
|
||||
cursor_push_str(&msgbuf, method) &&
|
||||
cursor_push_str(&msgbuf, "\",\"params\":") &&
|
||||
cursor_push_str(&msgbuf, params) &&
|
||||
cursor_push_str(&msgbuf, ",\"rune\":\"") &&
|
||||
cursor_push_str(&msgbuf, rune) &&
|
||||
cursor_push_str(&msgbuf, "\"}");
|
||||
|
||||
if (!ok)
|
||||
return 0;
|
||||
|
||||
return msgbuf.p - msgbuf.start;
|
||||
}
|
14
node_modules/lnsocket/commando.h
generated
vendored
Normal file
14
node_modules/lnsocket/commando.h
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
#ifndef LNSOCKET_COMMANDO
|
||||
#define LNSOCKET_COMMANDO
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "export.h"
|
||||
|
||||
#define COMMANDO_CMD 0x4c4f
|
||||
#define COMMANDO_REPLY_CONTINUES 0x594b
|
||||
#define COMMANDO_REPLY_TERM 0x594d
|
||||
|
||||
int EXPORT commando_make_rpc_msg(const char *method, const char *params, const char *rune, unsigned int req_id, unsigned char *buf, int buflen);
|
||||
|
||||
#endif /* LNSOCKET_COMMANDO */
|
85
node_modules/lnsocket/compiler.h
generated
vendored
Normal file
85
node_modules/lnsocket/compiler.h
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
|
||||
#ifndef COMPILER_H
|
||||
#define COMPILER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_UNALIGNED_ACCESS
|
||||
#define alignment_ok(p, n) 1
|
||||
#else
|
||||
#define alignment_ok(p, n) ((size_t)(p) % (n) == 0)
|
||||
#endif
|
||||
|
||||
#define UNUSED __attribute__((__unused__))
|
||||
|
||||
/**
|
||||
* BUILD_ASSERT - assert a build-time dependency.
|
||||
* @cond: the compile-time condition which must be true.
|
||||
*
|
||||
* Your compile will fail if the condition isn't true, or can't be evaluated
|
||||
* by the compiler. This can only be used within a function.
|
||||
*
|
||||
* Example:
|
||||
* #include <stddef.h>
|
||||
* ...
|
||||
* static char *foo_to_char(struct foo *foo)
|
||||
* {
|
||||
* // This code needs string to be at start of foo.
|
||||
* BUILD_ASSERT(offsetof(struct foo, string) == 0);
|
||||
* return (char *)foo;
|
||||
* }
|
||||
*/
|
||||
#define BUILD_ASSERT(cond) \
|
||||
do { (void) sizeof(char [1 - 2*!(cond)]); } while(0)
|
||||
|
||||
/**
|
||||
* BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression.
|
||||
* @cond: the compile-time condition which must be true.
|
||||
*
|
||||
* Your compile will fail if the condition isn't true, or can't be evaluated
|
||||
* by the compiler. This can be used in an expression: its value is "0".
|
||||
*
|
||||
* Example:
|
||||
* #define foo_to_char(foo) \
|
||||
* ((char *)(foo) \
|
||||
* + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))
|
||||
*/
|
||||
#define BUILD_ASSERT_OR_ZERO(cond) \
|
||||
(sizeof(char [1 - 2*!(cond)]) - 1)
|
||||
|
||||
#define memclear(mem, size) memset(mem, 0, size)
|
||||
#define memclear_2(m1, s1, m2, s2) { memclear(m1, s1); memclear(m2, s2); }
|
||||
#define memclear_3(m1, s1, m2, s2, m3, s3) { memclear(m1, s1); memclear(m2, s2); memclear(m3, s3); }
|
||||
|
||||
static inline void *memcheck_(const void *data, size_t len)
|
||||
{
|
||||
(void)len;
|
||||
return (void *)data;
|
||||
}
|
||||
|
||||
#if HAVE_TYPEOF
|
||||
/**
|
||||
* memcheck - check that a memory region is initialized
|
||||
* @data: start of region
|
||||
* @len: length in bytes
|
||||
*
|
||||
* When running under valgrind, this causes an error to be printed
|
||||
* if the entire region is not defined. Otherwise valgrind only
|
||||
* reports an error when an undefined value is used for a branch, or
|
||||
* written out.
|
||||
*
|
||||
* Example:
|
||||
* // Search for space, but make sure it's all initialized.
|
||||
* if (memchr(memcheck(somebytes, bytes_len), ' ', bytes_len)) {
|
||||
* printf("space was found!\n");
|
||||
* }
|
||||
*/
|
||||
#define memcheck(data, len) ((__typeof__((data)+0))memcheck_((data), (len)))
|
||||
#else
|
||||
#define memcheck(data, len) memcheck_((data), (len))
|
||||
#endif
|
||||
|
||||
#endif /* COMPILER_H */
|
1110
node_modules/lnsocket/configurator.c
generated
vendored
Normal file
1110
node_modules/lnsocket/configurator.c
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
239
node_modules/lnsocket/crypto.c
generated
vendored
Normal file
239
node_modules/lnsocket/crypto.c
generated
vendored
Normal file
|
@ -0,0 +1,239 @@
|
|||
/* Copyright Rusty Russell (Blockstream) 2015.
|
||||
William Casarin 2022
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "crypto.h"
|
||||
#include "endian.h"
|
||||
#include "typedefs.h"
|
||||
#include "compiler.h"
|
||||
#include "hkdf.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <sodium/crypto_aead_chacha20poly1305.h>
|
||||
|
||||
void le64_nonce(unsigned char *npub, u64 nonce)
|
||||
{
|
||||
/* BOLT #8:
|
||||
*
|
||||
* ...with nonce `n` encoded as 32 zero bits, followed by a
|
||||
* *little-endian* 64-bit value. Note: this follows the Noise Protocol
|
||||
* convention, rather than our normal endian
|
||||
*/
|
||||
le64 le_nonce = cpu_to_le64(nonce);
|
||||
const size_t zerolen = crypto_aead_chacha20poly1305_ietf_NPUBBYTES - sizeof(le_nonce);
|
||||
|
||||
BUILD_ASSERT(crypto_aead_chacha20poly1305_ietf_NPUBBYTES >= sizeof(le_nonce));
|
||||
/* First part is 0, followed by nonce. */
|
||||
memset(npub, 0, zerolen);
|
||||
memcpy(npub + zerolen, &le_nonce, sizeof(le_nonce));
|
||||
}
|
||||
|
||||
/* out1, out2 = HKDF(in1, in2)` */
|
||||
void hkdf_two_keys(struct secret *out1, struct secret *out2,
|
||||
const struct secret *in1,
|
||||
const struct secret *in2)
|
||||
{
|
||||
/* BOLT #8:
|
||||
*
|
||||
* * `HKDF(salt,ikm)`: a function defined in `RFC 5869`<sup>[3](#reference-3)</sup>,
|
||||
* evaluated with a zero-length `info` field
|
||||
* * All invocations of `HKDF` implicitly return 64 bytes
|
||||
* of cryptographic randomness using the extract-and-expand
|
||||
* component of the `HKDF`.
|
||||
*/
|
||||
struct secret okm[2];
|
||||
size_t in2_size = in2 == NULL ? 0 : sizeof(*in2);
|
||||
|
||||
hkdf_sha256(okm, sizeof(okm), in1, sizeof(*in1), in2, in2_size,
|
||||
NULL, 0);
|
||||
*out1 = okm[0];
|
||||
*out2 = okm[1];
|
||||
}
|
||||
|
||||
|
||||
static void maybe_rotate_key(u64 *n, struct secret *k, struct secret *ck)
|
||||
{
|
||||
struct secret new_k, new_ck;
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* A key is to be rotated after a party encrypts or decrypts 1000 times
|
||||
* with it (i.e. every 500 messages). This can be properly accounted
|
||||
* for by rotating the key once the nonce dedicated to it
|
||||
* exceeds 1000.
|
||||
*/
|
||||
if (*n != 1000)
|
||||
return;
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* Key rotation for a key `k` is performed according to the following
|
||||
* steps:
|
||||
*
|
||||
* 1. Let `ck` be the chaining key obtained at the end of Act Three.
|
||||
* 2. `ck', k' = HKDF(ck, k)`
|
||||
* 3. Reset the nonce for the key to `n = 0`.
|
||||
* 4. `k = k'`
|
||||
* 5. `ck = ck'`
|
||||
*/
|
||||
hkdf_two_keys(&new_ck, &new_k, ck, k);
|
||||
|
||||
*ck = new_ck;
|
||||
*k = new_k;
|
||||
*n = 0;
|
||||
}
|
||||
|
||||
int cryptomsg_decrypt_body(struct crypto_state *cs, const u8 *in, size_t inlen, u8 *out, size_t outcap)
|
||||
{
|
||||
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||
unsigned long long mlen;
|
||||
|
||||
if (inlen < 16 || outcap < cryptomsg_decrypt_size(inlen))
|
||||
return 0;
|
||||
|
||||
le64_nonce(npub, cs->rn++);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 5. Decrypt `c` (using `ChaCha20-Poly1305`, `rn`, and `rk`), to
|
||||
* obtain decrypted plaintext packet `p`.
|
||||
* * The nonce `rn` MUST be incremented after this step.
|
||||
*/
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(out,
|
||||
&mlen, NULL,
|
||||
memcheck(in, inlen),
|
||||
inlen,
|
||||
NULL, 0,
|
||||
npub, cs->rk.data) != 0) {
|
||||
/* FIXME: Report error! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(mlen == cryptomsg_decrypt_size(inlen));
|
||||
|
||||
maybe_rotate_key(&cs->rn, &cs->rk, &cs->r_ck);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cryptomsg_decrypt_header(struct crypto_state *cs, u8 hdr[18], u16 *lenp)
|
||||
{
|
||||
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||
unsigned long long mlen;
|
||||
be16 len;
|
||||
|
||||
le64_nonce(npub, cs->rn++);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 2. Let the encrypted length prefix be known as `lc`.
|
||||
* 3. Decrypt `lc` (using `ChaCha20-Poly1305`, `rn`, and `rk`), to
|
||||
* obtain the size of the encrypted packet `l`.
|
||||
* * A zero-length byte slice is to be passed as the AD
|
||||
* (associated data).
|
||||
* * The nonce `rn` MUST be incremented after this step.
|
||||
*/
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt((unsigned char *)&len,
|
||||
&mlen, NULL,
|
||||
memcheck(hdr, 18), 18,
|
||||
NULL, 0,
|
||||
npub, cs->rk.data) != 0) {
|
||||
return 0;
|
||||
}
|
||||
assert(mlen == sizeof(len));
|
||||
*lenp = be16_to_cpu(len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
u8 *cryptomsg_encrypt_msg(struct crypto_state *cs, const u8 *msg, unsigned long long mlen, u8 *out, size_t *outlen, size_t outcap)
|
||||
{
|
||||
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||
unsigned long long clen;
|
||||
be16 l;
|
||||
int ret;
|
||||
|
||||
*outlen = sizeof(l) + 16 + mlen + 16;
|
||||
|
||||
if (outcap < mlen) {
|
||||
*outlen = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* In order to encrypt and send a Lightning message (`m`) to the
|
||||
* network stream, given a sending key (`sk`) and a nonce (`sn`), the
|
||||
* following steps are completed:
|
||||
*
|
||||
* 1. Let `l = len(m)`.
|
||||
* * where `len` obtains the length in bytes of the Lightning
|
||||
* message
|
||||
*
|
||||
* 2. Serialize `l` into 2 bytes encoded as a big-endian integer.
|
||||
*/
|
||||
l = cpu_to_be16(mlen);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 3. Encrypt `l` (using `ChaChaPoly-1305`, `sn`, and `sk`), to obtain
|
||||
* `lc` (18 bytes)
|
||||
* * The nonce `sn` is encoded as a 96-bit little-endian number. As
|
||||
* the decoded nonce is 64 bits, the 96-bit nonce is encoded as:
|
||||
* 32 bits of leading 0s followed by a 64-bit value.
|
||||
* * The nonce `sn` MUST be incremented after this step.
|
||||
* * A zero-length byte slice is to be passed as the AD (associated
|
||||
data).
|
||||
*/
|
||||
le64_nonce(npub, cs->sn++);
|
||||
ret = crypto_aead_chacha20poly1305_ietf_encrypt(out, &clen,
|
||||
(unsigned char *)
|
||||
memcheck(&l, sizeof(l)),
|
||||
sizeof(l),
|
||||
NULL, 0,
|
||||
NULL, npub,
|
||||
cs->sk.data);
|
||||
assert(ret == 0);
|
||||
assert(clen == sizeof(l) + 16);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 4. Finally, encrypt the message itself (`m`) using the same
|
||||
* procedure used to encrypt the length prefix. Let
|
||||
* encrypted ciphertext be known as `c`.
|
||||
*
|
||||
* * The nonce `sn` MUST be incremented after this step.
|
||||
*/
|
||||
le64_nonce(npub, cs->sn++);
|
||||
ret = crypto_aead_chacha20poly1305_ietf_encrypt(out + clen, &clen,
|
||||
memcheck(msg, mlen),
|
||||
mlen,
|
||||
NULL, 0,
|
||||
NULL, npub,
|
||||
cs->sk.data);
|
||||
assert(ret == 0);
|
||||
assert(clen == mlen + 16);
|
||||
|
||||
maybe_rotate_key(&cs->sn, &cs->sk, &cs->s_ck);
|
||||
|
||||
return out;
|
||||
}
|
55
node_modules/lnsocket/crypto.h
generated
vendored
Normal file
55
node_modules/lnsocket/crypto.h
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
#ifndef LNSOCKET_CRYPTO_H
|
||||
#define LNSOCKET_CRYPTO_H
|
||||
|
||||
#include <secp256k1.h>
|
||||
#include "typedefs.h"
|
||||
|
||||
#define PUBKEY_CMPR_LEN 33
|
||||
|
||||
struct secret {
|
||||
u8 data[32];
|
||||
};
|
||||
|
||||
struct node_id {
|
||||
u8 k[PUBKEY_CMPR_LEN];
|
||||
};
|
||||
|
||||
struct pubkey {
|
||||
secp256k1_pubkey pubkey;
|
||||
};
|
||||
|
||||
struct privkey {
|
||||
struct secret secret;
|
||||
};
|
||||
|
||||
struct keypair {
|
||||
struct pubkey pub;
|
||||
struct privkey priv;
|
||||
};
|
||||
|
||||
struct crypto_state {
|
||||
/* Received and sent nonces. */
|
||||
u64 rn, sn;
|
||||
/* Sending and receiving keys. */
|
||||
struct secret sk, rk;
|
||||
/* Chaining key for re-keying */
|
||||
struct secret s_ck, r_ck;
|
||||
};
|
||||
|
||||
void le64_nonce(unsigned char *npub, u64 nonce);
|
||||
|
||||
void hkdf_two_keys(struct secret *out1, struct secret *out2,
|
||||
const struct secret *in1,
|
||||
const struct secret *in2);
|
||||
|
||||
int cryptomsg_decrypt_body(struct crypto_state *cs, const u8 *in, size_t inlen, u8 *out, size_t outcap);
|
||||
int cryptomsg_decrypt_header(struct crypto_state *cs, u8 hdr[18], u16 *lenp);
|
||||
unsigned char *cryptomsg_encrypt_msg(struct crypto_state *cs, const u8 *msg, unsigned long long mlen, u8 *out, size_t *outlen, size_t outcap);
|
||||
|
||||
static inline int cryptomsg_decrypt_size(size_t inlen)
|
||||
{
|
||||
return inlen - 16;
|
||||
}
|
||||
|
||||
#endif /* LNSOCKET_CRYPTO_H */
|
393
node_modules/lnsocket/cursor.h
generated
vendored
Normal file
393
node_modules/lnsocket/cursor.h
generated
vendored
Normal file
|
@ -0,0 +1,393 @@
|
|||
|
||||
|
||||
#ifndef LNSOCKET_CURSOR_H
|
||||
#define LNSOCKET_CURSOR_H
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "varint.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#define unlikely(x) __builtin_expect((x),0)
|
||||
#define likely(x) __builtin_expect((x),1)
|
||||
|
||||
struct cursor {
|
||||
unsigned char *start;
|
||||
unsigned char *p;
|
||||
unsigned char *end;
|
||||
};
|
||||
|
||||
struct array {
|
||||
struct cursor cur;
|
||||
unsigned int elem_size;
|
||||
};
|
||||
|
||||
static inline void reset_cursor(struct cursor *cursor)
|
||||
{
|
||||
cursor->p = cursor->start;
|
||||
}
|
||||
|
||||
static inline void wipe_cursor(struct cursor *cursor)
|
||||
{
|
||||
reset_cursor(cursor);
|
||||
memset(cursor->start, 0, cursor->end - cursor->start);
|
||||
}
|
||||
|
||||
static inline void make_cursor(u8 *start, u8 *end, struct cursor *cursor)
|
||||
{
|
||||
cursor->start = start;
|
||||
cursor->p = start;
|
||||
cursor->end = end;
|
||||
}
|
||||
|
||||
static inline void make_array(struct array *a, u8* start, u8 *end, unsigned int elem_size)
|
||||
{
|
||||
make_cursor(start, end, &a->cur);
|
||||
a->elem_size = elem_size;
|
||||
}
|
||||
|
||||
static inline int cursor_eof(struct cursor *c)
|
||||
{
|
||||
return c->p == c->end;
|
||||
}
|
||||
|
||||
static inline void *cursor_malloc(struct cursor *mem, unsigned long size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (mem->p + size > mem->end) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = mem->p;
|
||||
mem->p += size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void *cursor_alloc(struct cursor *mem, unsigned long size)
|
||||
{
|
||||
void *ret;
|
||||
if (!(ret = cursor_malloc(mem, size))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int cursor_slice(struct cursor *mem, struct cursor *slice, size_t size)
|
||||
{
|
||||
u8 *p;
|
||||
if (!(p = cursor_alloc(mem, size))) {
|
||||
return 0;
|
||||
}
|
||||
make_cursor(p, mem->p, slice);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static inline void copy_cursor(struct cursor *src, struct cursor *dest)
|
||||
{
|
||||
dest->start = src->start;
|
||||
dest->p = src->p;
|
||||
dest->end = src->end;
|
||||
}
|
||||
|
||||
static inline int pull_byte(struct cursor *cursor, u8 *c)
|
||||
{
|
||||
if (unlikely(cursor->p + 1 > cursor->end))
|
||||
return 0;
|
||||
|
||||
*c = *cursor->p;
|
||||
cursor->p++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_pull_c_str(struct cursor *cursor, const char **str)
|
||||
{
|
||||
*str = (const char*)cursor->p;
|
||||
|
||||
for (; cursor->p < cursor->end; cursor->p++) {
|
||||
if (*cursor->p == 0) {
|
||||
cursor->p++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int cursor_push_byte(struct cursor *cursor, u8 c)
|
||||
{
|
||||
if (unlikely(cursor->p + 1 > cursor->end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*cursor->p = c;
|
||||
cursor->p++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_pull(struct cursor *cursor, u8 *data, int len)
|
||||
{
|
||||
if (unlikely(cursor->p + len > cursor->end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(data, cursor->p, len);
|
||||
cursor->p += len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int pull_data_into_cursor(struct cursor *cursor,
|
||||
struct cursor *dest,
|
||||
unsigned char **data,
|
||||
int len)
|
||||
{
|
||||
int ok;
|
||||
|
||||
if (unlikely(dest->p + len > dest->end)) {
|
||||
printf("not enough room in dest buffer\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ok = cursor_pull(cursor, dest->p, len);
|
||||
if (!ok) return 0;
|
||||
|
||||
*data = dest->p;
|
||||
dest->p += len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_dropn(struct cursor *cur, int size, int n)
|
||||
{
|
||||
if (n == 0)
|
||||
return 1;
|
||||
|
||||
if (unlikely(cur->p - size*n < cur->start)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cur->p -= size*n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_drop(struct cursor *cur, int size)
|
||||
{
|
||||
return cursor_dropn(cur, size, 1);
|
||||
}
|
||||
|
||||
static inline unsigned char *cursor_topn(struct cursor *cur, int len, int n)
|
||||
{
|
||||
n += 1;
|
||||
if (unlikely(cur->p - len*n < cur->start)) {
|
||||
return NULL;
|
||||
}
|
||||
return cur->p - len*n;
|
||||
}
|
||||
|
||||
static inline unsigned char *cursor_top(struct cursor *cur, int len)
|
||||
{
|
||||
if (unlikely(cur->p - len < cur->start)) {
|
||||
return NULL;
|
||||
}
|
||||
return cur->p - len;
|
||||
}
|
||||
|
||||
static inline int cursor_top_int(struct cursor *cur, int *i)
|
||||
{
|
||||
u8 *p;
|
||||
if (unlikely(!(p = cursor_top(cur, sizeof(*i))))) {
|
||||
return 0;
|
||||
}
|
||||
*i = *((int*)p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_pop(struct cursor *cur, u8 *data, int len)
|
||||
{
|
||||
if (unlikely(cur->p - len < cur->start)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cur->p -= len;
|
||||
memcpy(data, cur->p, len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_push(struct cursor *cursor, const void *data, int len)
|
||||
{
|
||||
if (unlikely(cursor->p + len >= cursor->end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cursor->p != data)
|
||||
memcpy(cursor->p, data, len);
|
||||
|
||||
cursor->p += len;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_push_int(struct cursor *cursor, int i)
|
||||
{
|
||||
return cursor_push(cursor, (u8*)&i, sizeof(i));
|
||||
}
|
||||
|
||||
static inline size_t cursor_count(struct cursor *cursor, size_t elem_size)
|
||||
{
|
||||
return (cursor->p - cursor->start)/elem_size;
|
||||
}
|
||||
|
||||
/* TODO: push_varint */
|
||||
static inline int push_varint(struct cursor *cursor, int n)
|
||||
{
|
||||
int ok, len;
|
||||
unsigned char b;
|
||||
len = 0;
|
||||
|
||||
while (1) {
|
||||
b = (n & 0xFF) | 0x80;
|
||||
n >>= 7;
|
||||
if (n == 0) {
|
||||
b &= 0x7F;
|
||||
ok = cursor_push_byte(cursor, b);
|
||||
len++;
|
||||
if (!ok) return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ok = cursor_push_byte(cursor, b);
|
||||
len++;
|
||||
if (!ok) return 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* TODO: pull_varint */
|
||||
static inline int pull_varint(struct cursor *cursor, int *n)
|
||||
{
|
||||
int ok, i;
|
||||
unsigned char b;
|
||||
*n = 0;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
ok = pull_byte(cursor, &b);
|
||||
if (!ok) return 0;
|
||||
|
||||
*n |= ((int)b & 0x7F) << (i * 7);
|
||||
|
||||
/* is_last */
|
||||
if ((b & 0x80) == 0) {
|
||||
return i+1;
|
||||
}
|
||||
|
||||
if (i == 4) return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cursor_pull_int(struct cursor *cursor, int *i)
|
||||
{
|
||||
return cursor_pull(cursor, (u8*)i, sizeof(*i));
|
||||
}
|
||||
|
||||
static inline void *index_cursor(struct cursor *cursor, unsigned int index, int elem_size)
|
||||
{
|
||||
u8 *p;
|
||||
p = &cursor->start[elem_size * index];
|
||||
|
||||
if (unlikely(p >= cursor->end))
|
||||
return NULL;
|
||||
|
||||
return (void*)p;
|
||||
}
|
||||
|
||||
|
||||
static inline int push_sized_str(struct cursor *cursor, const char *str, int len)
|
||||
{
|
||||
return cursor_push(cursor, (u8*)str, len);
|
||||
}
|
||||
|
||||
static inline int cursor_push_str(struct cursor *cursor, const char *str)
|
||||
{
|
||||
return cursor_push(cursor, (u8*)str, strlen(str));
|
||||
}
|
||||
|
||||
static inline int cursor_push_c_str(struct cursor *cursor, const char *str)
|
||||
{
|
||||
return cursor_push_str(cursor, str) && cursor_push_byte(cursor, 0);
|
||||
}
|
||||
|
||||
/* TODO: push varint size */
|
||||
static inline int push_prefixed_str(struct cursor *cursor, const char *str)
|
||||
{
|
||||
int ok, len;
|
||||
len = strlen(str);
|
||||
ok = push_varint(cursor, len);
|
||||
if (!ok) return 0;
|
||||
return push_sized_str(cursor, str, len);
|
||||
}
|
||||
|
||||
static inline int pull_prefixed_str(struct cursor *cursor, struct cursor *dest_buf, const char **str)
|
||||
{
|
||||
int len, ok;
|
||||
|
||||
ok = pull_varint(cursor, &len);
|
||||
if (!ok) return 0;
|
||||
|
||||
if (unlikely(dest_buf->p + len > dest_buf->end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ok = pull_data_into_cursor(cursor, dest_buf, (unsigned char**)str, len);
|
||||
if (!ok) return 0;
|
||||
|
||||
ok = cursor_push_byte(dest_buf, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_remaining_capacity(struct cursor *cursor)
|
||||
{
|
||||
return cursor->end - cursor->p;
|
||||
}
|
||||
|
||||
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
static inline void cursor_print_around(struct cursor *cur, int range)
|
||||
{
|
||||
unsigned char *c;
|
||||
|
||||
printf("[%ld/%ld]\n", cur->p - cur->start, cur->end - cur->start);
|
||||
|
||||
c = max(cur->p - range, cur->start);
|
||||
for (; c < cur->end && c < (cur->p + range); c++) {
|
||||
printf("%02x", *c);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
c = max(cur->p - range, cur->start);
|
||||
for (; c < cur->end && c < (cur->p + range); c++) {
|
||||
if (c == cur->p) {
|
||||
printf("^");
|
||||
continue;
|
||||
}
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#undef max
|
||||
|
||||
#endif
|
391
node_modules/lnsocket/dist/node/lnsocket.js
generated
vendored
Normal file
391
node_modules/lnsocket/dist/node/lnsocket.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
node_modules/lnsocket/dist/node/lnsocket.wasm
generated
vendored
Executable file
BIN
node_modules/lnsocket/dist/node/lnsocket.wasm
generated
vendored
Executable file
Binary file not shown.
385
node_modules/lnsocket/endian.h
generated
vendored
Normal file
385
node_modules/lnsocket/endian.h
generated
vendored
Normal file
|
@ -0,0 +1,385 @@
|
|||
/* CC0 (Public domain) */
|
||||
#ifndef CCAN_ENDIAN_H
|
||||
#define CCAN_ENDIAN_H
|
||||
#include <stdint.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "cursor.h"
|
||||
|
||||
/**
|
||||
* BSWAP_16 - reverse bytes in a constant uint16_t value.
|
||||
* @val: constant value whose bytes to swap.
|
||||
*
|
||||
* Designed to be usable in constant-requiring initializers.
|
||||
*
|
||||
* Example:
|
||||
* struct mystruct {
|
||||
* char buf[BSWAP_16(0x1234)];
|
||||
* };
|
||||
*/
|
||||
#define BSWAP_16(val) \
|
||||
((((uint16_t)(val) & 0x00ff) << 8) \
|
||||
| (((uint16_t)(val) & 0xff00) >> 8))
|
||||
|
||||
/**
|
||||
* BSWAP_32 - reverse bytes in a constant uint32_t value.
|
||||
* @val: constant value whose bytes to swap.
|
||||
*
|
||||
* Designed to be usable in constant-requiring initializers.
|
||||
*
|
||||
* Example:
|
||||
* struct mystruct {
|
||||
* char buf[BSWAP_32(0xff000000)];
|
||||
* };
|
||||
*/
|
||||
#define BSWAP_32(val) \
|
||||
((((uint32_t)(val) & 0x000000ff) << 24) \
|
||||
| (((uint32_t)(val) & 0x0000ff00) << 8) \
|
||||
| (((uint32_t)(val) & 0x00ff0000) >> 8) \
|
||||
| (((uint32_t)(val) & 0xff000000) >> 24))
|
||||
|
||||
/**
|
||||
* BSWAP_64 - reverse bytes in a constant uint64_t value.
|
||||
* @val: constantvalue whose bytes to swap.
|
||||
*
|
||||
* Designed to be usable in constant-requiring initializers.
|
||||
*
|
||||
* Example:
|
||||
* struct mystruct {
|
||||
* char buf[BSWAP_64(0xff00000000000000ULL)];
|
||||
* };
|
||||
*/
|
||||
#define BSWAP_64(val) \
|
||||
((((uint64_t)(val) & 0x00000000000000ffULL) << 56) \
|
||||
| (((uint64_t)(val) & 0x000000000000ff00ULL) << 40) \
|
||||
| (((uint64_t)(val) & 0x0000000000ff0000ULL) << 24) \
|
||||
| (((uint64_t)(val) & 0x00000000ff000000ULL) << 8) \
|
||||
| (((uint64_t)(val) & 0x000000ff00000000ULL) >> 8) \
|
||||
| (((uint64_t)(val) & 0x0000ff0000000000ULL) >> 24) \
|
||||
| (((uint64_t)(val) & 0x00ff000000000000ULL) >> 40) \
|
||||
| (((uint64_t)(val) & 0xff00000000000000ULL) >> 56))
|
||||
|
||||
#if HAVE_BYTESWAP_H
|
||||
#include <byteswap.h>
|
||||
#else
|
||||
/**
|
||||
* bswap_16 - reverse bytes in a uint16_t value.
|
||||
* @val: value whose bytes to swap.
|
||||
*
|
||||
* Example:
|
||||
* // Output contains "1024 is 4 as two bytes reversed"
|
||||
* printf("1024 is %u as two bytes reversed\n", bswap_16(1024));
|
||||
*/
|
||||
static inline uint16_t bswap_16(uint16_t val)
|
||||
{
|
||||
return BSWAP_16(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* bswap_32 - reverse bytes in a uint32_t value.
|
||||
* @val: value whose bytes to swap.
|
||||
*
|
||||
* Example:
|
||||
* // Output contains "1024 is 262144 as four bytes reversed"
|
||||
* printf("1024 is %u as four bytes reversed\n", bswap_32(1024));
|
||||
*/
|
||||
static inline uint32_t bswap_32(uint32_t val)
|
||||
{
|
||||
return BSWAP_32(val);
|
||||
}
|
||||
#endif /* !HAVE_BYTESWAP_H */
|
||||
|
||||
#if !HAVE_BSWAP_64
|
||||
/**
|
||||
* bswap_64 - reverse bytes in a uint64_t value.
|
||||
* @val: value whose bytes to swap.
|
||||
*
|
||||
* Example:
|
||||
* // Output contains "1024 is 1125899906842624 as eight bytes reversed"
|
||||
* printf("1024 is %llu as eight bytes reversed\n",
|
||||
* (unsigned long long)bswap_64(1024));
|
||||
*/
|
||||
static inline uint64_t bswap_64(uint64_t val)
|
||||
{
|
||||
return BSWAP_64(val);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Needed for Glibc like endiness check */
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#define __BIG_ENDIAN 4321
|
||||
|
||||
/* Sanity check the defines. We don't handle weird endianness. */
|
||||
#if !HAVE_LITTLE_ENDIAN && !HAVE_BIG_ENDIAN
|
||||
#error "Unknown endian"
|
||||
#elif HAVE_LITTLE_ENDIAN && HAVE_BIG_ENDIAN
|
||||
#error "Can't compile for both big and little endian."
|
||||
#elif HAVE_LITTLE_ENDIAN
|
||||
#ifndef __BYTE_ORDER
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#elif __BYTE_ORDER != __LITTLE_ENDIAN
|
||||
#error "__BYTE_ORDER already defined, but not equal to __LITTLE_ENDIAN"
|
||||
#endif
|
||||
#elif HAVE_BIG_ENDIAN
|
||||
#ifndef __BYTE_ORDER
|
||||
#define __BYTE_ORDER __BIG_ENDIAN
|
||||
#elif __BYTE_ORDER != __BIG_ENDIAN
|
||||
#error "__BYTE_ORDER already defined, but not equal to __BIG_ENDIAN"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __CHECKER__
|
||||
/* sparse needs forcing to remove bitwise attribute from ccan/short_types */
|
||||
#define ENDIAN_CAST __attribute__((force))
|
||||
#define ENDIAN_TYPE __attribute__((bitwise))
|
||||
#else
|
||||
#define ENDIAN_CAST
|
||||
#define ENDIAN_TYPE
|
||||
#endif
|
||||
|
||||
typedef uint64_t ENDIAN_TYPE leint64_t;
|
||||
typedef uint64_t ENDIAN_TYPE beint64_t;
|
||||
typedef uint32_t ENDIAN_TYPE leint32_t;
|
||||
typedef uint32_t ENDIAN_TYPE beint32_t;
|
||||
typedef uint16_t ENDIAN_TYPE leint16_t;
|
||||
typedef uint16_t ENDIAN_TYPE beint16_t;
|
||||
|
||||
#if HAVE_LITTLE_ENDIAN
|
||||
/**
|
||||
* CPU_TO_LE64 - convert a constant uint64_t value to little-endian
|
||||
* @native: constant to convert
|
||||
*/
|
||||
#define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)(native))
|
||||
|
||||
/**
|
||||
* CPU_TO_LE32 - convert a constant uint32_t value to little-endian
|
||||
* @native: constant to convert
|
||||
*/
|
||||
#define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)(native))
|
||||
|
||||
/**
|
||||
* CPU_TO_LE16 - convert a constant uint16_t value to little-endian
|
||||
* @native: constant to convert
|
||||
*/
|
||||
#define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)(native))
|
||||
|
||||
/**
|
||||
* LE64_TO_CPU - convert a little-endian uint64_t constant
|
||||
* @le_val: little-endian constant to convert
|
||||
*/
|
||||
#define LE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val))
|
||||
|
||||
/**
|
||||
* LE32_TO_CPU - convert a little-endian uint32_t constant
|
||||
* @le_val: little-endian constant to convert
|
||||
*/
|
||||
#define LE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val))
|
||||
|
||||
/**
|
||||
* LE16_TO_CPU - convert a little-endian uint16_t constant
|
||||
* @le_val: little-endian constant to convert
|
||||
*/
|
||||
#define LE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val))
|
||||
|
||||
#else /* ... HAVE_BIG_ENDIAN */
|
||||
#define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)BSWAP_64(native))
|
||||
#define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)BSWAP_32(native))
|
||||
#define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)BSWAP_16(native))
|
||||
#define LE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val)
|
||||
#define LE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val)
|
||||
#define LE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val)
|
||||
#endif /* HAVE_BIG_ENDIAN */
|
||||
|
||||
#if HAVE_BIG_ENDIAN
|
||||
/**
|
||||
* CPU_TO_BE64 - convert a constant uint64_t value to big-endian
|
||||
* @native: constant to convert
|
||||
*/
|
||||
#define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)(native))
|
||||
|
||||
/**
|
||||
* CPU_TO_BE32 - convert a constant uint32_t value to big-endian
|
||||
* @native: constant to convert
|
||||
*/
|
||||
#define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)(native))
|
||||
|
||||
/**
|
||||
* CPU_TO_BE16 - convert a constant uint16_t value to big-endian
|
||||
* @native: constant to convert
|
||||
*/
|
||||
#define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)(native))
|
||||
|
||||
/**
|
||||
* BE64_TO_CPU - convert a big-endian uint64_t constant
|
||||
* @le_val: big-endian constant to convert
|
||||
*/
|
||||
#define BE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val))
|
||||
|
||||
/**
|
||||
* BE32_TO_CPU - convert a big-endian uint32_t constant
|
||||
* @le_val: big-endian constant to convert
|
||||
*/
|
||||
#define BE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val))
|
||||
|
||||
/**
|
||||
* BE16_TO_CPU - convert a big-endian uint16_t constant
|
||||
* @le_val: big-endian constant to convert
|
||||
*/
|
||||
#define BE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val))
|
||||
|
||||
#else /* ... HAVE_LITTLE_ENDIAN */
|
||||
#define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)BSWAP_64(native))
|
||||
#define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)BSWAP_32(native))
|
||||
#define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)BSWAP_16(native))
|
||||
#define BE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val)
|
||||
#define BE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val)
|
||||
#define BE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val)
|
||||
#endif /* HAVE_LITTE_ENDIAN */
|
||||
|
||||
|
||||
/**
|
||||
* cpu_to_le64 - convert a uint64_t value to little-endian
|
||||
* @native: value to convert
|
||||
*/
|
||||
static inline leint64_t cpu_to_le64(uint64_t native)
|
||||
{
|
||||
return CPU_TO_LE64(native);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_to_le32 - convert a uint32_t value to little-endian
|
||||
* @native: value to convert
|
||||
*/
|
||||
static inline leint32_t cpu_to_le32(uint32_t native)
|
||||
{
|
||||
return CPU_TO_LE32(native);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_to_le16 - convert a uint16_t value to little-endian
|
||||
* @native: value to convert
|
||||
*/
|
||||
static inline leint16_t cpu_to_le16(uint16_t native)
|
||||
{
|
||||
return CPU_TO_LE16(native);
|
||||
}
|
||||
|
||||
/**
|
||||
* le64_to_cpu - convert a little-endian uint64_t value
|
||||
* @le_val: little-endian value to convert
|
||||
*/
|
||||
static inline uint64_t le64_to_cpu(leint64_t le_val)
|
||||
{
|
||||
return LE64_TO_CPU(le_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* le32_to_cpu - convert a little-endian uint32_t value
|
||||
* @le_val: little-endian value to convert
|
||||
*/
|
||||
static inline uint32_t le32_to_cpu(leint32_t le_val)
|
||||
{
|
||||
return LE32_TO_CPU(le_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* le16_to_cpu - convert a little-endian uint16_t value
|
||||
* @le_val: little-endian value to convert
|
||||
*/
|
||||
static inline uint16_t le16_to_cpu(leint16_t le_val)
|
||||
{
|
||||
return LE16_TO_CPU(le_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_to_be64 - convert a uint64_t value to big endian.
|
||||
* @native: value to convert
|
||||
*/
|
||||
static inline beint64_t cpu_to_be64(uint64_t native)
|
||||
{
|
||||
return CPU_TO_BE64(native);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_to_be32 - convert a uint32_t value to big endian.
|
||||
* @native: value to convert
|
||||
*/
|
||||
static inline beint32_t cpu_to_be32(uint32_t native)
|
||||
{
|
||||
return CPU_TO_BE32(native);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_to_be16 - convert a uint16_t value to big endian.
|
||||
* @native: value to convert
|
||||
*/
|
||||
static inline beint16_t cpu_to_be16(uint16_t native)
|
||||
{
|
||||
return CPU_TO_BE16(native);
|
||||
}
|
||||
|
||||
/**
|
||||
* be64_to_cpu - convert a big-endian uint64_t value
|
||||
* @be_val: big-endian value to convert
|
||||
*/
|
||||
static inline uint64_t be64_to_cpu(beint64_t be_val)
|
||||
{
|
||||
return BE64_TO_CPU(be_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* be32_to_cpu - convert a big-endian uint32_t value
|
||||
* @be_val: big-endian value to convert
|
||||
*/
|
||||
static inline uint32_t be32_to_cpu(beint32_t be_val)
|
||||
{
|
||||
return BE32_TO_CPU(be_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* be16_to_cpu - convert a big-endian uint16_t value
|
||||
* @be_val: big-endian value to convert
|
||||
*/
|
||||
static inline uint16_t be16_to_cpu(beint16_t be_val)
|
||||
{
|
||||
return BE16_TO_CPU(be_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* be64/be32/be16 - 64/32/16 bit big-endian representation.
|
||||
*/
|
||||
typedef beint64_t be64;
|
||||
typedef beint32_t be32;
|
||||
typedef beint16_t be16;
|
||||
|
||||
/**
|
||||
* le64/le32/le16 - 64/32/16 bit little-endian representation.
|
||||
*/
|
||||
typedef leint64_t le64;
|
||||
typedef leint32_t le32;
|
||||
typedef leint16_t le16;
|
||||
|
||||
static inline int cursor_push_u16(struct cursor *cursor, u16 i)
|
||||
{
|
||||
be16 v = cpu_to_be16(i);
|
||||
return cursor_push(cursor, &v, sizeof(v));
|
||||
}
|
||||
|
||||
static inline int cursor_pull_u16(struct cursor *cursor, u16 *i)
|
||||
{
|
||||
be16 ret;
|
||||
if (!cursor_pull(cursor, (u8*)&ret, sizeof(ret)))
|
||||
return 0;
|
||||
*i = be16_to_cpu(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int cursor_push_u64(struct cursor *cur, u64 v)
|
||||
{
|
||||
be64 l = cpu_to_be64(v);
|
||||
return cursor_push(cur, (u8*)&l, sizeof(l));
|
||||
}
|
||||
|
||||
|
||||
#endif /* CCAN_ENDIAN_H */
|
49
node_modules/lnsocket/error.c
generated
vendored
Normal file
49
node_modules/lnsocket/error.c
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
|
||||
#include "error.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
int note_error_(struct errors *errs_, const char *fmt, ...)
|
||||
{
|
||||
static char buf[512];
|
||||
struct error err;
|
||||
struct cursor *errs;
|
||||
va_list ap;
|
||||
|
||||
errs = &errs_->cur;
|
||||
|
||||
if (errs_->enabled == 0)
|
||||
return 0;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
err.msg = buf;
|
||||
|
||||
if (!cursor_push_error(errs, &err)) {
|
||||
fprintf(stderr, "arena OOM when recording error, ");
|
||||
fprintf(stderr, "errs->p at %ld, remaining %ld, strlen %ld\n",
|
||||
errs->p - errs->start, errs->end - errs->p, strlen(buf));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_error_backtrace(struct errors *errors)
|
||||
{
|
||||
struct cursor errs;
|
||||
struct error err;
|
||||
|
||||
copy_cursor(&errors->cur, &errs);
|
||||
errs.p = errs.start;
|
||||
|
||||
while (errs.p < errors->cur.p) {
|
||||
if (!cursor_pull_error(&errs, &err)) {
|
||||
fprintf(stderr, "backtrace: couldn't pull error\n");
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "%s\n", err.msg);
|
||||
}
|
||||
}
|
32
node_modules/lnsocket/error.h
generated
vendored
Normal file
32
node_modules/lnsocket/error.h
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
#ifndef LNSOCKET_ERROR_H
|
||||
#define LNSOCKET_ERROR_H
|
||||
|
||||
#include "cursor.h"
|
||||
|
||||
struct error {
|
||||
const char *msg;
|
||||
};
|
||||
|
||||
struct errors {
|
||||
struct cursor cur;
|
||||
int enabled;
|
||||
};
|
||||
|
||||
#define note_error(errs, fmt, ...) note_error_(errs, "%s:%s:%d: " fmt, __FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
static inline int cursor_push_error(struct cursor *cur, struct error *err)
|
||||
{
|
||||
return cursor_push_c_str(cur, err->msg);
|
||||
}
|
||||
|
||||
static inline int cursor_pull_error(struct cursor *cur, struct error *err)
|
||||
{
|
||||
return cursor_pull_c_str(cur, &err->msg);
|
||||
}
|
||||
|
||||
int note_error_(struct errors *errs, const char *fmt, ...);
|
||||
|
||||
void print_error_backtrace(struct errors *errors);
|
||||
|
||||
#endif /* LNSOCKET_ERROR_H */
|
7
node_modules/lnsocket/examples/README.md
generated
vendored
Normal file
7
node_modules/lnsocket/examples/README.md
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
|
||||
# Examples
|
||||
|
||||
## nodejs
|
||||
|
||||
$ npm install
|
||||
$ node node.js
|
24
node_modules/lnsocket/examples/node.js
generated
vendored
Normal file
24
node_modules/lnsocket/examples/node.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
const LNSocket = require('lnsocket')
|
||||
|
||||
async function go() {
|
||||
const ln = await LNSocket()
|
||||
|
||||
ln.genkey()
|
||||
await ln.connect_and_init("03f3c108ccd536b8526841f0a5c58212bb9e6584a1eb493080e7c1cc34f82dad71", "24.84.152.187")
|
||||
|
||||
const rune = "b3Xsg2AS2cknHYa6H94so7FAVQVdnRSP6Pv-1WOQEBc9NCZtZXRob2Q9b2ZmZXItc3VtbWFyeQ=="
|
||||
const summary = await ln.rpc({
|
||||
rune,
|
||||
method: "offer-summary",
|
||||
params: {
|
||||
offerid: "22db2cbdb2d6e1f4d727d099e2ea987c05212d6b4af56d92497e093b82360db7",
|
||||
limit: 10
|
||||
}
|
||||
})
|
||||
|
||||
ln.destroy()
|
||||
console.log(summary.result)
|
||||
return summary.result
|
||||
}
|
||||
|
||||
go()
|
18
node_modules/lnsocket/examples/package.json
generated
vendored
Normal file
18
node_modules/lnsocket/examples/package.json
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "examples",
|
||||
"description": "lnsocket examples",
|
||||
"version": "0.1.0",
|
||||
"repository": {
|
||||
"url": "https://github.com/jb55/examples"
|
||||
},
|
||||
"main": "node.js",
|
||||
"scripts": {
|
||||
"test": "tap test/*.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"lnsocket": "^0.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tap": "~0.2.5"
|
||||
}
|
||||
}
|
16
node_modules/lnsocket/examples/websockets.html
generated
vendored
Normal file
16
node_modules/lnsocket/examples/websockets.html
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Hello World</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello World</h1>
|
||||
<script src="lnsocket.js"></script>
|
||||
<script src="websockets.js?v=2"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
16
node_modules/lnsocket/examples/websockets.js
generated
vendored
Normal file
16
node_modules/lnsocket/examples/websockets.js
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
async function go() {
|
||||
const LNSocket = await lnsocket_init()
|
||||
const ln = LNSocket()
|
||||
|
||||
ln.genkey()
|
||||
//const their_init = await ln.connect_and_init("03f3c108ccd536b8526841f0a5c58212bb9e6584a1eb493080e7c1cc34f82dad71", "cln.jb55.com:443")
|
||||
await ln.connect_and_init("03f3c108ccd536b8526841f0a5c58212bb9e6584a1eb493080e7c1cc34f82dad71", "ws://24.84.152.187:8324")
|
||||
|
||||
const rune = "APaeUhcGPAMQwgV1Kn-hRRs5Bi4-D1nrfsHfCoTLl749MTAmbWV0aG9kPWdldGluZm8="
|
||||
const res = await ln.rpc({ method: "getinfo", rune })
|
||||
|
||||
document.body.innerHTML = `<pre>${JSON.stringify(res.result, undefined, 2)}</pre>`
|
||||
}
|
||||
|
||||
go()
|
12
node_modules/lnsocket/export.h
generated
vendored
Normal file
12
node_modules/lnsocket/export.h
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef LNSOCKET_COMMON_H
|
||||
#define LNSOCKET_COMMON_H
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define EXPORT EMSCRIPTEN_KEEPALIVE
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
#endif
|
37
node_modules/lnsocket/go/go.mod
generated
vendored
Normal file
37
node_modules/lnsocket/go/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
module github.com/jb55/lnsocket/go
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcd v0.22.0-beta.0.20211005184431-e3449998be39
|
||||
github.com/lightningnetwork/lnd v0.14.1-beta
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aead/siphash v1.0.1 // indirect
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
|
||||
github.com/btcsuite/btcutil v1.0.3-0.20210527170813-e2ba6805a890 // indirect
|
||||
github.com/btcsuite/btcutil/psbt v1.0.3-0.20210527170813-e2ba6805a890 // indirect
|
||||
github.com/btcsuite/btcwallet v0.13.0 // indirect
|
||||
github.com/btcsuite/btcwallet/wallet/txauthor v1.1.0 // indirect
|
||||
github.com/btcsuite/btcwallet/wallet/txrules v1.1.0 // indirect
|
||||
github.com/btcsuite/btcwallet/wallet/txsizes v1.1.0 // indirect
|
||||
github.com/btcsuite/btcwallet/walletdb v1.3.6-0.20210803004036-eebed51155ec // indirect
|
||||
github.com/btcsuite/btcwallet/wtxmgr v1.3.1-0.20210822222949-9b5a201c344c // indirect
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/decred/dcrd/lru v1.0.0 // indirect
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
github.com/kkdai/bstream v1.0.0 // indirect
|
||||
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf // indirect
|
||||
github.com/lightninglabs/neutrino v0.13.0 // indirect
|
||||
github.com/lightningnetwork/lnd/clock v1.1.0 // indirect
|
||||
github.com/lightningnetwork/lnd/queue v1.1.0 // indirect
|
||||
github.com/lightningnetwork/lnd/ticker v1.1.0 // indirect
|
||||
github.com/miekg/dns v1.1.43 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/net v0.0.0-20210913180222-943fd674d43e // indirect
|
||||
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164 // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
)
|
||||
|
||||
go 1.17
|
1009
node_modules/lnsocket/go/go.sum
generated
vendored
Normal file
1009
node_modules/lnsocket/go/go.sum
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
190
node_modules/lnsocket/go/lnsocket.go
generated
vendored
Normal file
190
node_modules/lnsocket/go/lnsocket.go
generated
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
package lnsocket
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/lightningnetwork/lnd/brontide"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/tor"
|
||||
)
|
||||
|
||||
const (
|
||||
COMMANDO_CMD = 0x4c4f
|
||||
COMMANDO_REPLY_CONTINUES = 0x594b
|
||||
COMMANDO_REPLY_TERM = 0x594d
|
||||
)
|
||||
|
||||
type CommandoMsg struct {
|
||||
Rune string
|
||||
Method string
|
||||
Params string
|
||||
RequestId uint64
|
||||
}
|
||||
|
||||
func NewCommandoMsg(token string, method string, params string) CommandoMsg {
|
||||
return CommandoMsg{
|
||||
Rune: token,
|
||||
Method: method,
|
||||
Params: params,
|
||||
}
|
||||
}
|
||||
|
||||
// A compile time check to ensure Init implements the lnwire.Message
|
||||
// interface.
|
||||
|
||||
func (msg *CommandoMsg) MsgType() lnwire.MessageType {
|
||||
return COMMANDO_CMD
|
||||
}
|
||||
|
||||
func (msg *CommandoMsg) Decode(reader io.Reader, size uint32) error {
|
||||
return fmt.Errorf("implememt commando decode?")
|
||||
}
|
||||
|
||||
func (msg *CommandoMsg) Encode(buf *bytes.Buffer, pver uint32) error {
|
||||
if err := lnwire.WriteUint64(buf, msg.RequestId); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf.WriteString("{\"method\": \"")
|
||||
buf.WriteString(msg.Method)
|
||||
buf.WriteString("\",\"params\":")
|
||||
buf.WriteString(msg.Params)
|
||||
buf.WriteString(",\"rune\":\"")
|
||||
buf.WriteString(msg.Rune)
|
||||
buf.WriteString("\"}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type LNSocket struct {
|
||||
Conn net.Conn
|
||||
PrivKeyECDH *keychain.PrivKeyECDH
|
||||
}
|
||||
|
||||
func (ln *LNSocket) GenKey() {
|
||||
remotePriv, _ := btcec.NewPrivateKey(btcec.S256())
|
||||
ln.PrivKeyECDH = &keychain.PrivKeyECDH{PrivKey: remotePriv}
|
||||
}
|
||||
|
||||
func (ln *LNSocket) ConnectWith(netAddr *lnwire.NetAddress) error {
|
||||
conn, err := brontide.Dial(ln.PrivKeyECDH, netAddr, tor.DefaultConnTimeout, net.DialTimeout)
|
||||
ln.Conn = conn
|
||||
return err
|
||||
}
|
||||
|
||||
func (ln *LNSocket) Connect(hostname string, pubkey string) error {
|
||||
addr, err := net.ResolveTCPAddr("tcp", hostname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bytes, err := hex.DecodeString(pubkey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, err := btcec.ParsePubKey(bytes, btcec.S256())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
netAddr := &lnwire.NetAddress{
|
||||
IdentityKey: key,
|
||||
Address: addr,
|
||||
}
|
||||
|
||||
return ln.ConnectWith(netAddr)
|
||||
}
|
||||
|
||||
func (ln *LNSocket) PerformInit() error {
|
||||
no_features := lnwire.NewRawFeatureVector()
|
||||
init_reply_msg := lnwire.NewInitMessage(no_features, no_features)
|
||||
|
||||
var b bytes.Buffer
|
||||
_, err := lnwire.WriteMessage(&b, init_reply_msg, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = ln.Conn.Write(b.Bytes())
|
||||
|
||||
// receive the first init msg
|
||||
_, _, err = ln.Recv()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ln *LNSocket) Rpc(token string, method string, params string) (string, error) {
|
||||
commando_msg := NewCommandoMsg(token, method, params)
|
||||
|
||||
var b bytes.Buffer
|
||||
_, err := lnwire.WriteMessage(&b, &commando_msg, 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
bs := b.Bytes()
|
||||
_, err = ln.Conn.Write(bs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return ln.rpcReadAll()
|
||||
}
|
||||
|
||||
func ParseMsgType(bytes []byte) uint16 {
|
||||
return uint16(bytes[0])<<8 | uint16(bytes[1])
|
||||
}
|
||||
|
||||
func (ln *LNSocket) Recv() (uint16, []byte, error) {
|
||||
res := make([]byte, 65535)
|
||||
n, err := ln.Conn.Read(res)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
if n < 2 {
|
||||
return 0, nil, fmt.Errorf("read too small")
|
||||
}
|
||||
res = res[:n]
|
||||
msgtype := ParseMsgType(res)
|
||||
return msgtype, res[2:], nil
|
||||
}
|
||||
|
||||
func (ln *LNSocket) rpcReadAll() (string, error) {
|
||||
all := []byte{}
|
||||
for {
|
||||
msgtype, res, err := ln.Recv()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
switch msgtype {
|
||||
case COMMANDO_REPLY_CONTINUES:
|
||||
all = append(all, res[8:]...)
|
||||
continue
|
||||
case COMMANDO_REPLY_TERM:
|
||||
all = append(all, res[8:]...)
|
||||
return string(all), nil
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ln *LNSocket) Disconnect() {
|
||||
ln.Conn.Close()
|
||||
}
|
||||
|
||||
func (ln *LNSocket) ConnectAndInit(hostname string, pubkey string) error {
|
||||
err := ln.Connect(hostname, pubkey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ln.PerformInit()
|
||||
}
|
481
node_modules/lnsocket/handshake.c
generated
vendored
Normal file
481
node_modules/lnsocket/handshake.c
generated
vendored
Normal file
|
@ -0,0 +1,481 @@
|
|||
/* Copyright Rusty Russell (Blockstream) 2015.
|
||||
William Casarin 2022
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "compiler.h"
|
||||
#include "endian.h"
|
||||
#include "error.h"
|
||||
#include "handshake.h"
|
||||
#include "hkdf.h"
|
||||
#include "lnsocket_internal.h"
|
||||
#include "sha256.h"
|
||||
#include <errno.h>
|
||||
#include <secp256k1_ecdh.h>
|
||||
#include <unistd.h>
|
||||
#include <sodium/randombytes.h>
|
||||
#include "export.h"
|
||||
|
||||
struct keypair generate_key(secp256k1_context *ctx)
|
||||
{
|
||||
struct keypair k;
|
||||
|
||||
do {
|
||||
randombytes_buf(k.priv.secret.data, sizeof(k.priv.secret.data));
|
||||
} while (!secp256k1_ec_pubkey_create(ctx, &k.pub.pubkey,
|
||||
k.priv.secret.data));
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
/* h = SHA-256(h || data) */
|
||||
static void sha_mix_in(struct sha256 *h, const void *data, size_t len)
|
||||
{
|
||||
struct sha256_ctx shactx;
|
||||
|
||||
sha256_init(&shactx);
|
||||
sha256_update(&shactx, h->u.u8, sizeof(*h));
|
||||
sha256_update(&shactx, data, len);
|
||||
sha256_done(&shactx, h);
|
||||
}
|
||||
|
||||
/* h = SHA-256(h || pub.serializeCompressed()) */
|
||||
static void sha_mix_in_key(secp256k1_context *ctx, struct sha256 *h,
|
||||
const struct pubkey *key)
|
||||
{
|
||||
u8 der[PUBKEY_CMPR_LEN];
|
||||
size_t len = sizeof(der);
|
||||
|
||||
secp256k1_ec_pubkey_serialize(ctx, der, &len, &key->pubkey,
|
||||
SECP256K1_EC_COMPRESSED);
|
||||
assert(len == sizeof(der));
|
||||
sha_mix_in(h, der, sizeof(der));
|
||||
}
|
||||
|
||||
|
||||
/* BOLT #8:
|
||||
* * `encryptWithAD(k, n, ad, plaintext)`: outputs `encrypt(k, n, ad,
|
||||
* plaintext)`
|
||||
* * Where `encrypt` is an evaluation of `ChaCha20-Poly1305` (IETF
|
||||
* variant) with the passed arguments, with nonce `n`
|
||||
*/
|
||||
static void encrypt_ad(const struct secret *k, u64 nonce,
|
||||
const void *additional_data, size_t additional_data_len,
|
||||
const void *plaintext, size_t plaintext_len,
|
||||
void *output, size_t outputlen)
|
||||
{
|
||||
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||
unsigned long long clen;
|
||||
int ret;
|
||||
|
||||
assert(outputlen == plaintext_len + crypto_aead_chacha20poly1305_ietf_ABYTES);
|
||||
le64_nonce(npub, nonce);
|
||||
BUILD_ASSERT(sizeof(*k) == crypto_aead_chacha20poly1305_ietf_KEYBYTES);
|
||||
|
||||
ret = crypto_aead_chacha20poly1305_ietf_encrypt(
|
||||
output, &clen, memcheck(plaintext, plaintext_len),
|
||||
plaintext_len, additional_data, additional_data_len,
|
||||
NULL, npub, k->data);
|
||||
|
||||
assert(ret == 0);
|
||||
assert(clen == plaintext_len + crypto_aead_chacha20poly1305_ietf_ABYTES);
|
||||
}
|
||||
|
||||
static inline void check_act_one(const struct act_one *act1)
|
||||
{
|
||||
/* BOLT #8:
|
||||
*
|
||||
* : 1 byte for the handshake version, 33 bytes for the compressed
|
||||
* ephemeral public key of the initiator, and 16 bytes for the
|
||||
* `poly1305` tag.
|
||||
*/
|
||||
BUILD_ASSERT(sizeof(act1->v) == 1);
|
||||
BUILD_ASSERT(sizeof(act1->pubkey) == 33);
|
||||
BUILD_ASSERT(sizeof(act1->tag) == 16);
|
||||
}
|
||||
|
||||
/*
|
||||
static void print_hex(u8 *bytes, int len) {
|
||||
int i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
printf("%02x", bytes[i]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void new_handshake(secp256k1_context *secp, struct handshake *handshake,
|
||||
const struct pubkey *responder_id)
|
||||
{
|
||||
/* BOLT #8:
|
||||
*
|
||||
* Before the start of Act One, both sides initialize their
|
||||
* per-sessions state as follows:
|
||||
*
|
||||
* 1. `h = SHA-256(protocolName)`
|
||||
* * where `protocolName = "Noise_XK_secp256k1_ChaChaPoly_SHA256"`
|
||||
* encoded as an ASCII string
|
||||
*/
|
||||
sha256(&handshake->h, "Noise_XK_secp256k1_ChaChaPoly_SHA256",
|
||||
strlen("Noise_XK_secp256k1_ChaChaPoly_SHA256"));
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 2. `ck = h`
|
||||
*/
|
||||
BUILD_ASSERT(sizeof(handshake->h) == sizeof(handshake->ck));
|
||||
memcpy(&handshake->ck, &handshake->h, sizeof(handshake->ck));
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 3. `h = SHA-256(h || prologue)`
|
||||
* * where `prologue` is the ASCII string: `lightning`
|
||||
*/
|
||||
sha_mix_in(&handshake->h, "lightning", strlen("lightning"));
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* As a concluding step, both sides mix the responder's public key
|
||||
* into the handshake digest:
|
||||
*
|
||||
* * The initiating node mixes in the responding node's static public
|
||||
* key serialized in Bitcoin's compressed format:
|
||||
* * `h = SHA-256(h || rs.pub.serializeCompressed())`
|
||||
*
|
||||
* * The responding node mixes in their local static public key
|
||||
* serialized in Bitcoin's compressed format:
|
||||
* * `h = SHA-256(h || ls.pub.serializeCompressed())`
|
||||
*/
|
||||
sha_mix_in_key(secp, &handshake->h, responder_id);
|
||||
}
|
||||
|
||||
/*
|
||||
static void print_act_two(struct act_two *two)
|
||||
{
|
||||
printf("ACT2 v %d pubkey ", two->v);
|
||||
print_hex(two->pubkey, sizeof(two->pubkey));
|
||||
printf(" tag ");
|
||||
print_hex(two->tag, sizeof(two->tag));
|
||||
printf("\n");
|
||||
}
|
||||
*/
|
||||
|
||||
/* BOLT #8:
|
||||
* * `decryptWithAD(k, n, ad, ciphertext)`: outputs `decrypt(k, n, ad,
|
||||
* ciphertext)`
|
||||
* * Where `decrypt` is an evaluation of `ChaCha20-Poly1305` (IETF
|
||||
* variant) with the passed arguments, with nonce `n`
|
||||
*/
|
||||
static int decrypt(const struct secret *k, u64 nonce,
|
||||
const void *additional_data, size_t additional_data_len,
|
||||
const void *ciphertext, size_t ciphertext_len,
|
||||
void *output, size_t outputlen)
|
||||
{
|
||||
unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||
unsigned long long mlen;
|
||||
|
||||
assert(outputlen == ciphertext_len - crypto_aead_chacha20poly1305_ietf_ABYTES);
|
||||
|
||||
le64_nonce(npub, nonce);
|
||||
BUILD_ASSERT(sizeof(*k) == crypto_aead_chacha20poly1305_ietf_KEYBYTES);
|
||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(output, &mlen, NULL,
|
||||
memcheck(ciphertext, ciphertext_len),
|
||||
ciphertext_len,
|
||||
additional_data, additional_data_len,
|
||||
npub, k->data) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(mlen == ciphertext_len - crypto_aead_chacha20poly1305_ietf_ABYTES);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int handshake_success(struct lnsocket *ln, struct handshake *h)
|
||||
{
|
||||
struct crypto_state *cs = &ln->crypto_state;
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 9. `rk, sk = HKDF(ck, zero)`
|
||||
* * where `zero` is a zero-length plaintext, `rk` is the key to
|
||||
* be used by the responder to decrypt the messages sent by the
|
||||
* initiator, and `sk` is the key to be used by the responder
|
||||
* to encrypt messages to the initiator
|
||||
*
|
||||
* * The final encryption keys, to be used for sending and
|
||||
* receiving messages for the duration of the session, are
|
||||
* generated.
|
||||
*/
|
||||
if (h->side == RESPONDER)
|
||||
hkdf_two_keys(&cs->rk, &cs->sk, &h->ck, NULL);
|
||||
else
|
||||
hkdf_two_keys(&cs->sk, &cs->rk, &h->ck, NULL);
|
||||
|
||||
cs->rn = cs->sn = 0;
|
||||
cs->r_ck = cs->s_ck = h->ck;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct act_three *build_act_three(struct lnsocket *ln)
|
||||
{
|
||||
u8 spub[PUBKEY_CMPR_LEN];
|
||||
size_t len = sizeof(spub);
|
||||
struct handshake *h = &ln->handshake;
|
||||
|
||||
/* BOLT #8:
|
||||
* 1. `c = encryptWithAD(temp_k2, 1, h, s.pub.serializeCompressed())`
|
||||
* * where `s` is the static public key of the initiator
|
||||
*/
|
||||
secp256k1_ec_pubkey_serialize(ln->secp, spub, &len,
|
||||
&ln->key.pub.pubkey,
|
||||
SECP256K1_EC_COMPRESSED);
|
||||
encrypt_ad(&h->temp_k, 1, &h->h, sizeof(h->h), spub, sizeof(spub),
|
||||
h->act3.ciphertext, sizeof(h->act3.ciphertext));
|
||||
|
||||
/* BOLT #8:
|
||||
* 2. `h = SHA-256(h || c)`
|
||||
*/
|
||||
sha_mix_in(&h->h, h->act3.ciphertext, sizeof(h->act3.ciphertext));
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 3. `se = ECDH(s.priv, re)`
|
||||
* * where `re` is the ephemeral public key of the responder
|
||||
*/
|
||||
if (!secp256k1_ecdh(ln->secp, h->ss.data, &h->re.pubkey,
|
||||
ln->key.priv.secret.data, NULL, NULL)) {
|
||||
note_error(&ln->errs, "act3 ecdh handshake failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 4. `ck, temp_k3 = HKDF(ck, se)`
|
||||
* * The final intermediate shared secret is mixed into the running chaining key.
|
||||
*/
|
||||
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 5. `t = encryptWithAD(temp_k3, 0, h, zero)`
|
||||
* * where `zero` is a zero-length plaintext
|
||||
*
|
||||
*/
|
||||
encrypt_ad(&h->temp_k, 0, &h->h, sizeof(h->h), NULL, 0,
|
||||
h->act3.tag, sizeof(h->act3.tag));
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 8. Send `m = 0 || c || t` over the network buffer.
|
||||
*
|
||||
*/
|
||||
h->act3.v = 0;
|
||||
|
||||
handshake_success(ln, &ln->handshake);
|
||||
|
||||
return &h->act3;
|
||||
}
|
||||
|
||||
|
||||
// act2: handle the response to the message sent in act1
|
||||
struct act_three* EXPORT lnsocket_act_two(struct lnsocket *ln, struct act_two *act2)
|
||||
{
|
||||
struct handshake *h = &ln->handshake;
|
||||
|
||||
//print_act_two(act2);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 3. If `v` is an unrecognized handshake version, then the responder
|
||||
* MUST abort the connection attempt.
|
||||
*/
|
||||
if (act2->v != 0) {
|
||||
note_error(&ln->errs, "unrecognized handshake version");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//print_hex()
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* * The raw bytes of the remote party's ephemeral public key
|
||||
* (`re`) are to be deserialized into a point on the curve using
|
||||
* affine coordinates as encoded by the key's serialized
|
||||
* composed format.
|
||||
*/
|
||||
if (secp256k1_ec_pubkey_parse(ln->secp, &h->re.pubkey, act2->pubkey,
|
||||
sizeof(act2->pubkey)) != 1) {
|
||||
note_error(&ln->errs, "failed to parse remote pubkey");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 4. `h = SHA-256(h || re.serializeCompressed())`
|
||||
*/
|
||||
sha_mix_in_key(ln->secp, &h->h, &h->re);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 5. `es = ECDH(s.priv, re)`
|
||||
*/
|
||||
if (!secp256k1_ecdh(ln->secp, h->ss.data, &h->re.pubkey,
|
||||
h->e.priv.secret.data, NULL, NULL)) {
|
||||
note_error(&ln->errs, "act2 ecdh failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 6. `ck, temp_k2 = HKDF(ck, ee)`
|
||||
* * A new temporary encryption key is generated, which is
|
||||
* used to generate the authenticating MAC.
|
||||
*/
|
||||
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 7. `p = decryptWithAD(temp_k2, 0, h, c)`
|
||||
* * If the MAC check in this operation fails, then the initiator
|
||||
* MUST terminate the connection without any further messages.
|
||||
*/
|
||||
if (!decrypt(&h->temp_k, 0, &h->h, sizeof(h->h),
|
||||
act2->tag, sizeof(act2->tag), NULL, 0)) {
|
||||
note_error(&ln->errs, "handshake decrypt failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 8. `h = SHA-256(h || c)`
|
||||
* * The received ciphertext is mixed into the handshake digest.
|
||||
* This step serves to ensure the payload wasn't modified by a
|
||||
* MITM.
|
||||
*/
|
||||
sha_mix_in(&h->h, act2->tag, sizeof(act2->tag));
|
||||
|
||||
return build_act_three(ln);
|
||||
}
|
||||
|
||||
// Prepare the very first message and send it the connected node
|
||||
// Wait for a response in act2
|
||||
int act_one_initiator_prep(struct lnsocket *ln)
|
||||
{
|
||||
struct handshake *h = &ln->handshake;
|
||||
|
||||
h->e = generate_key(ln->secp);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 2. `h = SHA-256(h || e.pub.serializeCompressed())`
|
||||
* * The newly generated ephemeral key is accumulated into the
|
||||
* running handshake digest.
|
||||
*/
|
||||
sha_mix_in_key(ln->secp, &h->h, &h->e.pub);
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 3. `es = ECDH(e.priv, rs)`
|
||||
* * The initiator performs an ECDH between its newly generated ephemeral
|
||||
* key and the remote node's static public key.
|
||||
*/
|
||||
if (!secp256k1_ecdh(ln->secp, h->ss.data,
|
||||
&h->their_id.pubkey, h->e.priv.secret.data,
|
||||
NULL, NULL)) {
|
||||
return note_error(&ln->errs, "handshake failed, secp256k1_ecdh error");
|
||||
}
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 4. `ck, temp_k1 = HKDF(ck, es)`
|
||||
* * A new temporary encryption key is generated, which is
|
||||
* used to generate the authenticating MAC.
|
||||
*/
|
||||
hkdf_two_keys(&h->ck, &h->temp_k, &h->ck, &h->ss);
|
||||
|
||||
/* BOLT #8:
|
||||
* 5. `c = encryptWithAD(temp_k1, 0, h, zero)`
|
||||
* * where `zero` is a zero-length plaintext
|
||||
*/
|
||||
encrypt_ad(&h->temp_k, 0, &h->h, sizeof(h->h), NULL, 0,
|
||||
h->act1.tag, sizeof(h->act1.tag));
|
||||
|
||||
/* BOLT #8:
|
||||
* 6. `h = SHA-256(h || c)`
|
||||
* * Finally, the generated ciphertext is accumulated into the
|
||||
* authenticating handshake digest.
|
||||
*/
|
||||
sha_mix_in(&h->h, h->act1.tag, sizeof(h->act1.tag));
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 7. Send `m = 0 || e.pub.serializeCompressed() || c` to the responder over the network buffer.
|
||||
*/
|
||||
h->act1.v = 0;
|
||||
size_t len = sizeof(h->act1.pubkey);
|
||||
secp256k1_ec_pubkey_serialize(ln->secp, h->act1.pubkey, &len,
|
||||
&h->e.pub.pubkey,
|
||||
SECP256K1_EC_COMPRESSED);
|
||||
|
||||
check_act_one(&h->act1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// act2: read the response to the message sent in act1
|
||||
static int act_two_initiator(struct lnsocket *ln, struct handshake *h)
|
||||
{
|
||||
/* BOLT #8:
|
||||
*
|
||||
* 1. Read _exactly_ 50 bytes from the network buffer.
|
||||
*
|
||||
* 2. Parse the read message (`m`) into `v`, `re`, and `c`:
|
||||
* * where `v` is the _first_ byte of `m`, `re` is the next 33
|
||||
* bytes of `m`, and `c` is the last 16 bytes of `m`.
|
||||
*/
|
||||
ssize_t size;
|
||||
|
||||
if ((size = read(ln->socket, &h->act2, ACT_TWO_SIZE)) != ACT_TWO_SIZE) {
|
||||
printf("read %ld bytes, expected %d\n", size, ACT_TWO_SIZE);
|
||||
return note_error(&ln->errs, "%s", strerror(errno));
|
||||
}
|
||||
|
||||
struct act_three *act3 = lnsocket_act_two(ln, &h->act2);
|
||||
if (act3 == NULL)
|
||||
return 0;
|
||||
|
||||
if (write(ln->socket, act3, ACT_THREE_SIZE) != ACT_THREE_SIZE) {
|
||||
return note_error(&ln->errs, "handshake failed on initial send");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int act_one_initiator(struct lnsocket *ln)
|
||||
{
|
||||
if (!act_one_initiator_prep(ln))
|
||||
return 0;
|
||||
|
||||
if (write(ln->socket, &ln->handshake.act1, ACT_ONE_SIZE) != ACT_ONE_SIZE) {
|
||||
return note_error(&ln->errs, "handshake failed on initial send");
|
||||
}
|
||||
|
||||
return act_two_initiator(ln, &ln->handshake);
|
||||
}
|
147
node_modules/lnsocket/handshake.h
generated
vendored
Normal file
147
node_modules/lnsocket/handshake.h
generated
vendored
Normal file
|
@ -0,0 +1,147 @@
|
|||
/* Copyright Rusty Russell (Blockstream) 2015.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LNLINK_HANDSHAKE_H
|
||||
#define LNLINK_HANDSHAKE_H
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "sha256.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#include <sodium/crypto_aead_chacha20poly1305.h>
|
||||
#include <secp256k1_extrakeys.h>
|
||||
|
||||
#define ACT_ONE_SIZE 50
|
||||
#define ACT_TWO_SIZE 50
|
||||
#define ACT_THREE_SIZE 66
|
||||
|
||||
enum bolt8_side {
|
||||
INITIATOR,
|
||||
RESPONDER
|
||||
};
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* Act One is sent from initiator to responder. During Act One, the
|
||||
* initiator attempts to satisfy an implicit challenge by the responder. To
|
||||
* complete this challenge, the initiator must know the static public key of
|
||||
* the responder.
|
||||
*/
|
||||
struct act_one {
|
||||
u8 v;
|
||||
u8 pubkey[PUBKEY_CMPR_LEN];
|
||||
u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES];
|
||||
};
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* Act Two is sent from the responder to the initiator. Act Two will
|
||||
* _only_ take place if Act One was successful. Act One was successful if
|
||||
* the responder was able to properly decrypt and check the MAC of the tag
|
||||
* sent at the end of Act One.
|
||||
*/
|
||||
struct act_two {
|
||||
u8 v;
|
||||
u8 pubkey[PUBKEY_CMPR_LEN];
|
||||
u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES];
|
||||
};
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* Act Three is the final phase in the authenticated key agreement described
|
||||
* in this section. This act is sent from the initiator to the responder as a
|
||||
* concluding step. Act Three is executed _if and only if_ Act Two was
|
||||
* successful. During Act Three, the initiator transports its static public
|
||||
* key to the responder encrypted with _strong_ forward secrecy, using the
|
||||
* accumulated `HKDF` derived secret key at this point of the handshake.
|
||||
*/
|
||||
struct act_three {
|
||||
u8 v;
|
||||
u8 ciphertext[PUBKEY_CMPR_LEN + crypto_aead_chacha20poly1305_ietf_ABYTES];
|
||||
u8 tag[crypto_aead_chacha20poly1305_ietf_ABYTES];
|
||||
};
|
||||
|
||||
/* BOLT #8:
|
||||
*
|
||||
* Throughout the handshake process, each side maintains these variables:
|
||||
*
|
||||
* * `ck`: the **chaining key**. This value is the accumulated hash of all
|
||||
* previous ECDH outputs. At the end of the handshake, `ck` is used to derive
|
||||
* the encryption keys for Lightning messages.
|
||||
*
|
||||
* * `h`: the **handshake hash**. This value is the accumulated hash of _all_
|
||||
* handshake data that has been sent and received so far during the handshake
|
||||
* process.
|
||||
*
|
||||
* * `temp_k1`, `temp_k2`, `temp_k3`: the **intermediate keys**. These are used to
|
||||
* encrypt and decrypt the zero-length AEAD payloads at the end of each handshake
|
||||
* message.
|
||||
*
|
||||
* * `e`: a party's **ephemeral keypair**. For each session, a node MUST generate a
|
||||
* new ephemeral key with strong cryptographic randomness.
|
||||
*
|
||||
* * `s`: a party's **static keypair** (`ls` for local, `rs` for remote)
|
||||
*/
|
||||
struct handshake {
|
||||
struct secret ck;
|
||||
struct secret temp_k;
|
||||
struct sha256 h;
|
||||
struct keypair e;
|
||||
struct secret ss;
|
||||
|
||||
/* Used between the Acts */
|
||||
struct pubkey re;
|
||||
struct act_one act1;
|
||||
struct act_two act2;
|
||||
struct act_three act3;
|
||||
|
||||
/* Where is connection from/to */
|
||||
struct addrinfo addr;
|
||||
|
||||
/* Who they are: set already if we're initiator. */
|
||||
struct pubkey their_id;
|
||||
|
||||
/* Are we initiator or responder. */
|
||||
enum bolt8_side side;
|
||||
|
||||
/* Function to call once handshake complete. */
|
||||
/*
|
||||
struct io_plan *(*cb)(struct io_conn *conn,
|
||||
const struct pubkey *their_id,
|
||||
const struct wireaddr_internal *wireaddr,
|
||||
struct crypto_state *cs,
|
||||
void *cbarg);
|
||||
void *cbarg;
|
||||
*/
|
||||
};
|
||||
|
||||
void new_handshake(secp256k1_context *secp, struct handshake *handshake,
|
||||
const struct pubkey *responder_id);
|
||||
|
||||
struct lnsocket;
|
||||
|
||||
int act_one_initiator_prep(struct lnsocket *ln);
|
||||
int act_one_initiator(struct lnsocket *ln);
|
||||
struct keypair generate_key(secp256k1_context *ctx);
|
||||
|
||||
#endif /* LNLINK_HANDSHAKE_H */
|
98
node_modules/lnsocket/hkdf.c
generated
vendored
Normal file
98
node_modules/lnsocket/hkdf.c
generated
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* MIT (BSD) license */
|
||||
|
||||
#include "hmac.h"
|
||||
#include "sha256.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
void hkdf_sha256(void *okm, size_t okm_size,
|
||||
const void *s, size_t ssize,
|
||||
const void *k, size_t ksize,
|
||||
const void *info, size_t isize)
|
||||
{
|
||||
struct hmac_sha256 prk, t;
|
||||
struct hmac_sha256_ctx ctx;
|
||||
unsigned char c;
|
||||
|
||||
assert(okm_size < 255 * sizeof(t));
|
||||
|
||||
/* RFC 5869:
|
||||
*
|
||||
* 2.2. Step 1: Extract
|
||||
*
|
||||
* HKDF-Extract(salt, IKM) -> PRK
|
||||
*
|
||||
* Options:
|
||||
* Hash a hash function; HashLen denotes the length of the
|
||||
* hash function output in octets
|
||||
*
|
||||
* Inputs:
|
||||
* salt optional salt value (a non-secret random value);
|
||||
* if not provided, it is set to a string of HashLen zeros.
|
||||
* IKM input keying material
|
||||
*
|
||||
* Output:
|
||||
* PRK a pseudorandom key (of HashLen octets)
|
||||
*
|
||||
* The output PRK is calculated as follows:
|
||||
*
|
||||
* PRK = HMAC-Hash(salt, IKM)
|
||||
*/
|
||||
hmac_sha256(&prk, s, ssize, k, ksize);
|
||||
|
||||
/*
|
||||
* 2.3. Step 2: Expand
|
||||
*
|
||||
* HKDF-Expand(PRK, info, L) -> OKM
|
||||
*
|
||||
* Options:
|
||||
* Hash a hash function; HashLen denotes the length of the
|
||||
* hash function output in octets
|
||||
*
|
||||
* Inputs:
|
||||
* PRK a pseudorandom key of at least HashLen octets
|
||||
* (usually, the output from the extract step)
|
||||
* info optional context and application specific information
|
||||
* (can be a zero-length string)
|
||||
* L length of output keying material in octets
|
||||
* (<= 255*HashLen)
|
||||
*
|
||||
* Output:
|
||||
* OKM output keying material (of L octets)
|
||||
*
|
||||
* The output OKM is calculated as follows:
|
||||
*
|
||||
* N = ceil(L/HashLen)
|
||||
* T = T(1) | T(2) | T(3) | ... | T(N)
|
||||
* OKM = first L octets of T
|
||||
*
|
||||
* where:
|
||||
* T(0) = empty string (zero length)
|
||||
* T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
|
||||
* T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
|
||||
* T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
|
||||
* ...
|
||||
*
|
||||
* (where the constant concatenated to the end of each T(n) is a
|
||||
* single octet.)
|
||||
*/
|
||||
c = 1;
|
||||
hmac_sha256_init(&ctx, &prk, sizeof(prk));
|
||||
hmac_sha256_update(&ctx, info, isize);
|
||||
hmac_sha256_update(&ctx, &c, 1);
|
||||
hmac_sha256_done(&ctx, &t);
|
||||
|
||||
while (okm_size > sizeof(t)) {
|
||||
memcpy(okm, &t, sizeof(t));
|
||||
okm = (char *)okm + sizeof(t);
|
||||
okm_size -= sizeof(t);
|
||||
|
||||
c++;
|
||||
hmac_sha256_init(&ctx, &prk, sizeof(prk));
|
||||
hmac_sha256_update(&ctx, &t, sizeof(t));
|
||||
hmac_sha256_update(&ctx, info, isize);
|
||||
hmac_sha256_update(&ctx, &c, 1);
|
||||
hmac_sha256_done(&ctx, &t);
|
||||
}
|
||||
memcpy(okm, &t, okm_size);
|
||||
}
|
22
node_modules/lnsocket/hkdf.h
generated
vendored
Normal file
22
node_modules/lnsocket/hkdf.h
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
#ifndef CCAN_CRYPTO_HKDF_SHA256_H
|
||||
#define CCAN_CRYPTO_HKDF_SHA256_H
|
||||
/* BSD-MIT - see LICENSE file for details */
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* hkdf_sha256 - generate a derived key
|
||||
* @okm: where to output the key
|
||||
* @okm_size: the number of bytes pointed to by @okm (must be less than 255*32)
|
||||
* @s: salt
|
||||
* @ssize: the number of bytes pointed to by @s
|
||||
* @k: pointer to input key
|
||||
* @ksize: the number of bytes pointed to by @k
|
||||
* @info: pointer to info
|
||||
* @isize: the number of bytes pointed to by @info
|
||||
*/
|
||||
void hkdf_sha256(void *okm, size_t okm_size,
|
||||
const void *s, size_t ssize,
|
||||
const void *k, size_t ksize,
|
||||
const void *info, size_t isize);
|
||||
#endif /* CCAN_CRYPTO_HKDF_SHA256_H */
|
278
node_modules/lnsocket/hmac.c
generated
vendored
Normal file
278
node_modules/lnsocket/hmac.c
generated
vendored
Normal file
|
@ -0,0 +1,278 @@
|
|||
/* Copyright Rusty Russell (Blockstream) 2015.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "hmac.h"
|
||||
|
||||
#define IPAD 0x3636363636363636ULL
|
||||
#define OPAD 0x5C5C5C5C5C5C5C5CULL
|
||||
|
||||
#define BLOCK_256_U64S (HMAC_SHA256_BLOCKSIZE / sizeof(uint64_t))
|
||||
#define BLOCK_512_U64S (HMAC_SHA512_BLOCKSIZE / sizeof(uint64_t))
|
||||
|
||||
static inline void xor_block_256(uint64_t block[BLOCK_256_U64S], uint64_t pad)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < BLOCK_256_U64S; i++)
|
||||
block[i] ^= pad;
|
||||
}
|
||||
|
||||
|
||||
static inline void xor_block_512(uint64_t block[BLOCK_512_U64S], uint64_t pad)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < BLOCK_512_U64S; i++)
|
||||
block[i] ^= pad;
|
||||
}
|
||||
|
||||
void hmac_sha256_init(struct hmac_sha256_ctx *ctx,
|
||||
const void *k, size_t ksize)
|
||||
{
|
||||
struct sha256 hashed_key;
|
||||
/* We use k_opad as k_ipad temporarily. */
|
||||
uint64_t *k_ipad = ctx->k_opad;
|
||||
|
||||
/* (keys longer than B bytes are first hashed using H) */
|
||||
if (ksize > HMAC_SHA256_BLOCKSIZE) {
|
||||
sha256(&hashed_key, k, ksize);
|
||||
k = &hashed_key;
|
||||
ksize = sizeof(hashed_key);
|
||||
}
|
||||
|
||||
/* From RFC2104:
|
||||
*
|
||||
* (1) append zeros to the end of K to create a B byte string
|
||||
* (e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
* appended with 44 zero bytes 0x00)
|
||||
*/
|
||||
memcpy(k_ipad, k, ksize);
|
||||
memset((char *)k_ipad + ksize, 0, HMAC_SHA256_BLOCKSIZE - ksize);
|
||||
|
||||
/*
|
||||
* (2) XOR (bitwise exclusive-OR) the B byte string computed
|
||||
* in step (1) with ipad
|
||||
*/
|
||||
xor_block_256(k_ipad, IPAD);
|
||||
|
||||
/*
|
||||
* We start (4) here, appending text later:
|
||||
*
|
||||
* (3) append the stream of data 'text' to the B byte string resulting
|
||||
* from step (2)
|
||||
* (4) apply H to the stream generated in step (3)
|
||||
*/
|
||||
sha256_init(&ctx->sha);
|
||||
sha256_update(&ctx->sha, k_ipad, HMAC_SHA256_BLOCKSIZE);
|
||||
|
||||
/*
|
||||
* (5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
* step (1) with opad
|
||||
*/
|
||||
xor_block_256(ctx->k_opad, IPAD^OPAD);
|
||||
}
|
||||
|
||||
|
||||
void hmac_sha512_init(struct hmac_sha512_ctx *ctx,
|
||||
const void *k, size_t ksize)
|
||||
{
|
||||
struct sha512 hashed_key;
|
||||
/* We use k_opad as k_ipad temporarily. */
|
||||
uint64_t *k_ipad = ctx->k_opad;
|
||||
|
||||
/* (keys longer than B bytes are first hashed using H) */
|
||||
if (ksize > HMAC_SHA512_BLOCKSIZE) {
|
||||
sha512(&hashed_key, k, ksize);
|
||||
k = &hashed_key;
|
||||
ksize = sizeof(hashed_key);
|
||||
}
|
||||
|
||||
/* From RFC2104:
|
||||
*
|
||||
* (1) append zeros to the end of K to create a B byte string
|
||||
* (e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
* appended with 44 zero bytes 0x00)
|
||||
*/
|
||||
memcpy(k_ipad, k, ksize);
|
||||
memset((char *)k_ipad + ksize, 0, HMAC_SHA512_BLOCKSIZE - ksize);
|
||||
|
||||
/*
|
||||
* (2) XOR (bitwise exclusive-OR) the B byte string computed
|
||||
* in step (1) with ipad
|
||||
*/
|
||||
xor_block_512(k_ipad, IPAD);
|
||||
|
||||
/*
|
||||
* We start (4) here, appending text later:
|
||||
*
|
||||
* (3) append the stream of data 'text' to the B byte string resulting
|
||||
* from step (2)
|
||||
* (4) apply H to the stream generated in step (3)
|
||||
*/
|
||||
sha512_init(&ctx->sha);
|
||||
sha512_update(&ctx->sha, k_ipad, HMAC_SHA512_BLOCKSIZE);
|
||||
|
||||
/*
|
||||
* (5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
* step (1) with opad
|
||||
*/
|
||||
xor_block_512(ctx->k_opad, IPAD^OPAD);
|
||||
}
|
||||
|
||||
|
||||
void hmac_sha256_update(struct hmac_sha256_ctx *ctx, const void *p, size_t size)
|
||||
{
|
||||
/* This is the appending-text part of this:
|
||||
*
|
||||
* (3) append the stream of data 'text' to the B byte string resulting
|
||||
* from step (2)
|
||||
* (4) apply H to the stream generated in step (3)
|
||||
*/
|
||||
sha256_update(&ctx->sha, p, size);
|
||||
}
|
||||
|
||||
|
||||
void hmac_sha512_update(struct hmac_sha512_ctx *ctx, const void *p, size_t size)
|
||||
{
|
||||
sha512_update(&ctx->sha, p, size);
|
||||
}
|
||||
|
||||
|
||||
void hmac_sha256_done(struct hmac_sha256_ctx *ctx,
|
||||
struct hmac_sha256 *hmac)
|
||||
{
|
||||
/* (4) apply H to the stream generated in step (3) */
|
||||
sha256_done(&ctx->sha, &hmac->sha);
|
||||
|
||||
/*
|
||||
* (6) append the H result from step (4) to the B byte string
|
||||
* resulting from step (5)
|
||||
* (7) apply H to the stream generated in step (6) and output
|
||||
* the result
|
||||
*/
|
||||
sha256_init(&ctx->sha);
|
||||
sha256_update(&ctx->sha, ctx->k_opad, sizeof(ctx->k_opad));
|
||||
sha256_update(&ctx->sha, &hmac->sha, sizeof(hmac->sha));
|
||||
sha256_done(&ctx->sha, &hmac->sha);
|
||||
}
|
||||
|
||||
|
||||
void hmac_sha512_done(struct hmac_sha512_ctx *ctx,
|
||||
struct hmac_sha512 *hmac)
|
||||
{
|
||||
/* (4) apply H to the stream generated in step (3) */
|
||||
sha512_done(&ctx->sha, &hmac->sha);
|
||||
|
||||
/*
|
||||
* (6) append the H result from step (4) to the B byte string
|
||||
* resulting from step (5)
|
||||
* (7) apply H to the stream generated in step (6) and output
|
||||
* the result
|
||||
*/
|
||||
sha512_init(&ctx->sha);
|
||||
sha512_update(&ctx->sha, ctx->k_opad, sizeof(ctx->k_opad));
|
||||
sha512_update(&ctx->sha, &hmac->sha, sizeof(hmac->sha));
|
||||
sha512_done(&ctx->sha, &hmac->sha);
|
||||
}
|
||||
|
||||
#if 1
|
||||
void hmac_sha256(struct hmac_sha256 *hmac,
|
||||
const void *k, size_t ksize,
|
||||
const void *d, size_t dsize)
|
||||
{
|
||||
struct hmac_sha256_ctx ctx;
|
||||
|
||||
hmac_sha256_init(&ctx, k, ksize);
|
||||
hmac_sha256_update(&ctx, d, dsize);
|
||||
hmac_sha256_done(&ctx, hmac);
|
||||
}
|
||||
|
||||
|
||||
void hmac_sha512(struct hmac_sha512 *hmac,
|
||||
const void *k, size_t ksize,
|
||||
const void *d, size_t dsize)
|
||||
{
|
||||
struct hmac_sha512_ctx ctx;
|
||||
|
||||
hmac_sha512_init(&ctx, k, ksize);
|
||||
hmac_sha512_update(&ctx, d, dsize);
|
||||
hmac_sha512_done(&ctx, hmac);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
/* Direct mapping from MD5 example in RFC2104 */
|
||||
void hmac_sha256(struct hmac_sha256 *hmac,
|
||||
const void *key, size_t key_len,
|
||||
const void *text, size_t text_len)
|
||||
{
|
||||
struct sha256_ctx context;
|
||||
unsigned char k_ipad[65]; /* inner padding -
|
||||
* key XORd with ipad
|
||||
*/
|
||||
unsigned char k_opad[65]; /* outer padding -
|
||||
* key XORd with opad
|
||||
*//* start out by storing key in pads */
|
||||
unsigned char tk[32];
|
||||
int i;
|
||||
|
||||
/* if key is longer than 64 bytes reset it to key=MD5(key) */
|
||||
if (key_len > 64) {
|
||||
|
||||
struct sha256_ctx tctx;
|
||||
|
||||
sha256_init(&tctx);
|
||||
sha256_update(&tctx, key, key_len);
|
||||
sha256_done(&tctx, tk);
|
||||
|
||||
key = tk;
|
||||
key_len = 32;
|
||||
}
|
||||
bzero( k_ipad, sizeof k_ipad);
|
||||
bzero( k_opad, sizeof k_opad);
|
||||
bcopy( key, k_ipad, key_len);
|
||||
bcopy( key, k_opad, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i=0; i<64; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
/*
|
||||
* perform inner MD5
|
||||
*/
|
||||
sha256_init(&context); /* init context for 1st
|
||||
* pass */
|
||||
sha256_update(&context, k_ipad, 64); /* start with inner pad */
|
||||
sha256_update(&context, text, text_len); /* then text of datagram */
|
||||
sha256_done(&context, &hmac->sha); /* finish up 1st pass */
|
||||
/*
|
||||
* perform outer MD5
|
||||
*/
|
||||
sha256_init(&context); /* init context for 2nd
|
||||
* pass */
|
||||
sha256_update(&context, k_opad, 64); /* start with outer pad */
|
||||
sha256_update(&context, &hmac->sha, 32); /* then results of 1st
|
||||
* hash */
|
||||
sha256_done(&context, &hmac->sha); /* finish up 2nd pass */
|
||||
}
|
||||
#endif
|
116
node_modules/lnsocket/hmac.h
generated
vendored
Normal file
116
node_modules/lnsocket/hmac.h
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
|
||||
#ifndef CCAN_CRYPTO_HMAC_SHA256_H
|
||||
#define CCAN_CRYPTO_HMAC_SHA256_H
|
||||
/* BSD-MIT */
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "sha256.h"
|
||||
#include "sha512.h"
|
||||
|
||||
/* Number of bytes per block. */
|
||||
#define HMAC_SHA256_BLOCKSIZE 64
|
||||
#define HMAC_SHA512_BLOCKSIZE 128
|
||||
|
||||
/**
|
||||
* struct hmac_sha256 - structure representing a completed HMAC.
|
||||
*/
|
||||
struct hmac_sha256 {
|
||||
struct sha256 sha;
|
||||
};
|
||||
|
||||
|
||||
struct hmac_sha512 {
|
||||
struct sha512 sha;
|
||||
};
|
||||
|
||||
/**
|
||||
* hmac_sha256 - return hmac of an object with a key.
|
||||
* @hmac: the hmac to fill in
|
||||
* @k: pointer to the key,
|
||||
* @ksize: the number of bytes pointed to by @k
|
||||
* @d: pointer to memory,
|
||||
* @dsize: the number of bytes pointed to by @d
|
||||
*/
|
||||
void hmac_sha256(struct hmac_sha256 *hmac,
|
||||
const void *k, size_t ksize,
|
||||
const void *d, size_t dsize);
|
||||
|
||||
void hmac_sha512(struct hmac_sha512 *hmac,
|
||||
const void *k, size_t ksize,
|
||||
const void *d, size_t dsize);
|
||||
|
||||
/**
|
||||
* struct hmac_sha256_ctx - structure to store running context for hmac_sha256
|
||||
*/
|
||||
struct hmac_sha256_ctx {
|
||||
struct sha256_ctx sha;
|
||||
uint64_t k_opad[HMAC_SHA256_BLOCKSIZE / sizeof(uint64_t)];
|
||||
};
|
||||
|
||||
|
||||
struct hmac_sha512_ctx {
|
||||
struct sha512_ctx sha;
|
||||
uint64_t k_opad[HMAC_SHA512_BLOCKSIZE / sizeof(uint64_t)];
|
||||
};
|
||||
|
||||
/**
|
||||
* hmac_sha256_init - initialize an HMAC_SHA256 context.
|
||||
* @ctx: the hmac_sha256_ctx to initialize
|
||||
* @k: pointer to the key,
|
||||
* @ksize: the number of bytes pointed to by @k
|
||||
*
|
||||
* This must be called before hmac_sha256_update or hmac_sha256_done.
|
||||
*
|
||||
* If it was already initialized, this forgets anything which was
|
||||
* hashed before.
|
||||
*
|
||||
* Example:
|
||||
* static void hmac_all(const char *key,
|
||||
* const char **arr, struct hmac_sha256 *hash)
|
||||
* {
|
||||
* size_t i;
|
||||
* struct hmac_sha256_ctx ctx;
|
||||
*
|
||||
* hmac_sha256_init(&ctx, key, strlen(key));
|
||||
* for (i = 0; arr[i]; i++)
|
||||
* hmac_sha256_update(&ctx, arr[i], strlen(arr[i]));
|
||||
* hmac_sha256_done(&ctx, hash);
|
||||
* }
|
||||
*/
|
||||
void hmac_sha256_init(struct hmac_sha256_ctx *ctx,
|
||||
const void *k, size_t ksize);
|
||||
|
||||
void hmac_sha512_init(struct hmac_sha512_ctx *ctx,
|
||||
const void *k, size_t ksize);
|
||||
|
||||
|
||||
/**
|
||||
* hmac_sha256_update - include some memory in the hash.
|
||||
* @ctx: the hmac_sha256_ctx to use
|
||||
* @p: pointer to memory,
|
||||
* @size: the number of bytes pointed to by @p
|
||||
*
|
||||
* You can call this multiple times to hash more data, before calling
|
||||
* hmac_sha256_done().
|
||||
*/
|
||||
void hmac_sha256_update(struct hmac_sha256_ctx *ctx,
|
||||
const void *p, size_t size);
|
||||
|
||||
void hmac_sha512_update(struct hmac_sha512_ctx *ctx,
|
||||
const void *p, size_t size);
|
||||
|
||||
/**
|
||||
* hmac_sha256_done - finish HMAC_SHA256 and return the hash
|
||||
* @ctx: the hmac_sha256_ctx to complete
|
||||
* @res: the hash to return.
|
||||
*
|
||||
* Note that @ctx is *destroyed* by this, and must be reinitialized.
|
||||
* To avoid that, pass a copy instead.
|
||||
*/
|
||||
void hmac_sha256_done(struct hmac_sha256_ctx *hmac_sha256,
|
||||
struct hmac_sha256 *res);
|
||||
|
||||
void hmac_sha512_done(struct hmac_sha512_ctx *hmac_sha256,
|
||||
struct hmac_sha512 *res);
|
||||
|
||||
#endif /* CCAN_CRYPTO_HMAC_SHA256_H */
|
11
node_modules/lnsocket/index.js
generated
vendored
Normal file
11
node_modules/lnsocket/index.js
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
const Module = require("./dist/node/lnsocket.js")
|
||||
const LNSocketReady = Module.lnsocket_init()
|
||||
|
||||
async function load_lnsocket(opts)
|
||||
{
|
||||
const LNSocket = await LNSocketReady
|
||||
return new LNSocket(opts)
|
||||
}
|
||||
|
||||
module.exports = load_lnsocket
|
114
node_modules/lnsocket/lnrpc.c
generated
vendored
Normal file
114
node_modules/lnsocket/lnrpc.c
generated
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lnsocket.h"
|
||||
#include "endian.h"
|
||||
#include "typedefs.h"
|
||||
#include "commando.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
|
||||
int usage()
|
||||
{
|
||||
printf("lnrpc <nodeid> <ip/hostname> <rune> <method> [params (json string)]\n\n");
|
||||
printf("currently supports commando for clightning, but potentially more rpc types in the future!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
static u8 msgbuf[4096];
|
||||
u8 *buf;
|
||||
struct lnsocket *ln;
|
||||
fd_set set;
|
||||
struct timeval timeout = {0};
|
||||
|
||||
char *timeout_str;
|
||||
u16 len, msgtype;
|
||||
int ok = 1;
|
||||
int socket, rv;
|
||||
int verbose = getenv("VERBOSE") != 0;
|
||||
//int verbose = 1;
|
||||
|
||||
timeout_str = getenv("LNRPC_TIMEOUT");
|
||||
int timeout_ms = timeout_str ? atoi(timeout_str) : 5000;
|
||||
|
||||
timeout.tv_sec = timeout_ms / 1000;
|
||||
timeout.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
|
||||
FD_ZERO(&set); /* clear the set */
|
||||
|
||||
if (argc < 5)
|
||||
return usage();
|
||||
|
||||
ln = lnsocket_create();
|
||||
assert(ln);
|
||||
|
||||
lnsocket_genkey(ln);
|
||||
|
||||
const char *nodeid = argv[1];
|
||||
const char *host = argv[2];
|
||||
const char *rune = argv[3];
|
||||
const char *method = argv[4];
|
||||
const char *params = argc < 7 ? argv[5] : NULL;
|
||||
|
||||
if (!(ok = lnsocket_connect(ln, nodeid, host)))
|
||||
goto done;
|
||||
|
||||
if (!(ok = lnsocket_fd(ln, &socket)))
|
||||
goto done;
|
||||
|
||||
FD_SET(socket, &set); /* add our file descriptor to the set */
|
||||
|
||||
if (!(ok = lnsocket_perform_init(ln)))
|
||||
goto done;
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "init success\n");
|
||||
|
||||
if (!(ok = len = commando_make_rpc_msg(method, params, rune, 1, msgbuf, sizeof(msgbuf))))
|
||||
goto done;
|
||||
|
||||
if (!(ok = lnsocket_write(ln, msgbuf, len)))
|
||||
goto done;
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "waiting for response...\n");
|
||||
|
||||
while (1) {
|
||||
rv = select(socket + 1, &set, NULL, NULL, &timeout);
|
||||
|
||||
if (rv == -1) {
|
||||
perror("select");
|
||||
ok = 0;
|
||||
goto done;
|
||||
} else if (rv == 0) {
|
||||
fprintf(stderr, "error: rpc request timeout\n");
|
||||
ok = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!(ok = lnsocket_recv(ln, &msgtype, &buf, &len)))
|
||||
goto done;
|
||||
|
||||
switch (msgtype) {
|
||||
case COMMANDO_REPLY_TERM:
|
||||
printf("%.*s\n", len - 8, buf + 8);
|
||||
goto done;
|
||||
case COMMANDO_REPLY_CONTINUES:
|
||||
printf("%.*s", len - 8, buf + 8);
|
||||
continue;
|
||||
default:
|
||||
// ignore extra interleaved messages which can happen
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
lnsocket_print_errors(ln);
|
||||
lnsocket_destroy(ln);
|
||||
return !ok;
|
||||
}
|
632
node_modules/lnsocket/lnsocket.c
generated
vendored
Normal file
632
node_modules/lnsocket/lnsocket.c
generated
vendored
Normal file
|
@ -0,0 +1,632 @@
|
|||
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <secp256k1.h>
|
||||
#include <secp256k1_ecdh.h>
|
||||
#include <sodium/crypto_aead_chacha20poly1305.h>
|
||||
#include <sodium/randombytes.h>
|
||||
|
||||
#include "handshake.h"
|
||||
#include "error.h"
|
||||
#include "crypto.h"
|
||||
#include "endian.h"
|
||||
#include "bigsize.h"
|
||||
#include "compiler.h"
|
||||
#include "lnsocket_internal.h"
|
||||
#include "lnsocket.h"
|
||||
|
||||
#define array_len(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
#define MSGBUF_MEM (65536*2)
|
||||
#define ERROR_MEM 4096
|
||||
#define DEFAULT_TIMEOUT 3000
|
||||
|
||||
int push_error(struct lnsocket *lnsocket, const char *err);
|
||||
|
||||
static int char_to_hex(unsigned char *val, char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') {
|
||||
*val = c - '0';
|
||||
return 1;
|
||||
}
|
||||
if (c >= 'a' && c <= 'f') {
|
||||
*val = c - 'a' + 10;
|
||||
return 1;
|
||||
}
|
||||
if (c >= 'A' && c <= 'F') {
|
||||
*val = c - 'A' + 10;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int hex_decode(const char *str, size_t slen, void *buf, size_t bufsize)
|
||||
{
|
||||
unsigned char v1, v2;
|
||||
unsigned char *p = buf;
|
||||
|
||||
while (slen > 1) {
|
||||
if (!char_to_hex(&v1, str[0]) || !char_to_hex(&v2, str[1]))
|
||||
return 0;
|
||||
if (!bufsize)
|
||||
return 0;
|
||||
*(p++) = (v1 << 4) | v2;
|
||||
str += 2;
|
||||
slen -= 2;
|
||||
bufsize--;
|
||||
}
|
||||
return slen == 0 && bufsize == 0;
|
||||
}
|
||||
|
||||
|
||||
int parse_node_id(const char *str, struct node_id *dest)
|
||||
{
|
||||
return hex_decode(str, strlen(str), dest->k, sizeof(*dest));
|
||||
}
|
||||
|
||||
int pubkey_from_node_id(secp256k1_context *secp, struct pubkey *key,
|
||||
const struct node_id *id)
|
||||
{
|
||||
return secp256k1_ec_pubkey_parse(secp, &key->pubkey,
|
||||
memcheck(id->k, sizeof(id->k)),
|
||||
sizeof(id->k));
|
||||
}
|
||||
|
||||
|
||||
static int read_all(int fd, void *data, size_t size)
|
||||
{
|
||||
while (size) {
|
||||
ssize_t done;
|
||||
|
||||
done = read(fd, data, size);
|
||||
if (done < 0 && errno == EINTR)
|
||||
continue;
|
||||
if (done <= 0)
|
||||
return 0;
|
||||
data = (char *)data + done;
|
||||
size -= done;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EXPORT lnsocket_make_default_initmsg(unsigned char *msgbuf, int buflen)
|
||||
{
|
||||
u8 global_features[2] = {0};
|
||||
u8 features[5] = {0};
|
||||
u16 len;
|
||||
|
||||
/*
|
||||
struct tlv network_tlv;
|
||||
u8 tlvbuf[1024];
|
||||
const u8 genesis_block[] = {
|
||||
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46,
|
||||
0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
|
||||
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const u8 *blockids[] = { genesis_block };
|
||||
|
||||
if (!lnsocket_make_network_tlv(tlvbuf, sizeof(tlvbuf), blockids, 1,
|
||||
&network_tlv))
|
||||
return 0;
|
||||
|
||||
|
||||
const struct tlv *init_tlvs[] = { &network_tlv } ;
|
||||
*/
|
||||
|
||||
const struct tlv *init_tlvs[] = { } ;
|
||||
|
||||
if (!lnsocket_make_init_msg(msgbuf, buflen,
|
||||
global_features, sizeof(global_features),
|
||||
features, sizeof(features),
|
||||
init_tlvs, 0,
|
||||
&len))
|
||||
return 0;
|
||||
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
/*
|
||||
static void print_hex(u8 *bytes, int len) {
|
||||
int i;
|
||||
for (i = 0; i < len; ++i) {
|
||||
printf("%02x", bytes[i]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
int lnsocket_perform_init(struct lnsocket *ln)
|
||||
{
|
||||
u8 msgbuf[1024];
|
||||
u16 len;
|
||||
u8 *buf;
|
||||
|
||||
// read the init message from the other side and ignore it
|
||||
if (!lnsocket_read(ln, &buf, &len))
|
||||
return 0;
|
||||
|
||||
if (!(len = lnsocket_make_default_initmsg(msgbuf, sizeof(msgbuf))))
|
||||
return 0;
|
||||
|
||||
if (!lnsocket_write(ln, msgbuf, len))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// simple helper that pushes a message type and payload
|
||||
int lnsocket_send(struct lnsocket *ln, unsigned short msg_type, const unsigned char *payload, unsigned short payload_len)
|
||||
{
|
||||
reset_cursor(&ln->msgbuf);
|
||||
|
||||
if (!cursor_push_u16(&ln->msgbuf, msg_type))
|
||||
return note_error(&ln->errs, "could not write type to msgbuf?");
|
||||
|
||||
if (!cursor_push(&ln->msgbuf, payload, payload_len))
|
||||
return note_error(&ln->errs, "payload too big");
|
||||
|
||||
return lnsocket_write(ln, ln->msgbuf.start, ln->msgbuf.p - ln->msgbuf.start);
|
||||
}
|
||||
|
||||
// simple helper that receives a message type and payload
|
||||
int lnsocket_recv(struct lnsocket *ln, u16 *msg_type, unsigned char **payload, u16 *payload_len)
|
||||
{
|
||||
struct cursor cur;
|
||||
u8 *msg;
|
||||
u16 msglen;
|
||||
|
||||
if (!lnsocket_read(ln, &msg, &msglen))
|
||||
return 0;
|
||||
|
||||
make_cursor(msg, msg + msglen, &cur);
|
||||
|
||||
if (!cursor_pull_u16(&cur, msg_type))
|
||||
return note_error(&ln->errs, "could not read msgtype");
|
||||
|
||||
*payload_len = msglen - 2;
|
||||
*payload = cur.p;
|
||||
|
||||
if (*payload + *payload_len > cur.end)
|
||||
return note_error(&ln->errs, "recv buffer overflow?");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EXPORT lnsocket_decrypt(struct lnsocket *ln, unsigned char *packet, int size)
|
||||
{
|
||||
struct cursor enc, dec;
|
||||
|
||||
make_cursor(packet, packet + size, &enc);
|
||||
reset_cursor(&ln->msgbuf);
|
||||
if (!cursor_slice(&ln->msgbuf, &dec, size - 16))
|
||||
return note_error(&ln->errs, "out of memory: %d + %d = %d > %d",
|
||||
ln->msgbuf.end - ln->msgbuf.p, size,
|
||||
ln->msgbuf.end - ln->msgbuf.p + size,
|
||||
MSGBUF_MEM
|
||||
);
|
||||
|
||||
if (!cryptomsg_decrypt_body(&ln->crypto_state,
|
||||
enc.start, enc.end - enc.start,
|
||||
dec.start, dec.end - dec.start))
|
||||
return note_error(&ln->errs, "error decrypting body");
|
||||
|
||||
return dec.end - dec.start;
|
||||
}
|
||||
|
||||
// this is used in js
|
||||
int EXPORT lnsocket_decrypt_header(struct lnsocket *ln, unsigned char *hdr)
|
||||
{
|
||||
u16 size = 0;
|
||||
if (!cryptomsg_decrypt_header(&ln->crypto_state, hdr, &size))
|
||||
return note_error(&ln->errs,
|
||||
"Failed hdr decrypt with rn=%"PRIu64,
|
||||
ln->crypto_state.rn-1);
|
||||
return size;
|
||||
}
|
||||
|
||||
int lnsocket_read(struct lnsocket *ln, unsigned char **buf, unsigned short *len)
|
||||
{
|
||||
struct cursor enc, dec;
|
||||
u8 hdr[18];
|
||||
u16 size;
|
||||
|
||||
reset_cursor(&ln->errs.cur);
|
||||
reset_cursor(&ln->msgbuf);
|
||||
|
||||
if (!read_all(ln->socket, hdr, sizeof(hdr)))
|
||||
return note_error(&ln->errs,"Failed reading header: %s",
|
||||
strerror(errno));
|
||||
|
||||
if (!cryptomsg_decrypt_header(&ln->crypto_state, hdr, &size))
|
||||
return note_error(&ln->errs,
|
||||
"Failed hdr decrypt with rn=%"PRIu64,
|
||||
ln->crypto_state.rn-1);
|
||||
|
||||
if (!cursor_slice(&ln->msgbuf, &enc, size + 16))
|
||||
return note_error(&ln->errs, "out of memory");
|
||||
|
||||
if (!cursor_slice(&ln->msgbuf, &dec, size))
|
||||
return note_error(&ln->errs, "out of memory: %d + %d = %d > %d",
|
||||
ln->msgbuf.end - ln->msgbuf.p, size,
|
||||
ln->msgbuf.end - ln->msgbuf.p + size,
|
||||
MSGBUF_MEM
|
||||
);
|
||||
|
||||
if (!read_all(ln->socket, enc.p, enc.end - enc.start))
|
||||
return note_error(&ln->errs, "Failed reading body: %s",
|
||||
strerror(errno));
|
||||
|
||||
if (!cryptomsg_decrypt_body(&ln->crypto_state,
|
||||
enc.start, enc.end - enc.start,
|
||||
dec.start, dec.end - dec.start))
|
||||
return note_error(&ln->errs, "error decrypting body");
|
||||
|
||||
*buf = dec.start;
|
||||
*len = dec.end - dec.start;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int highest_byte(unsigned char *buf, int buflen)
|
||||
{
|
||||
int i, highest;
|
||||
for (i = 0, highest = 0; i < buflen; i++) {
|
||||
if (buf[i] != 0)
|
||||
highest = i;
|
||||
}
|
||||
return highest;
|
||||
}
|
||||
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
int lnsocket_set_feature_bit(unsigned char *buf, int buflen, int *newlen, unsigned int bit)
|
||||
{
|
||||
if (newlen == NULL)
|
||||
return 0;
|
||||
|
||||
if (bit / 8 >= buflen)
|
||||
return 0;
|
||||
|
||||
*newlen = max(highest_byte(buf, buflen), (bit / 8) + 1);
|
||||
buf[*newlen - 1 - bit / 8] |= (1 << (bit % 8));
|
||||
|
||||
return 1;
|
||||
}
|
||||
#undef max
|
||||
|
||||
int cursor_push_tlv(struct cursor *cur, const struct tlv *tlv)
|
||||
{
|
||||
/* BOLT #1:
|
||||
*
|
||||
* The sending node:
|
||||
...
|
||||
* - MUST minimally encode `type` and `length`.
|
||||
*/
|
||||
return cursor_push_bigsize(cur, tlv->type) &&
|
||||
cursor_push_bigsize(cur, tlv->length) &&
|
||||
cursor_push(cur, tlv->value, tlv->length);
|
||||
}
|
||||
|
||||
int cursor_push_tlvs(struct cursor *cur, const struct tlv **tlvs, int n_tlvs)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n_tlvs; i++) {
|
||||
if (!cursor_push_tlv(cur, tlvs[i]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lnsocket_make_network_tlv(unsigned char *buf, int buflen,
|
||||
const unsigned char **blockids, int num_blockids,
|
||||
struct tlv *tlv_out)
|
||||
{
|
||||
struct cursor cur;
|
||||
|
||||
if (!tlv_out)
|
||||
return 0;
|
||||
|
||||
tlv_out->type = 1;
|
||||
tlv_out->value = buf;
|
||||
|
||||
make_cursor(buf, buf + buflen, &cur);
|
||||
|
||||
for (size_t i = 0; i < num_blockids; i++) {
|
||||
if (!cursor_push(&cur, memcheck(blockids[i], 32), 32))
|
||||
return 0;
|
||||
}
|
||||
|
||||
tlv_out->length = cur.p - cur.start;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lnsocket_make_ping_msg(unsigned char *buf, int buflen, u16 num_pong_bytes, u16 ignored_bytes)
|
||||
{
|
||||
struct cursor msg;
|
||||
int i;
|
||||
|
||||
make_cursor(buf, buf + buflen, &msg);
|
||||
|
||||
if (!cursor_push_u16(&msg, WIRE_PING))
|
||||
return 0;
|
||||
if (!cursor_push_u16(&msg, num_pong_bytes))
|
||||
return 0;
|
||||
if (!cursor_push_u16(&msg, ignored_bytes))
|
||||
return 0;
|
||||
for (i = 0; i < ignored_bytes; i++) {
|
||||
if (!cursor_push_byte(&msg, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return msg.p - msg.start;
|
||||
}
|
||||
|
||||
int lnsocket_make_init_msg(unsigned char *buf, int buflen,
|
||||
const unsigned char *globalfeatures, u16 gflen,
|
||||
const unsigned char *features, u16 flen,
|
||||
const struct tlv **tlvs,
|
||||
unsigned short num_tlvs,
|
||||
unsigned short *outlen)
|
||||
{
|
||||
struct cursor msg;
|
||||
|
||||
make_cursor(buf, buf + buflen, &msg);
|
||||
|
||||
if (!cursor_push_u16(&msg, WIRE_INIT))
|
||||
return 0;
|
||||
|
||||
if (!cursor_push_u16(&msg, gflen))
|
||||
return 0;
|
||||
|
||||
if (!cursor_push(&msg, globalfeatures, gflen))
|
||||
return 0;
|
||||
|
||||
if (!cursor_push_u16(&msg, flen))
|
||||
return 0;
|
||||
|
||||
if (!cursor_push(&msg, features, flen))
|
||||
return 0;
|
||||
|
||||
if (!cursor_push_tlvs(&msg, tlvs, num_tlvs))
|
||||
return 0;
|
||||
|
||||
*outlen = msg.p - msg.start;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char* EXPORT lnsocket_msgbuf(struct lnsocket *ln)
|
||||
{
|
||||
return ln->msgbuf.start;
|
||||
}
|
||||
|
||||
int EXPORT lnsocket_encrypt(struct lnsocket *ln, const u8 *msg, unsigned short msglen)
|
||||
{
|
||||
ssize_t outcap;
|
||||
size_t outlen;
|
||||
|
||||
// this is just temporary so we don't need to move the memory cursor
|
||||
reset_cursor(&ln->msgbuf);
|
||||
|
||||
u8 *out = ln->msgbuf.start;
|
||||
outcap = ln->msgbuf.end - ln->msgbuf.start;
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
if (!ln->socket)
|
||||
return note_error(&ln->errs, "not connected");
|
||||
#endif
|
||||
|
||||
if (outcap <= 0)
|
||||
return note_error(&ln->errs, "out of memory");
|
||||
|
||||
if (!cryptomsg_encrypt_msg(&ln->crypto_state, msg, msglen, out, &outlen, (size_t)outcap))
|
||||
return note_error(&ln->errs, "encrypt message failed, out of memory");
|
||||
|
||||
return outlen;
|
||||
}
|
||||
|
||||
int lnsocket_write(struct lnsocket *ln, const u8 *msg, unsigned short msglen)
|
||||
{
|
||||
ssize_t writelen, outlen;
|
||||
u8 *out = ln->msgbuf.start;
|
||||
|
||||
if (!(outlen = lnsocket_encrypt(ln, msg, msglen)))
|
||||
return 0;
|
||||
|
||||
if ((writelen = write(ln->socket, out, outlen)) != outlen)
|
||||
return note_error(&ln->errs,
|
||||
"write failed. wrote %ld bytes, expected %ld %s",
|
||||
writelen, outlen,
|
||||
writelen < 0 ? strerror(errno) : "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct lnsocket *lnsocket_create()
|
||||
{
|
||||
struct cursor mem;
|
||||
int memory = MSGBUF_MEM + ERROR_MEM + sizeof(struct lnsocket);
|
||||
|
||||
void *arena = malloc(memory);
|
||||
|
||||
if (!arena)
|
||||
return NULL;
|
||||
|
||||
make_cursor(arena, arena + memory, &mem);
|
||||
struct lnsocket *lnsocket = cursor_alloc(&mem, sizeof(*lnsocket));
|
||||
|
||||
if (!lnsocket)
|
||||
return NULL;
|
||||
|
||||
lnsocket->secp = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY |
|
||||
SECP256K1_CONTEXT_SIGN);
|
||||
|
||||
if (!cursor_slice(&mem, &lnsocket->msgbuf, MSGBUF_MEM))
|
||||
return NULL;
|
||||
|
||||
if (!cursor_slice(&mem, &lnsocket->errs.cur, ERROR_MEM))
|
||||
return NULL;
|
||||
|
||||
lnsocket->errs.enabled = 1;
|
||||
|
||||
lnsocket->mem = mem;
|
||||
return lnsocket;
|
||||
}
|
||||
|
||||
void lnsocket_destroy(struct lnsocket *lnsocket)
|
||||
{
|
||||
if (!lnsocket)
|
||||
return;
|
||||
|
||||
secp256k1_context_destroy(lnsocket->secp);
|
||||
free(lnsocket->mem.start);
|
||||
}
|
||||
|
||||
int is_zero(void *vp, int size)
|
||||
{
|
||||
u8 *p = (u8*)vp;
|
||||
const u8 *start = p;
|
||||
|
||||
for (; p < start+size; p++) {
|
||||
if (*p != 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int io_fd_block(int fd, int block)
|
||||
{
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
|
||||
if (flags == -1)
|
||||
return 0;
|
||||
|
||||
if (block)
|
||||
flags &= ~O_NONBLOCK;
|
||||
else
|
||||
flags |= O_NONBLOCK;
|
||||
|
||||
return fcntl(fd, F_SETFL, flags) != -1;
|
||||
}
|
||||
|
||||
const char *parse_port(char *host)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
len = strlen(host);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (host[i] == ':') {
|
||||
host[i] = 0;
|
||||
return &host[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int lnsocket_connect_with(struct lnsocket *ln, const char *node_id, const char *host, int timeout_ms)
|
||||
{
|
||||
int ret;
|
||||
struct addrinfo *addrs = NULL;
|
||||
struct pubkey their_id;
|
||||
struct node_id their_node_id;
|
||||
struct timeval timeout = {0};
|
||||
char onlyhost[strlen(host)+1];
|
||||
strncpy(onlyhost, host, sizeof(onlyhost));
|
||||
fd_set set;
|
||||
|
||||
timeout.tv_sec = timeout_ms / 1000;
|
||||
timeout.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
|
||||
FD_ZERO(&set); /* clear the set */
|
||||
|
||||
if (is_zero(&ln->key, sizeof(ln->key)))
|
||||
return note_error(&ln->errs, "key not initialized, use lnsocket_set_key() or lnsocket_genkey()");
|
||||
|
||||
// convert node_id string to bytes
|
||||
if (!parse_node_id(node_id, &their_node_id))
|
||||
return note_error(&ln->errs, "failed to parse node id");
|
||||
|
||||
// encode node_id bytes to secp pubkey
|
||||
if (!pubkey_from_node_id(ln->secp, &their_id, &their_node_id))
|
||||
return note_error(&ln->errs, "failed to convert node_id to pubkey");
|
||||
|
||||
// parse ip into addrinfo
|
||||
const char *port = parse_port(onlyhost);
|
||||
if ((ret = getaddrinfo(onlyhost, port ? port : "9735", NULL, &addrs)) || !addrs)
|
||||
return note_error(&ln->errs, "%s", gai_strerror(ret));
|
||||
|
||||
// create our network socket for comms
|
||||
if (!(ln->socket = socket(AF_INET, SOCK_STREAM, 0)))
|
||||
return note_error(&ln->errs, "creating socket failed");
|
||||
|
||||
FD_SET(ln->socket, &set); /* add our file descriptor to the set */
|
||||
|
||||
if (!io_fd_block(ln->socket, 0))
|
||||
return note_error(&ln->errs, "failed setting socket to non-blocking");
|
||||
|
||||
// connect to the node!
|
||||
connect(ln->socket, addrs->ai_addr, addrs->ai_addrlen);
|
||||
|
||||
if (!io_fd_block(ln->socket, 1))
|
||||
return note_error(&ln->errs, "failed setting socket to blocking");
|
||||
|
||||
ret = select(ln->socket + 1, NULL, &set, NULL, &timeout);
|
||||
if (ret == -1) {
|
||||
return note_error(&ln->errs, "select error");
|
||||
} else if (ret == 0) {
|
||||
return note_error(&ln->errs, "connection timeout");
|
||||
}
|
||||
|
||||
// prepare some data for ACT1
|
||||
new_handshake(ln->secp, &ln->handshake, &their_id);
|
||||
|
||||
ln->handshake.side = INITIATOR;
|
||||
ln->handshake.their_id = their_id;
|
||||
|
||||
// let's do this!
|
||||
return act_one_initiator(ln);
|
||||
}
|
||||
|
||||
int lnsocket_connect(struct lnsocket *ln, const char *node_id, const char *host)
|
||||
{
|
||||
return lnsocket_connect_with(ln, node_id, host, DEFAULT_TIMEOUT);
|
||||
}
|
||||
|
||||
int lnsocket_fd(struct lnsocket *ln, int *fd)
|
||||
{
|
||||
*fd = ln->socket;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void * lnsocket_secp(struct lnsocket *ln)
|
||||
{
|
||||
return ln->secp;
|
||||
}
|
||||
|
||||
void lnsocket_genkey(struct lnsocket *ln)
|
||||
{
|
||||
ln->key = generate_key(ln->secp);
|
||||
}
|
||||
|
||||
void lnsocket_print_errors(struct lnsocket *ln)
|
||||
{
|
||||
print_error_backtrace(&ln->errs);
|
||||
}
|
||||
|
||||
|
95
node_modules/lnsocket/lnsocket.h
generated
vendored
Normal file
95
node_modules/lnsocket/lnsocket.h
generated
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
#ifndef LNSOCKET_H
|
||||
#define LNSOCKET_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct lnsocket;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#define EXPORT EMSCRIPTEN_KEEPALIVE
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
enum peer_wire {
|
||||
WIRE_INIT = 16,
|
||||
WIRE_ERROR = 17,
|
||||
WIRE_WARNING = 1,
|
||||
WIRE_PING = 18,
|
||||
WIRE_PONG = 19,
|
||||
WIRE_TX_ADD_INPUT = 66,
|
||||
WIRE_TX_ADD_OUTPUT = 67,
|
||||
WIRE_TX_REMOVE_INPUT = 68,
|
||||
WIRE_TX_REMOVE_OUTPUT = 69,
|
||||
WIRE_TX_COMPLETE = 70,
|
||||
WIRE_TX_SIGNATURES = 71,
|
||||
WIRE_OPEN_CHANNEL = 32,
|
||||
WIRE_ACCEPT_CHANNEL = 33,
|
||||
WIRE_FUNDING_CREATED = 34,
|
||||
WIRE_FUNDING_SIGNED = 35,
|
||||
WIRE_FUNDING_LOCKED = 36,
|
||||
WIRE_OPEN_CHANNEL2 = 64,
|
||||
WIRE_ACCEPT_CHANNEL2 = 65,
|
||||
WIRE_INIT_RBF = 72,
|
||||
WIRE_ACK_RBF = 73,
|
||||
WIRE_SHUTDOWN = 38,
|
||||
WIRE_CLOSING_SIGNED = 39,
|
||||
WIRE_UPDATE_ADD_HTLC = 128,
|
||||
WIRE_UPDATE_FULFILL_HTLC = 130,
|
||||
WIRE_UPDATE_FAIL_HTLC = 131,
|
||||
WIRE_UPDATE_FAIL_MALFORMED_HTLC = 135,
|
||||
WIRE_COMMITMENT_SIGNED = 132,
|
||||
WIRE_REVOKE_AND_ACK = 133,
|
||||
WIRE_UPDATE_FEE = 134,
|
||||
WIRE_UPDATE_BLOCKHEIGHT = 137,
|
||||
WIRE_CHANNEL_REESTABLISH = 136,
|
||||
WIRE_ANNOUNCEMENT_SIGNATURES = 259,
|
||||
WIRE_CHANNEL_ANNOUNCEMENT = 256,
|
||||
WIRE_NODE_ANNOUNCEMENT = 257,
|
||||
WIRE_CHANNEL_UPDATE = 258,
|
||||
WIRE_QUERY_SHORT_CHANNEL_IDS = 261,
|
||||
WIRE_REPLY_SHORT_CHANNEL_IDS_END = 262,
|
||||
WIRE_QUERY_CHANNEL_RANGE = 263,
|
||||
WIRE_REPLY_CHANNEL_RANGE = 264,
|
||||
WIRE_GOSSIP_TIMESTAMP_FILTER = 265,
|
||||
WIRE_OBS2_ONION_MESSAGE = 387,
|
||||
WIRE_ONION_MESSAGE = 513,
|
||||
};
|
||||
|
||||
/* A single TLV field, consisting of the data and its associated metadata. */
|
||||
struct tlv {
|
||||
uint64_t type;
|
||||
size_t length;
|
||||
unsigned char *value;
|
||||
};
|
||||
|
||||
struct lnsocket EXPORT *lnsocket_create();
|
||||
|
||||
/* messages */
|
||||
|
||||
int lnsocket_make_network_tlv(unsigned char *buf, int buflen, const unsigned char **blockids, int num_blockids, struct tlv *tlv_out);
|
||||
int EXPORT lnsocket_make_ping_msg(unsigned char *buf, int buflen, unsigned short num_pong_bytes, unsigned short ignored_bytes);
|
||||
int lnsocket_make_init_msg(unsigned char *buf, int buflen, const unsigned char *globalfeatures, unsigned short gflen, const unsigned char *features, unsigned short flen, const struct tlv **tlvs, unsigned short num_tlvs, unsigned short *outlen);
|
||||
|
||||
int lnsocket_perform_init(struct lnsocket *ln);
|
||||
|
||||
int lnsocket_connect(struct lnsocket *, const char *node_id, const char *host);
|
||||
|
||||
int lnsocket_fd(struct lnsocket *, int *fd);
|
||||
int lnsocket_write(struct lnsocket *, const unsigned char *msg, unsigned short msg_len);
|
||||
int lnsocket_read(struct lnsocket *, unsigned char **buf, unsigned short *len);
|
||||
|
||||
int lnsocket_send(struct lnsocket *, unsigned short msg_type, const unsigned char *payload, unsigned short payload_len);
|
||||
int lnsocket_recv(struct lnsocket *, unsigned short *msg_type, unsigned char **payload, unsigned short *payload_len);
|
||||
|
||||
void* EXPORT lnsocket_secp(struct lnsocket *);
|
||||
void EXPORT lnsocket_genkey(struct lnsocket *);
|
||||
void EXPORT lnsocket_destroy(struct lnsocket *);
|
||||
void EXPORT lnsocket_print_errors(struct lnsocket *);
|
||||
int EXPORT lnsocket_make_default_initmsg(unsigned char *msgbuf, int buflen);
|
||||
int EXPORT lnsocket_encrypt(struct lnsocket *ln, const unsigned char *msg, unsigned short msglen);
|
||||
int EXPORT lnsocket_decrypt_header(struct lnsocket *ln, unsigned char *hdr);
|
||||
|
||||
#endif /* LNSOCKET_H */
|
26
node_modules/lnsocket/lnsocket_internal.h
generated
vendored
Normal file
26
node_modules/lnsocket/lnsocket_internal.h
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef LNSOCKET_INTERNAL_H
|
||||
#define LNSOCKET_INTERNAL_H
|
||||
|
||||
#include "crypto.h"
|
||||
#include "error.h"
|
||||
#include "handshake.h"
|
||||
|
||||
struct lnsocket {
|
||||
const char *errors[8];
|
||||
struct cursor mem;
|
||||
struct cursor msgbuf;
|
||||
struct errors errs;
|
||||
int num_errors;
|
||||
int socket;
|
||||
struct keypair key;
|
||||
struct pubkey responder_id;
|
||||
struct handshake handshake;
|
||||
struct crypto_state crypto_state;
|
||||
secp256k1_context *secp;
|
||||
};
|
||||
|
||||
int parse_node_id(const char *str, struct node_id *dest);
|
||||
int pubkey_from_node_id(secp256k1_context *secp, struct pubkey *key, const struct node_id *id);
|
||||
int is_zero(void *vp, int size);
|
||||
|
||||
#endif /* LNSOCKET_INTERNAL_H */
|
370
node_modules/lnsocket/lnsocket_lib.js
generated
vendored
Normal file
370
node_modules/lnsocket/lnsocket_lib.js
generated
vendored
Normal file
|
@ -0,0 +1,370 @@
|
|||
|
||||
async function lnsocket_init() {
|
||||
const module = await Module()
|
||||
|
||||
function SocketImpl(host) {
|
||||
if (!(this instanceof SocketImpl))
|
||||
return new SocketImpl(host)
|
||||
|
||||
if (typeof WebSocket !== 'undefined') {
|
||||
console.log("WebSocket", typeof WebSocket)
|
||||
const ok = host.startsWith("ws://") || host.startsWith("wss://")
|
||||
if (!ok)
|
||||
throw new Error("host must start with ws:// or wss://")
|
||||
const ws = new WebSocket(host)
|
||||
ws.ondata = function(fn) {
|
||||
ws.onmessage = (v) => {
|
||||
const data = v.data.arrayBuffer()
|
||||
fn(data)
|
||||
}
|
||||
}
|
||||
return ws
|
||||
}
|
||||
|
||||
//
|
||||
// we're in nodejs
|
||||
//
|
||||
const net = require('net')
|
||||
let [hostname,port] = host.split(":")
|
||||
port = +port || 9735
|
||||
const socket = net.createConnection(port, hostname, () => {
|
||||
socket.emit("open")
|
||||
})
|
||||
socket.addEventListener = socket.on.bind(socket)
|
||||
|
||||
if (socket.onmessage)
|
||||
throw new Error("socket already has onmessage?")
|
||||
|
||||
socket.ondata = (fn) => {
|
||||
socket.on('data', fn)
|
||||
}
|
||||
|
||||
socket.close = () => {
|
||||
socket.destroy()
|
||||
}
|
||||
|
||||
if (socket.send)
|
||||
throw new Error("socket already has send?")
|
||||
|
||||
socket.send = function socket_send(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
socket.write(data, resolve)
|
||||
});
|
||||
}
|
||||
|
||||
return socket
|
||||
}
|
||||
|
||||
const ACT_ONE_SIZE = 50
|
||||
const ACT_TWO_SIZE = 50
|
||||
const ACT_THREE_SIZE = 66
|
||||
const DEFAULT_TIMEOUT = 15000
|
||||
|
||||
const COMMANDO_REPLY_CONTINUES = 0x594b
|
||||
const COMMANDO_REPLY_TERM = 0x594d
|
||||
|
||||
const lnsocket_create = module.cwrap("lnsocket_create", "number")
|
||||
const lnsocket_destroy = module.cwrap("lnsocket_destroy", "number")
|
||||
const lnsocket_encrypt = module.cwrap("lnsocket_encrypt", "number", ["int", "array", "int", "int"])
|
||||
const lnsocket_decrypt = module.cwrap("lnsocket_decrypt", "number", ["int", "array", "int"])
|
||||
const lnsocket_decrypt_header = module.cwrap("lnsocket_decrypt_header", "number", ["number", "array"])
|
||||
const lnsocket_msgbuf = module.cwrap("lnsocket_msgbuf", "number", ["int"])
|
||||
const lnsocket_act_one = module.cwrap("lnsocket_act_one", "number", ["number", "string"])
|
||||
const lnsocket_act_two = module.cwrap("lnsocket_act_two", "number", ["number", "array"])
|
||||
const lnsocket_print_errors = module.cwrap("lnsocket_print_errors", "int")
|
||||
const lnsocket_genkey = module.cwrap("lnsocket_genkey", "int")
|
||||
const lnsocket_make_default_initmsg = module.cwrap("lnsocket_make_default_initmsg", "int", ["int", "int"])
|
||||
const lnsocket_make_ping_msg = module.cwrap("lnsocket_make_ping_msg", "int", ["int", "int", "int", "int"])
|
||||
const commando_make_rpc_msg = module.cwrap("commando_make_rpc_msg", "int", ["string", "string", "string", "number", "int", "int"])
|
||||
|
||||
function concat_u8_arrays(arrays) {
|
||||
// sum of individual array lengths
|
||||
let totalLength = arrays.reduce((acc, value) =>
|
||||
acc + (value.length || value.byteLength)
|
||||
, 0);
|
||||
|
||||
if (!arrays.length) return null;
|
||||
|
||||
let result = new Uint8Array(totalLength);
|
||||
|
||||
let length = 0;
|
||||
for (let array of arrays) {
|
||||
if (array instanceof ArrayBuffer)
|
||||
result.set(new Uint8Array(array), length);
|
||||
else
|
||||
result.set(array, length);
|
||||
|
||||
length += (array.length || array.byteLength);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function parse_msgtype(buf) {
|
||||
return buf[0] << 8 | buf[1]
|
||||
}
|
||||
|
||||
function wasm_mem(ptr, size) {
|
||||
return new Uint8Array(module.HEAPU8.buffer, ptr, size);
|
||||
}
|
||||
|
||||
function LNSocket(opts) {
|
||||
if (!(this instanceof LNSocket))
|
||||
return new LNSocket(opts)
|
||||
|
||||
this.opts = opts || {
|
||||
timeout: DEFAULT_TIMEOUT
|
||||
}
|
||||
this.queue = []
|
||||
this.ln = lnsocket_create()
|
||||
}
|
||||
|
||||
LNSocket.prototype.queue_recv = function() {
|
||||
let self = this
|
||||
return new Promise((resolve, reject) => {
|
||||
const checker = setInterval(() => {
|
||||
const val = self.queue.shift()
|
||||
if (val) {
|
||||
clearInterval(checker)
|
||||
resolve(val)
|
||||
} else if (!self.connected) {
|
||||
clearInterval(checker)
|
||||
reject()
|
||||
}
|
||||
}, 5);
|
||||
})
|
||||
}
|
||||
|
||||
LNSocket.prototype.print_errors = function _lnsocket_print_errors() {
|
||||
lnsocket_print_errors(this.ln)
|
||||
}
|
||||
|
||||
LNSocket.prototype.genkey = function _lnsocket_genkey() {
|
||||
lnsocket_genkey(this.ln)
|
||||
}
|
||||
|
||||
LNSocket.prototype.act_one_data = function _lnsocket_act_one(node_id) {
|
||||
const act_one_ptr = lnsocket_act_one(this.ln, node_id)
|
||||
if (act_one_ptr === 0)
|
||||
return null
|
||||
return wasm_mem(act_one_ptr, ACT_ONE_SIZE)
|
||||
}
|
||||
|
||||
LNSocket.prototype.act_two = function _lnsocket_act_two(act2) {
|
||||
const act_three_ptr = lnsocket_act_two(this.ln, new Uint8Array(act2))
|
||||
if (act_three_ptr === 0) {
|
||||
this.print_errors()
|
||||
return null
|
||||
}
|
||||
return wasm_mem(act_three_ptr, ACT_THREE_SIZE)
|
||||
}
|
||||
|
||||
LNSocket.prototype.connect = async function lnsocket_connect(node_id, host) {
|
||||
await handle_connect(this, node_id, host)
|
||||
|
||||
const act1 = this.act_one_data(node_id)
|
||||
this.ws.send(act1)
|
||||
const act2 = await this.read_all(ACT_TWO_SIZE)
|
||||
if (act2.length != ACT_TWO_SIZE) {
|
||||
throw new Error(`expected act2 to be ${ACT_TWO_SIZE} long, got ${act2.length}`)
|
||||
}
|
||||
const act3 = this.act_two(act2)
|
||||
this.ws.send(act3)
|
||||
}
|
||||
|
||||
LNSocket.prototype.connect_and_init = async function _connect_and_init(node_id, host) {
|
||||
await this.connect(node_id, host)
|
||||
await this.perform_init()
|
||||
}
|
||||
|
||||
LNSocket.prototype.read_all = async function read_all(n) {
|
||||
let count = 0
|
||||
let chunks = []
|
||||
if (!this.connected)
|
||||
throw new Error("read_all: not connected")
|
||||
while (true) {
|
||||
let res = await this.queue_recv()
|
||||
|
||||
const remaining = n - count
|
||||
|
||||
if (res.byteLength > remaining) {
|
||||
chunks.push(res.slice(0, remaining))
|
||||
this.queue.unshift(res.slice(remaining))
|
||||
break
|
||||
} else if (res.byteLength === remaining) {
|
||||
chunks.push(res)
|
||||
break
|
||||
}
|
||||
|
||||
chunks.push(res)
|
||||
count += res.byteLength
|
||||
}
|
||||
|
||||
return concat_u8_arrays(chunks)
|
||||
}
|
||||
|
||||
LNSocket.prototype.read_header = async function read_header() {
|
||||
const header = await this.read_all(18)
|
||||
if (header.length != 18)
|
||||
throw new Error("Failed to read header")
|
||||
return lnsocket_decrypt_header(this.ln, header)
|
||||
}
|
||||
|
||||
LNSocket.prototype.rpc = async function lnsocket_rpc(opts) {
|
||||
const msg = this.make_commando_msg(opts)
|
||||
this.write(msg)
|
||||
const res = await this.read_all_rpc()
|
||||
return JSON.parse(res)
|
||||
}
|
||||
|
||||
LNSocket.prototype.recv = async function lnsocket_recv() {
|
||||
const msg = await this.read()
|
||||
const msgtype = parse_msgtype(msg.slice(0,2))
|
||||
const res = [msgtype, msg.slice(2)]
|
||||
return res
|
||||
}
|
||||
|
||||
LNSocket.prototype.read_all_rpc = async function read_all_rpc() {
|
||||
let chunks = []
|
||||
while (true) {
|
||||
const [typ, msg] = await this.recv()
|
||||
switch (typ) {
|
||||
case COMMANDO_REPLY_TERM:
|
||||
chunks.push(msg.slice(8))
|
||||
return new TextDecoder().decode(concat_u8_arrays(chunks));
|
||||
case COMMANDO_REPLY_CONTINUES:
|
||||
chunks.push(msg.slice(8))
|
||||
break
|
||||
default:
|
||||
console.log("got unknown type", typ)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LNSocket.prototype.make_commando_msg = function _lnsocket_make_commando_msg(opts) {
|
||||
const buflen = 4096
|
||||
let len = 0;
|
||||
const buf = module._malloc(buflen);
|
||||
module.HEAPU8.set(Uint8Array, buf);
|
||||
|
||||
const params = JSON.stringify(opts.params||{})
|
||||
if (!(len = commando_make_rpc_msg(opts.method, params, opts.rune,
|
||||
0, buf, buflen))) {
|
||||
throw new Error("couldn't make commando msg");
|
||||
}
|
||||
|
||||
const dat = wasm_mem(buf, len)
|
||||
module._free(buf);
|
||||
return dat
|
||||
}
|
||||
|
||||
LNSocket.prototype.make_ping_msg = function _lnsocket_make_ping_msg(num_pong_bytes=1, ignored_bytes=1) {
|
||||
const buflen = 32
|
||||
let len = 0;
|
||||
const buf = module._malloc(buflen);
|
||||
module.HEAPU8.set(Uint8Array, buf);
|
||||
|
||||
if (!(len = lnsocket_make_ping_msg(buf, buflen, num_pong_bytes, ignored_bytes)))
|
||||
throw new Error("couldn't make ping msg");
|
||||
|
||||
const dat = wasm_mem(buf, len)
|
||||
module._free(buf);
|
||||
return dat
|
||||
}
|
||||
|
||||
LNSocket.prototype.encrypt = function _lnsocket_encrypt(dat) {
|
||||
const len = lnsocket_encrypt(this.ln, dat, dat.length)
|
||||
if (len === 0) {
|
||||
this.print_errors()
|
||||
throw new Error("encrypt error")
|
||||
}
|
||||
const enc = wasm_mem(lnsocket_msgbuf(this.ln), len)
|
||||
return enc
|
||||
}
|
||||
|
||||
LNSocket.prototype.decrypt = function _lnsocket_decrypt(dat) {
|
||||
const len = lnsocket_decrypt(this.ln, dat, dat.length)
|
||||
if (len === 0) {
|
||||
this.print_errors()
|
||||
throw new Error("decrypt error")
|
||||
}
|
||||
return wasm_mem(lnsocket_msgbuf(this.ln), len)
|
||||
}
|
||||
|
||||
LNSocket.prototype.write = function _lnsocket_write(dat) {
|
||||
this.ws.send(this.encrypt(dat))
|
||||
}
|
||||
|
||||
LNSocket.prototype.read = async function _lnsocket_read() {
|
||||
const size = await this.read_header()
|
||||
const enc = await this.read_all(size+16)
|
||||
return this.decrypt(enc)
|
||||
}
|
||||
|
||||
LNSocket.prototype.make_default_initmsg = function _lnsocket_make_default_initmsg() {
|
||||
const buflen = 1024
|
||||
let len = 0;
|
||||
const buf = module._malloc(buflen);
|
||||
module.HEAPU8.set(Uint8Array, buf);
|
||||
|
||||
if (!(len = lnsocket_make_default_initmsg(buf, buflen)))
|
||||
throw new Error("couldn't make initmsg");
|
||||
|
||||
const dat = wasm_mem(buf, len)
|
||||
module._free(buf);
|
||||
return dat
|
||||
}
|
||||
|
||||
LNSocket.prototype.perform_init = async function lnsocket_connect() {
|
||||
await this.read()
|
||||
const our_init = this.make_default_initmsg()
|
||||
this.write(our_init)
|
||||
}
|
||||
|
||||
LNSocket.prototype.ping_pong = async function lnsocket_ping_pong() {
|
||||
const pingmsg = this.make_ping_msg()
|
||||
this.write(pingmsg)
|
||||
return await this.read()
|
||||
}
|
||||
|
||||
LNSocket.prototype.disconnect = function lnsocket_disconnect() {
|
||||
if (this.connected === true && this.ws) {
|
||||
this.ws.close()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
LNSocket.prototype.destroy = function _lnsocket_destroy() {
|
||||
this.disconnect()
|
||||
lnsocket_destroy(this.ln)
|
||||
}
|
||||
|
||||
function handle_connect(ln, node_id, host) {
|
||||
const ws = new SocketImpl(host)
|
||||
return new Promise((resolve, reject) => {
|
||||
const timeout = ln.opts.timeout || DEFAULT_TIMEOUT
|
||||
const timer = setTimeout(reject, timeout);
|
||||
|
||||
ws.ondata((v) => {
|
||||
ln.queue.push(v)
|
||||
});
|
||||
|
||||
ws.addEventListener('open', function(ev) {
|
||||
ln.ws = ws
|
||||
ln.connected = true
|
||||
clearTimeout(timer)
|
||||
resolve(ws)
|
||||
});
|
||||
|
||||
ws.addEventListener('close', function(ev) {
|
||||
ln.connected = false
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return LNSocket
|
||||
}
|
||||
|
||||
Module.init = Module.lnsocket_init = lnsocket_init
|
24
node_modules/lnsocket/lnsocket_pre.js
generated
vendored
Normal file
24
node_modules/lnsocket/lnsocket_pre.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
Module.getRandomValue = (function() {
|
||||
const window_ = "object" === typeof window ? window : this
|
||||
const crypto_ = typeof window_.crypto !== "undefined" ? window_.crypto : window_.msCrypto;
|
||||
|
||||
let randomBytesNode
|
||||
if (!crypto_) {
|
||||
randomBytesNode = require('crypto').randomBytes
|
||||
fn = randomValuesNode
|
||||
} else {
|
||||
fn = randomValuesStandard
|
||||
}
|
||||
|
||||
function randomValuesNode() {
|
||||
return randomBytesNode(1)[0] >>> 0
|
||||
}
|
||||
|
||||
function randomValuesStandard() {
|
||||
var buf = new Uint32Array(1);
|
||||
crypto_.getRandomValues(buf);
|
||||
return buf[0] >>> 0;
|
||||
};
|
||||
|
||||
return fn
|
||||
})()
|
39
node_modules/lnsocket/lnsocket_wasm.c
generated
vendored
Normal file
39
node_modules/lnsocket/lnsocket_wasm.c
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
#include "handshake.h"
|
||||
#include "lnsocket_internal.h"
|
||||
#include <emscripten.h>
|
||||
|
||||
struct act_three* lnsocket_act_two(struct lnsocket *ln, struct act_two *act2);
|
||||
|
||||
void* EMSCRIPTEN_KEEPALIVE lnsocket_act_one(struct lnsocket *ln, const char *node_id)
|
||||
{
|
||||
struct pubkey their_id;
|
||||
struct node_id their_node_id;
|
||||
|
||||
if (is_zero(&ln->key, sizeof(ln->key))) {
|
||||
note_error(&ln->errs, "key not initialized, use lnsocket_set_key() or lnsocket_genkey()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!parse_node_id(node_id, &their_node_id)) {
|
||||
note_error(&ln->errs, "failed to parse node id");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!pubkey_from_node_id(ln->secp, &their_id, &their_node_id)) {
|
||||
note_error(&ln->errs, "failed to convert node_id to pubkey");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_handshake(ln->secp, &ln->handshake, &their_id);
|
||||
|
||||
ln->handshake.side = INITIATOR;
|
||||
ln->handshake.their_id = their_id;
|
||||
|
||||
if (!act_one_initiator_prep(ln)) {
|
||||
note_error(&ln->errs, "failed to build initial handshake data (act1)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &ln->handshake.act1;
|
||||
}
|
13
node_modules/lnsocket/package.json
generated
vendored
Normal file
13
node_modules/lnsocket/package.json
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "lnsocket",
|
||||
"description": "Connect to the lightning network",
|
||||
"version": "0.2.5",
|
||||
"repository": {
|
||||
"url": "https://github.com/jb55/lnsocket"
|
||||
},
|
||||
"main": "index.js",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"tap": "~0.2.5"
|
||||
}
|
||||
}
|
302
node_modules/lnsocket/sha256.c
generated
vendored
Normal file
302
node_modules/lnsocket/sha256.c
generated
vendored
Normal file
|
@ -0,0 +1,302 @@
|
|||
/* MIT (BSD) license - see LICENSE file for details */
|
||||
/* SHA256 core code translated from the Bitcoin project's C++:
|
||||
*
|
||||
* src/crypto/sha256.cpp commit 417532c8acb93c36c2b6fd052b7c11b6a2906aa2
|
||||
* Copyright (c) 2014 The Bitcoin Core developers
|
||||
* Distributed under the MIT software license, see the accompanying
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
*/
|
||||
#include "sha256.h"
|
||||
#include "endian.h"
|
||||
#include "compiler.h"
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static void invalidate_sha256(struct sha256_ctx *ctx)
|
||||
{
|
||||
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
|
||||
ctx->c.md_len = 0;
|
||||
#else
|
||||
ctx->bytes = (size_t)-1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void check_sha256(struct sha256_ctx *ctx)
|
||||
{
|
||||
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
|
||||
assert(ctx->c.md_len != 0);
|
||||
#else
|
||||
assert(ctx->bytes != (size_t)-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
|
||||
void sha256_init(struct sha256_ctx *ctx)
|
||||
{
|
||||
SHA256_Init(&ctx->c);
|
||||
}
|
||||
|
||||
void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size)
|
||||
{
|
||||
check_sha256(ctx);
|
||||
SHA256_Update(&ctx->c, p, size);
|
||||
}
|
||||
|
||||
void sha256_done(struct sha256_ctx *ctx, struct sha256 *res)
|
||||
{
|
||||
SHA256_Final(res->u.u8, &ctx->c);
|
||||
invalidate_sha256(ctx);
|
||||
}
|
||||
#else
|
||||
static uint32_t Ch(uint32_t x, uint32_t y, uint32_t z)
|
||||
{
|
||||
return z ^ (x & (y ^ z));
|
||||
}
|
||||
static uint32_t Maj(uint32_t x, uint32_t y, uint32_t z)
|
||||
{
|
||||
return (x & y) | (z & (x | y));
|
||||
}
|
||||
static uint32_t Sigma0(uint32_t x)
|
||||
{
|
||||
return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10);
|
||||
}
|
||||
static uint32_t Sigma1(uint32_t x)
|
||||
{
|
||||
return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7);
|
||||
}
|
||||
static uint32_t sigma0(uint32_t x)
|
||||
{
|
||||
return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3);
|
||||
}
|
||||
static uint32_t sigma1(uint32_t x)
|
||||
{
|
||||
return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10);
|
||||
}
|
||||
|
||||
/** One round of SHA-256. */
|
||||
static void Round(uint32_t a, uint32_t b, uint32_t c, uint32_t *d, uint32_t e, uint32_t f, uint32_t g, uint32_t *h, uint32_t k, uint32_t w)
|
||||
{
|
||||
uint32_t t1 = *h + Sigma1(e) + Ch(e, f, g) + k + w;
|
||||
uint32_t t2 = Sigma0(a) + Maj(a, b, c);
|
||||
*d += t1;
|
||||
*h = t1 + t2;
|
||||
}
|
||||
|
||||
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
|
||||
static void Transform(uint32_t *s, const uint32_t *chunk)
|
||||
{
|
||||
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
|
||||
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x428a2f98, w0 = be32_to_cpu(chunk[0]));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x71374491, w1 = be32_to_cpu(chunk[1]));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0xb5c0fbcf, w2 = be32_to_cpu(chunk[2]));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0xe9b5dba5, w3 = be32_to_cpu(chunk[3]));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x3956c25b, w4 = be32_to_cpu(chunk[4]));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x59f111f1, w5 = be32_to_cpu(chunk[5]));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x923f82a4, w6 = be32_to_cpu(chunk[6]));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0xab1c5ed5, w7 = be32_to_cpu(chunk[7]));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0xd807aa98, w8 = be32_to_cpu(chunk[8]));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x12835b01, w9 = be32_to_cpu(chunk[9]));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x243185be, w10 = be32_to_cpu(chunk[10]));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x550c7dc3, w11 = be32_to_cpu(chunk[11]));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x72be5d74, w12 = be32_to_cpu(chunk[12]));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x80deb1fe, w13 = be32_to_cpu(chunk[13]));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x9bdc06a7, w14 = be32_to_cpu(chunk[14]));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0xc19bf174, w15 = be32_to_cpu(chunk[15]));
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
s[0] += a;
|
||||
s[1] += b;
|
||||
s[2] += c;
|
||||
s[3] += d;
|
||||
s[4] += e;
|
||||
s[5] += f;
|
||||
s[6] += g;
|
||||
s[7] += h;
|
||||
}
|
||||
|
||||
|
||||
static void add(struct sha256_ctx *ctx, const void *p, size_t len)
|
||||
{
|
||||
const unsigned char *data = p;
|
||||
size_t bufsize = ctx->bytes % 64;
|
||||
|
||||
if (bufsize + len >= 64) {
|
||||
/* Fill the buffer, and process it. */
|
||||
memcpy(ctx->buf.u8 + bufsize, data, 64 - bufsize);
|
||||
ctx->bytes += 64 - bufsize;
|
||||
data += 64 - bufsize;
|
||||
len -= 64 - bufsize;
|
||||
Transform(ctx->s, ctx->buf.u32);
|
||||
bufsize = 0;
|
||||
}
|
||||
|
||||
while (len >= 64) {
|
||||
/* Process full chunks directly from the source. */
|
||||
if (alignment_ok(data, sizeof(uint32_t)))
|
||||
Transform(ctx->s, (const uint32_t *)data);
|
||||
else {
|
||||
memcpy(ctx->buf.u8, data, sizeof(ctx->buf));
|
||||
Transform(ctx->s, ctx->buf.u32);
|
||||
}
|
||||
ctx->bytes += 64;
|
||||
data += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
/* Fill the buffer with what remains. */
|
||||
memcpy(ctx->buf.u8 + bufsize, data, len);
|
||||
ctx->bytes += len;
|
||||
}
|
||||
}
|
||||
|
||||
void sha256_init(struct sha256_ctx *ctx)
|
||||
{
|
||||
struct sha256_ctx init = SHA256_INIT;
|
||||
*ctx = init;
|
||||
}
|
||||
|
||||
void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size)
|
||||
{
|
||||
check_sha256(ctx);
|
||||
add(ctx, p, size);
|
||||
}
|
||||
|
||||
void sha256_done(struct sha256_ctx *ctx, struct sha256 *res)
|
||||
{
|
||||
static const unsigned char pad[64] = {0x80};
|
||||
uint64_t sizedesc;
|
||||
size_t i;
|
||||
|
||||
sizedesc = cpu_to_be64((uint64_t)ctx->bytes << 3);
|
||||
/* Add '1' bit to terminate, then all 0 bits, up to next block - 8. */
|
||||
add(ctx, pad, 1 + ((128 - 8 - (ctx->bytes % 64) - 1) % 64));
|
||||
/* Add number of bits of data (big endian) */
|
||||
add(ctx, &sizedesc, 8);
|
||||
for (i = 0; i < sizeof(ctx->s) / sizeof(ctx->s[0]); i++)
|
||||
res->u.u32[i] = cpu_to_be32(ctx->s[i]);
|
||||
invalidate_sha256(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
void sha256(struct sha256 *sha, const void *p, size_t size)
|
||||
{
|
||||
struct sha256_ctx ctx;
|
||||
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, p, size);
|
||||
sha256_done(&ctx, sha);
|
||||
}
|
||||
|
||||
void sha256_u8(struct sha256_ctx *ctx, uint8_t v)
|
||||
{
|
||||
sha256_update(ctx, &v, sizeof(v));
|
||||
}
|
||||
|
||||
void sha256_u16(struct sha256_ctx *ctx, uint16_t v)
|
||||
{
|
||||
sha256_update(ctx, &v, sizeof(v));
|
||||
}
|
||||
|
||||
void sha256_u32(struct sha256_ctx *ctx, uint32_t v)
|
||||
{
|
||||
sha256_update(ctx, &v, sizeof(v));
|
||||
}
|
||||
|
||||
void sha256_u64(struct sha256_ctx *ctx, uint64_t v)
|
||||
{
|
||||
sha256_update(ctx, &v, sizeof(v));
|
||||
}
|
||||
|
||||
/* Add as little-endian */
|
||||
void sha256_le16(struct sha256_ctx *ctx, uint16_t v)
|
||||
{
|
||||
leint16_t lev = cpu_to_le16(v);
|
||||
sha256_update(ctx, &lev, sizeof(lev));
|
||||
}
|
||||
|
||||
void sha256_le32(struct sha256_ctx *ctx, uint32_t v)
|
||||
{
|
||||
leint32_t lev = cpu_to_le32(v);
|
||||
sha256_update(ctx, &lev, sizeof(lev));
|
||||
}
|
||||
|
||||
void sha256_le64(struct sha256_ctx *ctx, uint64_t v)
|
||||
{
|
||||
leint64_t lev = cpu_to_le64(v);
|
||||
sha256_update(ctx, &lev, sizeof(lev));
|
||||
}
|
||||
|
||||
/* Add as big-endian */
|
||||
void sha256_be16(struct sha256_ctx *ctx, uint16_t v)
|
||||
{
|
||||
beint16_t bev = cpu_to_be16(v);
|
||||
sha256_update(ctx, &bev, sizeof(bev));
|
||||
}
|
||||
|
||||
void sha256_be32(struct sha256_ctx *ctx, uint32_t v)
|
||||
{
|
||||
beint32_t bev = cpu_to_be32(v);
|
||||
sha256_update(ctx, &bev, sizeof(bev));
|
||||
}
|
||||
|
||||
void sha256_be64(struct sha256_ctx *ctx, uint64_t v)
|
||||
{
|
||||
beint64_t bev = cpu_to_be64(v);
|
||||
sha256_update(ctx, &bev, sizeof(bev));
|
||||
}
|
||||
|
||||
|
155
node_modules/lnsocket/sha256.h
generated
vendored
Normal file
155
node_modules/lnsocket/sha256.h
generated
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
|
||||
#ifndef CCAN_CRYPTO_SHA256_H
|
||||
#define CCAN_CRYPTO_SHA256_H
|
||||
|
||||
|
||||
/** Output length for `wally_sha256` */
|
||||
#define SHA256_LEN 32
|
||||
|
||||
|
||||
/* BSD-MIT - see LICENSE file for details */
|
||||
/* #include "config.h" */
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Uncomment this to use openssl's SHA256 routines (and link with -lcrypto) */
|
||||
/*#define CCAN_CRYPTO_SHA256_USE_OPENSSL 1*/
|
||||
|
||||
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct sha256 - structure representing a completed SHA256.
|
||||
* @u.u8: an unsigned char array.
|
||||
* @u.u32: a 32-bit integer array.
|
||||
*
|
||||
* Other fields may be added to the union in future.
|
||||
*/
|
||||
struct sha256 {
|
||||
union {
|
||||
uint32_t u32[8];
|
||||
unsigned char u8[32];
|
||||
} u;
|
||||
};
|
||||
|
||||
/**
|
||||
* sha256 - return sha256 of an object.
|
||||
* @sha256: the sha256 to fill in
|
||||
* @p: pointer to memory,
|
||||
* @size: the number of bytes pointed to by @p
|
||||
*
|
||||
* The bytes pointed to by @p is SHA256 hashed into @sha256. This is
|
||||
* equivalent to sha256_init(), sha256_update() then sha256_done().
|
||||
*/
|
||||
void sha256(struct sha256 *sha, const void *p, size_t size);
|
||||
|
||||
/**
|
||||
* struct sha256_ctx - structure to store running context for sha256
|
||||
*/
|
||||
struct sha256_ctx {
|
||||
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
|
||||
SHA256_CTX c;
|
||||
#else
|
||||
uint32_t s[8];
|
||||
union {
|
||||
uint32_t u32[16];
|
||||
unsigned char u8[64];
|
||||
} buf;
|
||||
size_t bytes;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* sha256_init - initialize an SHA256 context.
|
||||
* @ctx: the sha256_ctx to initialize
|
||||
*
|
||||
* This must be called before sha256_update or sha256_done, or
|
||||
* alternately you can assign SHA256_INIT.
|
||||
*
|
||||
* If it was already initialized, this forgets anything which was
|
||||
* hashed before.
|
||||
*
|
||||
* Example:
|
||||
* static void hash_all(const char **arr, struct sha256 *hash)
|
||||
* {
|
||||
* size_t i;
|
||||
* struct sha256_ctx ctx;
|
||||
*
|
||||
* sha256_init(&ctx);
|
||||
* for (i = 0; arr[i]; i++)
|
||||
* sha256_update(&ctx, arr[i], strlen(arr[i]));
|
||||
* sha256_done(&ctx, hash);
|
||||
* }
|
||||
*/
|
||||
void sha256_init(struct sha256_ctx *ctx);
|
||||
|
||||
/**
|
||||
* SHA256_INIT - initializer for an SHA256 context.
|
||||
*
|
||||
* This can be used to statically initialize an SHA256 context (instead
|
||||
* of sha256_init()).
|
||||
*
|
||||
* Example:
|
||||
* static void hash_all(const char **arr, struct sha256 *hash)
|
||||
* {
|
||||
* size_t i;
|
||||
* struct sha256_ctx ctx = SHA256_INIT;
|
||||
*
|
||||
* for (i = 0; arr[i]; i++)
|
||||
* sha256_update(&ctx, arr[i], strlen(arr[i]));
|
||||
* sha256_done(&ctx, hash);
|
||||
* }
|
||||
*/
|
||||
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
|
||||
#define SHA256_INIT \
|
||||
{ { { 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, \
|
||||
0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul }, \
|
||||
0x0, 0x0, \
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
|
||||
0x0, 0x20 } }
|
||||
#else
|
||||
#define SHA256_INIT \
|
||||
{ { 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, \
|
||||
0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul }, \
|
||||
{ { 0 } }, 0 }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* sha256_update - include some memory in the hash.
|
||||
* @ctx: the sha256_ctx to use
|
||||
* @p: pointer to memory,
|
||||
* @size: the number of bytes pointed to by @p
|
||||
*
|
||||
* You can call this multiple times to hash more data, before calling
|
||||
* sha256_done().
|
||||
*/
|
||||
void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size);
|
||||
|
||||
/**
|
||||
* sha256_done - finish SHA256 and return the hash
|
||||
* @ctx: the sha256_ctx to complete
|
||||
* @res: the hash to return.
|
||||
*
|
||||
* Note that @ctx is *destroyed* by this, and must be reinitialized.
|
||||
* To avoid that, pass a copy instead.
|
||||
*/
|
||||
void sha256_done(struct sha256_ctx *sha256, struct sha256 *res);
|
||||
|
||||
/* Add various types to an SHA256 hash */
|
||||
void sha256_u8(struct sha256_ctx *ctx, uint8_t v);
|
||||
void sha256_u16(struct sha256_ctx *ctx, uint16_t v);
|
||||
void sha256_u32(struct sha256_ctx *ctx, uint32_t v);
|
||||
void sha256_u64(struct sha256_ctx *ctx, uint64_t v);
|
||||
|
||||
/* Add as little-endian */
|
||||
void sha256_le16(struct sha256_ctx *ctx, uint16_t v);
|
||||
void sha256_le32(struct sha256_ctx *ctx, uint32_t v);
|
||||
void sha256_le64(struct sha256_ctx *ctx, uint64_t v);
|
||||
|
||||
/* Add as big-endian */
|
||||
void sha256_be16(struct sha256_ctx *ctx, uint16_t v);
|
||||
void sha256_be32(struct sha256_ctx *ctx, uint32_t v);
|
||||
void sha256_be64(struct sha256_ctx *ctx, uint64_t v);
|
||||
|
||||
#endif /* CCAN_CRYPTO_SHA256_H */
|
261
node_modules/lnsocket/sha512.c
generated
vendored
Normal file
261
node_modules/lnsocket/sha512.c
generated
vendored
Normal file
|
@ -0,0 +1,261 @@
|
|||
|
||||
/* MIT (BSD) license - see LICENSE file for details */
|
||||
/* SHA512 core code translated from the Bitcoin project's C++:
|
||||
*
|
||||
* src/crypto/sha512.cpp commit f914f1a746d7f91951c1da262a4a749dd3ebfa71
|
||||
* Copyright (c) 2014 The Bitcoin Core developers
|
||||
* Distributed under the MIT software license, see the accompanying
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
*/
|
||||
#include "sha512.h"
|
||||
#include "endian.h"
|
||||
#include "compiler.h"
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static void invalidate_sha512(struct sha512_ctx *ctx)
|
||||
{
|
||||
#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
|
||||
ctx->c.md_len = 0;
|
||||
#else
|
||||
ctx->bytes = (size_t)-1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void check_sha512(struct sha512_ctx *ctx)
|
||||
{
|
||||
#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
|
||||
assert(ctx->c.md_len != 0);
|
||||
#else
|
||||
assert(ctx->bytes != (size_t)-1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
|
||||
void sha512_init(struct sha512_ctx *ctx)
|
||||
{
|
||||
SHA512_Init(&ctx->c);
|
||||
}
|
||||
|
||||
void sha512_update(struct sha512_ctx *ctx, const void *p, size_t size)
|
||||
{
|
||||
check_sha512(ctx);
|
||||
SHA512_Update(&ctx->c, p, size);
|
||||
}
|
||||
|
||||
void sha512_done(struct sha512_ctx *ctx, struct sha512 *res)
|
||||
{
|
||||
SHA512_Final(res->u.u8, &ctx->c);
|
||||
invalidate_sha512(ctx);
|
||||
}
|
||||
#else
|
||||
static uint64_t Ch(uint64_t x, uint64_t y, uint64_t z)
|
||||
{
|
||||
return z ^ (x & (y ^ z));
|
||||
}
|
||||
static uint64_t Maj(uint64_t x, uint64_t y, uint64_t z)
|
||||
{
|
||||
return (x & y) | (z & (x | y));
|
||||
}
|
||||
static uint64_t Sigma0(uint64_t x)
|
||||
{
|
||||
return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25);
|
||||
}
|
||||
static uint64_t Sigma1(uint64_t x)
|
||||
{
|
||||
return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23);
|
||||
}
|
||||
static uint64_t sigma0(uint64_t x)
|
||||
{
|
||||
return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7);
|
||||
}
|
||||
static uint64_t sigma1(uint64_t x)
|
||||
{
|
||||
return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6);
|
||||
}
|
||||
|
||||
/** One round of SHA-512. */
|
||||
static void Round(uint64_t a, uint64_t b, uint64_t c, uint64_t *d, uint64_t e, uint64_t f, uint64_t g, uint64_t *h, uint64_t k, uint64_t w)
|
||||
{
|
||||
uint64_t t1 = *h + Sigma1(e) + Ch(e, f, g) + k + w;
|
||||
uint64_t t2 = Sigma0(a) + Maj(a, b, c);
|
||||
*d += t1;
|
||||
*h = t1 + t2;
|
||||
}
|
||||
|
||||
/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
|
||||
static void Transform(uint64_t *s, const uint64_t *chunk)
|
||||
{
|
||||
uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
|
||||
uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x428a2f98d728ae22ull, w0 = be64_to_cpu(chunk[0]));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x7137449123ef65cdull, w1 = be64_to_cpu(chunk[1]));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0xb5c0fbcfec4d3b2full, w2 = be64_to_cpu(chunk[2]));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0xe9b5dba58189dbbcull, w3 = be64_to_cpu(chunk[3]));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x3956c25bf348b538ull, w4 = be64_to_cpu(chunk[4]));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x59f111f1b605d019ull, w5 = be64_to_cpu(chunk[5]));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x923f82a4af194f9bull, w6 = be64_to_cpu(chunk[6]));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0xab1c5ed5da6d8118ull, w7 = be64_to_cpu(chunk[7]));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0xd807aa98a3030242ull, w8 = be64_to_cpu(chunk[8]));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x12835b0145706fbeull, w9 = be64_to_cpu(chunk[9]));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x243185be4ee4b28cull, w10 = be64_to_cpu(chunk[10]));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x550c7dc3d5ffb4e2ull, w11 = be64_to_cpu(chunk[11]));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x72be5d74f27b896full, w12 = be64_to_cpu(chunk[12]));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x80deb1fe3b1696b1ull, w13 = be64_to_cpu(chunk[13]));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x9bdc06a725c71235ull, w14 = be64_to_cpu(chunk[14]));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0xc19bf174cf692694ull, w15 = be64_to_cpu(chunk[15]));
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
Round(a, b, c, &d, e, f, g, &h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, &d, e, f, g, &h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, &c, d, e, f, &g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, &b, c, d, e, &f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, &a, b, c, d, &e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, &h, a, b, c, &d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, &g, h, a, b, &c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, &f, g, h, a, &b, 0x5fcb6fab3ad6faecull, w14 + sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, &e, f, g, h, &a, 0x6c44198c4a475817ull, w15 + sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
s[0] += a;
|
||||
s[1] += b;
|
||||
s[2] += c;
|
||||
s[3] += d;
|
||||
s[4] += e;
|
||||
s[5] += f;
|
||||
s[6] += g;
|
||||
s[7] += h;
|
||||
}
|
||||
|
||||
static void add(struct sha512_ctx *ctx, const void *p, size_t len)
|
||||
{
|
||||
const unsigned char *data = p;
|
||||
size_t bufsize = ctx->bytes % 128;
|
||||
|
||||
if (bufsize + len >= 128) {
|
||||
/* Fill the buffer, and process it. */
|
||||
memcpy(ctx->buf.u8 + bufsize, data, 128 - bufsize);
|
||||
ctx->bytes += 128 - bufsize;
|
||||
data += 128 - bufsize;
|
||||
len -= 128 - bufsize;
|
||||
Transform(ctx->s, ctx->buf.u64);
|
||||
bufsize = 0;
|
||||
}
|
||||
|
||||
while (len >= 128) {
|
||||
/* Process full chunks directly from the source. */
|
||||
if (alignment_ok(data, sizeof(uint64_t)))
|
||||
Transform(ctx->s, (const uint64_t *)data);
|
||||
else {
|
||||
memcpy(ctx->buf.u8, data, sizeof(ctx->buf));
|
||||
Transform(ctx->s, ctx->buf.u64);
|
||||
}
|
||||
ctx->bytes += 128;
|
||||
data += 128;
|
||||
len -= 128;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
/* Fill the buffer with what remains. */
|
||||
memcpy(ctx->buf.u8 + bufsize, data, len);
|
||||
ctx->bytes += len;
|
||||
}
|
||||
}
|
||||
|
||||
void sha512_init(struct sha512_ctx *ctx)
|
||||
{
|
||||
struct sha512_ctx init = SHA512_INIT;
|
||||
*ctx = init;
|
||||
}
|
||||
|
||||
void sha512_update(struct sha512_ctx *ctx, const void *p, size_t size)
|
||||
{
|
||||
check_sha512(ctx);
|
||||
add(ctx, p, size);
|
||||
}
|
||||
|
||||
void sha512_done(struct sha512_ctx *ctx, struct sha512 *res)
|
||||
{
|
||||
static const unsigned char pad[128] = { 0x80 };
|
||||
uint64_t sizedesc[2] = { 0, 0 };
|
||||
size_t i;
|
||||
|
||||
sizedesc[1] = cpu_to_be64((uint64_t)ctx->bytes << 3);
|
||||
|
||||
/* Add '1' bit to terminate, then all 0 bits, up to next block - 16. */
|
||||
add(ctx, pad, 1 + ((256 - 16 - (ctx->bytes % 128) - 1) % 128));
|
||||
/* Add number of bits of data (big endian) */
|
||||
add(ctx, sizedesc, sizeof(sizedesc));
|
||||
for (i = 0; i < sizeof(ctx->s) / sizeof(ctx->s[0]); i++)
|
||||
res->u.u64[i] = cpu_to_be64(ctx->s[i]);
|
||||
invalidate_sha512(ctx);
|
||||
}
|
||||
#endif /* CCAN_CRYPTO_SHA512_USE_OPENSSL */
|
||||
|
||||
void sha512(struct sha512 *sha, const void *p, size_t size)
|
||||
{
|
||||
struct sha512_ctx ctx;
|
||||
|
||||
sha512_init(&ctx);
|
||||
sha512_update(&ctx, p, size);
|
||||
sha512_done(&ctx, sha);
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
}
|
138
node_modules/lnsocket/sha512.h
generated
vendored
Normal file
138
node_modules/lnsocket/sha512.h
generated
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
|
||||
#ifndef CCAN_CRYPTO_SHA512_H
|
||||
#define CCAN_CRYPTO_SHA512_H
|
||||
/* BSD-MIT - see LICENSE file for details */
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** Output length for `wally_sha512` */
|
||||
#define SHA512_LEN 64
|
||||
|
||||
/* Uncomment this to use openssl's SHA512 routines (and link with -lcrypto) */
|
||||
/*#define CCAN_CRYPTO_SHA512_USE_OPENSSL 1*/
|
||||
|
||||
#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct sha512 - structure representing a completed SHA512.
|
||||
* @u.u8: an unsigned char array.
|
||||
* @u.u64: a 64-bit integer array.
|
||||
*
|
||||
* Other fields may be added to the union in future.
|
||||
*/
|
||||
struct sha512 {
|
||||
union {
|
||||
uint64_t u64[8];
|
||||
unsigned char u8[64];
|
||||
} u;
|
||||
};
|
||||
|
||||
/**
|
||||
* sha512 - return sha512 of an object.
|
||||
* @sha512: the sha512 to fill in
|
||||
* @p: pointer to memory,
|
||||
* @size: the number of bytes pointed to by @p
|
||||
*
|
||||
* The bytes pointed to by @p is SHA512 hashed into @sha512. This is
|
||||
* equivalent to sha512_init(), sha512_update() then sha512_done().
|
||||
*/
|
||||
void sha512(struct sha512 *sha, const void *p, size_t size);
|
||||
|
||||
/**
|
||||
* struct sha512_ctx - structure to store running context for sha512
|
||||
*/
|
||||
struct sha512_ctx {
|
||||
#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
|
||||
SHA512_CTX c;
|
||||
#else
|
||||
uint64_t s[8];
|
||||
union {
|
||||
uint64_t u64[16];
|
||||
unsigned char u8[128];
|
||||
} buf;
|
||||
size_t bytes;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* sha512_init - initialize an SHA512 context.
|
||||
* @ctx: the sha512_ctx to initialize
|
||||
*
|
||||
* This must be called before sha512_update or sha512_done, or
|
||||
* alternately you can assign SHA512_INIT.
|
||||
*
|
||||
* If it was already initialized, this forgets anything which was
|
||||
* hashed before.
|
||||
*
|
||||
* Example:
|
||||
* static void hash_all(const char **arr, struct sha512 *hash)
|
||||
* {
|
||||
* size_t i;
|
||||
* struct sha512_ctx ctx;
|
||||
*
|
||||
* sha512_init(&ctx);
|
||||
* for (i = 0; arr[i]; i++)
|
||||
* sha512_update(&ctx, arr[i], strlen(arr[i]));
|
||||
* sha512_done(&ctx, hash);
|
||||
* }
|
||||
*/
|
||||
void sha512_init(struct sha512_ctx *ctx);
|
||||
|
||||
/**
|
||||
* SHA512_INIT - initializer for an SHA512 context.
|
||||
*
|
||||
* This can be used to statically initialize an SHA512 context (instead
|
||||
* of sha512_init()).
|
||||
*
|
||||
* Example:
|
||||
* static void hash_all(const char **arr, struct sha512 *hash)
|
||||
* {
|
||||
* size_t i;
|
||||
* struct sha512_ctx ctx = SHA512_INIT;
|
||||
*
|
||||
* for (i = 0; arr[i]; i++)
|
||||
* sha512_update(&ctx, arr[i], strlen(arr[i]));
|
||||
* sha512_done(&ctx, hash);
|
||||
* }
|
||||
*/
|
||||
#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
|
||||
{ { { 0x6a09e667f3bcc908ull, 0xbb67ae8584caa73bull, \
|
||||
0x3c6ef372fe94f82bull, 0xa54ff53a5f1d36f1ull, \
|
||||
0x510e527fade682d1ull, 0x9b05688c2b3e6c1full, \
|
||||
0x1f83d9abfb41bd6bull, 0x5be0cd19137e2179ull }, \
|
||||
0, 0, \
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
|
||||
0, 0x40 } }
|
||||
#else
|
||||
#define SHA512_INIT \
|
||||
{ { 0x6a09e667f3bcc908ull, 0xbb67ae8584caa73bull, \
|
||||
0x3c6ef372fe94f82bull, 0xa54ff53a5f1d36f1ull, \
|
||||
0x510e527fade682d1ull, 0x9b05688c2b3e6c1full, \
|
||||
0x1f83d9abfb41bd6bull, 0x5be0cd19137e2179ull }, \
|
||||
{ { 0 } }, 0 }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* sha512_update - include some memory in the hash.
|
||||
* @ctx: the sha512_ctx to use
|
||||
* @p: pointer to memory,
|
||||
* @size: the number of bytes pointed to by @p
|
||||
*
|
||||
* You can call this multiple times to hash more data, before calling
|
||||
* sha512_done().
|
||||
*/
|
||||
void sha512_update(struct sha512_ctx *ctx, const void *p, size_t size);
|
||||
|
||||
/**
|
||||
* sha512_done - finish SHA512 and return the hash
|
||||
* @ctx: the sha512_ctx to complete
|
||||
* @res: the hash to return.
|
||||
*
|
||||
* Note that @ctx is *destroyed* by this, and must be reinitialized.
|
||||
* To avoid that, pass a copy instead.
|
||||
*/
|
||||
void sha512_done(struct sha512_ctx *sha512, struct sha512 *res);
|
||||
|
||||
#endif /* CCAN_CRYPTO_SHA512_H */
|
5
node_modules/lnsocket/shell.nix
generated
vendored
Normal file
5
node_modules/lnsocket/shell.nix
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
buildInputs = [ ];
|
||||
nativeBuildInputs = with pkgs; [ gdb autoreconfHook emscripten wabt go ];
|
||||
}
|
59
node_modules/lnsocket/test.c
generated
vendored
Normal file
59
node_modules/lnsocket/test.c
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
#include "lnsocket.h"
|
||||
#include "endian.h"
|
||||
#include "typedefs.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
static void print_data(unsigned char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
printf("%02x", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
static u8 msgbuf[4096];
|
||||
u8 *buf;
|
||||
struct lnsocket *ln;
|
||||
|
||||
u16 len;
|
||||
int ok = 1;
|
||||
|
||||
ln = lnsocket_create();
|
||||
assert(ln);
|
||||
|
||||
lnsocket_genkey(ln);
|
||||
|
||||
const char *nodeid = "03f3c108ccd536b8526841f0a5c58212bb9e6584a1eb493080e7c1cc34f82dad71";
|
||||
if (!(ok = lnsocket_connect(ln, nodeid, "24.84.152.187")))
|
||||
goto done;
|
||||
|
||||
if (!(ok = lnsocket_perform_init(ln)))
|
||||
goto done;
|
||||
|
||||
printf("init ok!\n");
|
||||
|
||||
if (!(ok = len = lnsocket_make_ping_msg(msgbuf, sizeof(msgbuf), 1, 1)))
|
||||
goto done;
|
||||
|
||||
if (!(ok = lnsocket_write(ln, msgbuf, len)))
|
||||
goto done;
|
||||
|
||||
printf("sent ping ");
|
||||
print_data(msgbuf, len);
|
||||
|
||||
if (!(ok = lnsocket_read(ln, &buf, &len)))
|
||||
goto done;
|
||||
|
||||
printf("got ");
|
||||
print_data(buf, len);
|
||||
done:
|
||||
lnsocket_print_errors(ln);
|
||||
lnsocket_destroy(ln);
|
||||
return !ok;
|
||||
}
|
67
node_modules/lnsocket/tools/0001-configure-customizable-AR-and-RANLIB.patch
generated
vendored
Normal file
67
node_modules/lnsocket/tools/0001-configure-customizable-AR-and-RANLIB.patch
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
From 0d253d52e804a5affb0f1c851ec250071e7345d9 Mon Sep 17 00:00:00 2001
|
||||
From: Tim Ruffing <crypto@timruffing.de>
|
||||
Date: Sun, 13 Mar 2022 10:39:55 +0100
|
||||
Subject: [PATCH] configure: Use modern way to set AR
|
||||
|
||||
This uses AM_PROG_AR to discover ar, which is the recommended way to do
|
||||
so. Among other advantages, it honors the AR environment variable (as
|
||||
set from the outside). The macro has been around since automake 1.11.2
|
||||
(Dec 2011).
|
||||
|
||||
This commit also removes code that discovers ranlib and strip. ranlib
|
||||
has been obsolete for decades (ar does its task now automatically), and
|
||||
anyway LT_INIT takes care of discovering it. The code we used to set
|
||||
STRIP was last mentioned in the automake 1.5 manual. Since automake 1.6
|
||||
(Mar 2002), strip is discovered automatically when necessary (look for
|
||||
the *private* macro AM_PROG_INSTALL_STRIP in the automake manual).
|
||||
---
|
||||
.gitignore | 1 +
|
||||
configure.ac | 11 +++++------
|
||||
2 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 53941f23a..d88627d72 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -46,6 +46,7 @@ coverage.*.html
|
||||
|
||||
src/libsecp256k1-config.h
|
||||
src/libsecp256k1-config.h.in
|
||||
+build-aux/ar-lib
|
||||
build-aux/config.guess
|
||||
build-aux/config.sub
|
||||
build-aux/depcomp
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index cc766b20a..16a492071 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -25,24 +25,23 @@ AC_CANONICAL_HOST
|
||||
AH_TOP([#ifndef LIBSECP256K1_CONFIG_H])
|
||||
AH_TOP([#define LIBSECP256K1_CONFIG_H])
|
||||
AH_BOTTOM([#endif /*LIBSECP256K1_CONFIG_H*/])
|
||||
-AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
|
||||
-LT_INIT([win32-dll])
|
||||
+# Require Automake 1.11.2 for AM_PROG_AR
|
||||
+AM_INIT_AUTOMAKE([1.11.2 foreign subdir-objects])
|
||||
|
||||
# Make the compilation flags quiet unless V=1 is used.
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
-AC_PATH_TOOL(AR, ar)
|
||||
-AC_PATH_TOOL(RANLIB, ranlib)
|
||||
-AC_PATH_TOOL(STRIP, strip)
|
||||
-
|
||||
AC_PROG_CC
|
||||
if test x"$ac_cv_prog_cc_c89" = x"no"; then
|
||||
AC_MSG_ERROR([c89 compiler support required])
|
||||
fi
|
||||
AM_PROG_AS
|
||||
+AM_PROG_AR
|
||||
+
|
||||
+LT_INIT([win32-dll])
|
||||
|
||||
build_windows=no
|
||||
|
42
node_modules/lnsocket/tools/refresh-submodules.sh
generated
vendored
Executable file
42
node_modules/lnsocket/tools/refresh-submodules.sh
generated
vendored
Executable file
|
@ -0,0 +1,42 @@
|
|||
#! /bin/sh
|
||||
|
||||
if [ $# = 0 ]; then
|
||||
echo "Usage: $0 <submoduledir1>..." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If no git dir (or, if we're a submodule, git file), forget it.
|
||||
[ -e .git ] || exit 0
|
||||
|
||||
# git submodule can't run in parallel. Really.
|
||||
# Wait for it to finish if in parallel.
|
||||
if ! mkdir .refresh-submodules 2>/dev/null ; then
|
||||
# If we don't make progress in ~60 seconds, force delete and retry.
|
||||
LIMIT=$((50 + $$ % 20))
|
||||
i=0
|
||||
while [ $i -lt $LIMIT ]; do
|
||||
[ -d .refresh-submodules ] || exit 0
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
rmdir .refresh-submodules
|
||||
exec "$0" "$@" || exit 1
|
||||
fi
|
||||
|
||||
trap "rmdir .refresh-submodules" EXIT
|
||||
|
||||
# Be a little careful here, since we do rm -rf!
|
||||
for m in "$@"; do
|
||||
if ! grep -q "path = $m\$" .gitmodules; then
|
||||
echo "$m is not a submodule!" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# git submodule can segfault. Really.
|
||||
if [ "$(git submodule status "$@" | grep -c '^ ')" != $# ]; then
|
||||
echo Reinitializing submodules "$@" ...
|
||||
git submodule sync "$@"
|
||||
rm -rf "$@"
|
||||
git submodule update --init --recursive "$@"
|
||||
fi
|
74
node_modules/lnsocket/tools/secp-ios.sh
generated
vendored
Executable file
74
node_modules/lnsocket/tools/secp-ios.sh
generated
vendored
Executable file
|
@ -0,0 +1,74 @@
|
|||
#! /usr/bin/env bash
|
||||
#
|
||||
# Step 1.
|
||||
# Configure for base system so simulator is covered
|
||||
#
|
||||
# Step 2.
|
||||
# Make for iOS and iOS simulator
|
||||
#
|
||||
# Step 3.
|
||||
# Merge libs into final version for xcode import
|
||||
|
||||
cd deps/secp256k1
|
||||
|
||||
export PREFIX="$(pwd)/libsecp256k1-ios"
|
||||
export IOS64_PREFIX="$PREFIX/tmp/ios64"
|
||||
export SIMULATOR64_PREFIX="$PREFIX/tmp/simulator64"
|
||||
export XCODEDIR=$(xcode-select -p)
|
||||
export IOS_SIMULATOR_VERSION_MIN=${IOS_SIMULATOR_VERSION_MIN-"6.0.0"}
|
||||
export IOS_VERSION_MIN=${IOS_VERSION_MIN-"6.0.0"}
|
||||
|
||||
mkdir -p $SIMULATOR64_PREFIX $IOS64_PREFIX || exit 1
|
||||
|
||||
# Build for the simulator
|
||||
export BASEDIR="${XCODEDIR}/Platforms/iPhoneSimulator.platform/Developer"
|
||||
export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH"
|
||||
export SDK="${BASEDIR}/SDKs/iPhoneSimulator.sdk"
|
||||
|
||||
## x86_64 simulator
|
||||
export CFLAGS="-O2 -arch x86_64 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN} -flto"
|
||||
export LDFLAGS="-arch x86_64 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN} -flto"
|
||||
|
||||
make distclean > /dev/null
|
||||
|
||||
./configure --host=x86_64-apple-darwin10 \
|
||||
--disable-shared \
|
||||
--enable-module-ecdh \
|
||||
--prefix="$SIMULATOR64_PREFIX"
|
||||
|
||||
make -j3 install || exit 1
|
||||
|
||||
# Build for iOS
|
||||
export BASEDIR="${XCODEDIR}/Platforms/iPhoneOS.platform/Developer"
|
||||
export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH"
|
||||
export SDK="${BASEDIR}/SDKs/iPhoneOS.sdk"
|
||||
|
||||
## 64-bit iOS
|
||||
export CFLAGS="-O2 -arch arm64 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN} -flto -fembed-bitcode"
|
||||
export LDFLAGS="-arch arm64 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN} -flto -fembed-bitcode"
|
||||
|
||||
make distclean > /dev/null
|
||||
|
||||
./configure --host=arm-apple-darwin10 \
|
||||
--disable-shared \
|
||||
--enable-module-ecdh \
|
||||
--prefix="$IOS64_PREFIX" || exit 1
|
||||
|
||||
make -j3 install || exit 1
|
||||
|
||||
# Create universal binary and include folder
|
||||
rm -fr -- "$PREFIX/include" "$PREFIX/libsecp256k1.a" 2> /dev/null
|
||||
mkdir -p -- "$PREFIX/lib"
|
||||
lipo -create \
|
||||
"$SIMULATOR64_PREFIX/lib/libsecp256k1.a" \
|
||||
"$IOS64_PREFIX/lib/libsecp256k1.a" \
|
||||
-output "$PREFIX/lib/libsecp256k1.a"
|
||||
|
||||
echo
|
||||
echo "libsecp256k1 has been installed into $PREFIX"
|
||||
echo
|
||||
file -- "$PREFIX/lib/libsecp256k1.a"
|
||||
|
||||
# Cleanup
|
||||
rm -rf -- "$PREFIX/tmp"
|
||||
make distclean > /dev/null
|
27
node_modules/lnsocket/tools/secp-wasm.sh
generated
vendored
Executable file
27
node_modules/lnsocket/tools/secp-wasm.sh
generated
vendored
Executable file
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
cd deps/secp256k1
|
||||
|
||||
export CC=emcc
|
||||
export AR=emar
|
||||
export RANLIB=emranlib
|
||||
|
||||
export PREFIX="$(pwd)/libsecp256k1-wasm"
|
||||
|
||||
mkdir -p $PREFIX || exit 1
|
||||
|
||||
make distclean > /dev/null
|
||||
|
||||
patch -N -p1 < ../../tools/0001-configure-customizable-AR-and-RANLIB.patch
|
||||
|
||||
./configure --disable-shared \
|
||||
--disable-tests \
|
||||
--disable-exhaustive-tests \
|
||||
--disable-benchmark \
|
||||
--enable-module-ecdh \
|
||||
--prefix="$PREFIX"
|
||||
|
||||
make -j3 install || exit 1
|
||||
|
||||
rm -rf -- "$PREFIX/tmp"
|
||||
make distclean > /dev/null
|
13
node_modules/lnsocket/typedefs.h
generated
vendored
Normal file
13
node_modules/lnsocket/typedefs.h
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
#ifndef LNSOCKET_TYPES_H
|
||||
#define LNSOCKET_TYPES_H
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short u16;
|
||||
typedef uint64_t u64;
|
||||
typedef int64_t s64;
|
||||
|
||||
|
||||
#endif /* LNSOCKET_TYPES_H */
|
75
node_modules/lnsocket/varint.c
generated
vendored
Normal file
75
node_modules/lnsocket/varint.c
generated
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
|
||||
#include "varint.h"
|
||||
|
||||
size_t varint_size(uint64_t v)
|
||||
{
|
||||
if (v < 0xfd)
|
||||
return 1;
|
||||
if (v <= 0xffff)
|
||||
return 3;
|
||||
if (v <= 0xffffffff)
|
||||
return 5;
|
||||
return 9;
|
||||
}
|
||||
|
||||
size_t varint_put(unsigned char buf[VARINT_MAX_LEN], uint64_t v)
|
||||
{
|
||||
unsigned char *p = buf;
|
||||
|
||||
if (v < 0xfd) {
|
||||
*(p++) = v;
|
||||
} else if (v <= 0xffff) {
|
||||
(*p++) = 0xfd;
|
||||
(*p++) = v;
|
||||
(*p++) = v >> 8;
|
||||
} else if (v <= 0xffffffff) {
|
||||
(*p++) = 0xfe;
|
||||
(*p++) = v;
|
||||
(*p++) = v >> 8;
|
||||
(*p++) = v >> 16;
|
||||
(*p++) = v >> 24;
|
||||
} else {
|
||||
(*p++) = 0xff;
|
||||
(*p++) = v;
|
||||
(*p++) = v >> 8;
|
||||
(*p++) = v >> 16;
|
||||
(*p++) = v >> 24;
|
||||
(*p++) = v >> 32;
|
||||
(*p++) = v >> 40;
|
||||
(*p++) = v >> 48;
|
||||
(*p++) = v >> 56;
|
||||
}
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
size_t varint_get(const unsigned char *p, size_t max, int64_t *val)
|
||||
{
|
||||
if (max < 1)
|
||||
return 0;
|
||||
|
||||
switch (*p) {
|
||||
case 0xfd:
|
||||
if (max < 3)
|
||||
return 0;
|
||||
*val = ((uint64_t)p[2] << 8) + p[1];
|
||||
return 3;
|
||||
case 0xfe:
|
||||
if (max < 5)
|
||||
return 0;
|
||||
*val = ((uint64_t)p[4] << 24) + ((uint64_t)p[3] << 16)
|
||||
+ ((uint64_t)p[2] << 8) + p[1];
|
||||
return 5;
|
||||
case 0xff:
|
||||
if (max < 9)
|
||||
return 0;
|
||||
*val = ((uint64_t)p[8] << 56) + ((uint64_t)p[7] << 48)
|
||||
+ ((uint64_t)p[6] << 40) + ((uint64_t)p[5] << 32)
|
||||
+ ((uint64_t)p[4] << 24) + ((uint64_t)p[3] << 16)
|
||||
+ ((uint64_t)p[2] << 8) + p[1];
|
||||
return 9;
|
||||
default:
|
||||
*val = *p;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
14
node_modules/lnsocket/varint.h
generated
vendored
Normal file
14
node_modules/lnsocket/varint.h
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
#ifndef LNSOCKET_VARINT_H
|
||||
#define LNSOCKET_VARINT_H
|
||||
|
||||
#define VARINT_MAX_LEN 9
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
size_t varint_put(unsigned char buf[VARINT_MAX_LEN], uint64_t v);
|
||||
size_t varint_size(uint64_t v);
|
||||
size_t varint_get(const unsigned char *p, size_t max, int64_t *val);
|
||||
|
||||
#endif /* LNSOCKET_VARINT_H */
|
Loading…
Add table
Add a link
Reference in a new issue