1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 15:38:11 +00:00

Merge remote-tracking branch 'origin/master' into andrewkozlik/slip0039

This commit is contained in:
Andrew Kozlik 2019-04-29 11:29:54 +02:00
commit e631983d6d
200 changed files with 6760 additions and 4171 deletions

1
.gitignore vendored
View File

@ -6,3 +6,4 @@
.vscode/ .vscode/
__pycache__/ __pycache__/
*.pyc *.pyc
/build

30
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,30 @@
variables:
# Init submodules.
# See https://docs.gitlab.com/ee/ci/yaml/#git-submodule-strategy
GIT_SUBMODULE_STRATEGY: "recursive"
# Use shallow cloning to speed up git clone. This can fail, if retrying an older build on CI
# and the old commit is not in the shallow history any more.
# See https://docs.gitlab.com/ee/ci/yaml/#shallow-cloning
GIT_DEPTH: "50"
# run make paralel
MAKEFLAGS: "-j10"
stages:
- environment
- prebuild
- build
- test
before_script:
- pipenv install
include:
- ci/environment.yml
- ci/prebuild.yml # common, style
- ci/core.yml
- ci/legacy.yml
# - ci/python.yml TODO
- ci/crypto.yml
- ci/storage.yml

1
.gitmodules vendored
View File

@ -23,6 +23,7 @@
[submodule "legacy/vendor/nanopb"] [submodule "legacy/vendor/nanopb"]
path = legacy/vendor/nanopb path = legacy/vendor/nanopb
url = https://github.com/nanopb/nanopb.git url = https://github.com/nanopb/nanopb.git
ignore = untracked
[submodule "legacy/vendor/QR-Code-generator"] [submodule "legacy/vendor/QR-Code-generator"]
path = legacy/vendor/QR-Code-generator path = legacy/vendor/QR-Code-generator
url = https://github.com/nayuki/QR-Code-generator.git url = https://github.com/nayuki/QR-Code-generator.git

24
Makefile Normal file
View File

@ -0,0 +1,24 @@
## help commands:
help: ## show this help
@awk -f ./tools/help.awk $(MAKEFILE_LIST)
## style commands:
style_check: ## run code style check on application sources and tests
flake8 --version
isort --version | awk '/VERSION/{print $$2}'
black --version
flake8 $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude )
isort --check-only $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude )
black --check $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude )
style: ## apply code style on application sources and tests
isort $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude )
black $(shell find -type f -name '*.py' | grep -f ./tools/style.py.include | grep -v -f ./tools/style.py.exclude )
cstyle_check: ## run code style check on low-level C code
./tools/clang-format-check $(shell find -type f -name '*.c' -o -name '*.h' | grep -f ./tools/style.c.include | grep -v -f ./tools/style.c.exclude )
cstyle: ## apply code style on low-level C code
clang-format -i $(shell find -type f -name '*.c' -o -name '*.h' | grep -f ./tools/style.c.include | grep -v -f ./tools/style.c.exclude )

View File

@ -4,31 +4,49 @@ name = "pypi"
verify_ssl = true verify_ssl = true
[packages] [packages]
trezor = {git = "https://github.com/trezor/python-trezor", editable = true, ref = "master"} # all
trezor = {editable = true, path = "./python"}
scons = "*"
protobuf = "==3.4.0" protobuf = "==3.4.0"
pyblake2 = "*"
# python-trezor tests ## tests
pytest = "*" pytest = "*"
mock = "*" mock = "*"
## style
# make style
isort = "*" isort = "*"
flake8 = "*" flake8 = "*"
black = "*" black = "*"
mako = ">=1.0.7"
munch = ">=2.3.2"
# trezor-common cointool # common
demjson = "*"
graphviz = "*" # TODO this was '8' do we need that?
## cointool
click = ">=6" click = ">=6"
"ed25519" = ">=1.4" "ed25519" = ">=1.4"
requests = ">=2.19" requests = ">=2.19"
munch = ">=2.3.2"
termcolor = ">=0.1.2" termcolor = ">=0.1.2"
Pillow = ">=5.2.0" Pillow = ">=5.2.0"
Mako = ">=1.0.7"
# monero # crypto
ecdsa = "*"
curve25519-donna = "*"
pyasn1 = "*"
# core
## monero
monero_agent = {version = ">=2.0.1", extras = ["tcry", "dev"]} monero_agent = {version = ">=2.0.1", extras = ["tcry", "dev"]}
py_trezor_crypto_ph4 = {version = ">=0.1.1"} py_trezor_crypto_ph4 = {version = ">=0.1.1"}
# legacy
setuptools = ">=24.2.0"
typing = "*"
# storage
cryptography = "*"
hypothesis = "*"
[dev-packages] [dev-packages]
scan-build = "*" scan-build = "*"

View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "f038c016ebf0f0551ad1a2d066dd5861661925767b56bcf3c82b6764156b3b60" "sha256": "4c4b090a727ea8f5db592444bf5930bb9ec06898d5b58d7c4eba4fd9a1317ebb"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": {}, "requires": {},
@ -79,36 +79,36 @@
}, },
"cffi": { "cffi": {
"hashes": [ "hashes": [
"sha256:00b97afa72c233495560a0793cdc86c2571721b4271c0667addc83c417f3d90f", "sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774",
"sha256:0ba1b0c90f2124459f6966a10c03794082a2f3985cd699d7d63c4a8dae113e11", "sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d",
"sha256:0bffb69da295a4fc3349f2ec7cbe16b8ba057b0a593a92cbe8396e535244ee9d", "sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90",
"sha256:21469a2b1082088d11ccd79dd84157ba42d940064abbfa59cf5f024c19cf4891", "sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b",
"sha256:2e4812f7fa984bf1ab253a40f1f4391b604f7fc424a3e21f7de542a7f8f7aedf", "sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63",
"sha256:2eac2cdd07b9049dd4e68449b90d3ef1adc7c759463af5beb53a84f1db62e36c", "sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45",
"sha256:2f9089979d7456c74d21303c7851f158833d48fb265876923edcb2d0194104ed", "sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25",
"sha256:3dd13feff00bddb0bd2d650cdb7338f815c1789a91a6f68fdc00e5c5ed40329b", "sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3",
"sha256:4065c32b52f4b142f417af6f33a5024edc1336aa845b9d5a8d86071f6fcaac5a", "sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b",
"sha256:51a4ba1256e9003a3acf508e3b4f4661bebd015b8180cc31849da222426ef585", "sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647",
"sha256:59888faac06403767c0cf8cfb3f4a777b2939b1fbd9f729299b5384f097f05ea", "sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016",
"sha256:59c87886640574d8b14910840327f5cd15954e26ed0bbd4e7cef95fa5aef218f", "sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4",
"sha256:610fc7d6db6c56a244c2701575f6851461753c60f73f2de89c79bbf1cc807f33", "sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb",
"sha256:70aeadeecb281ea901bf4230c6222af0248c41044d6f57401a614ea59d96d145", "sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753",
"sha256:71e1296d5e66c59cd2c0f2d72dc476d42afe02aeddc833d8e05630a0551dad7a", "sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7",
"sha256:8fc7a49b440ea752cfdf1d51a586fd08d395ff7a5d555dc69e84b1939f7ddee3", "sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9",
"sha256:9b5c2afd2d6e3771d516045a6cfa11a8da9a60e3d128746a7fe9ab36dfe7221f", "sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f",
"sha256:9c759051ebcb244d9d55ee791259ddd158188d15adee3c152502d3b69005e6bd", "sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8",
"sha256:b4d1011fec5ec12aa7cc10c05a2f2f12dfa0adfe958e56ae38dc140614035804", "sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f",
"sha256:b4f1d6332339ecc61275bebd1f7b674098a66fea11a00c84d1c58851e618dc0d", "sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc",
"sha256:c030cda3dc8e62b814831faa4eb93dd9a46498af8cd1d5c178c2de856972fd92", "sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42",
"sha256:c2e1f2012e56d61390c0e668c20c4fb0ae667c44d6f6a2eeea5d7148dcd3df9f", "sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3",
"sha256:c37c77d6562074452120fc6c02ad86ec928f5710fbc435a181d69334b4de1d84", "sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909",
"sha256:c8149780c60f8fd02752d0429246088c6c04e234b895c4a42e1ea9b4de8d27fb", "sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45",
"sha256:cbeeef1dc3c4299bd746b774f019de9e4672f7cc666c777cd5b409f0b746dac7", "sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d",
"sha256:e113878a446c6228669144ae8a56e268c91b7f1fafae927adc4879d9849e0ea7", "sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512",
"sha256:e21162bf941b85c0cda08224dade5def9360f53b09f9f259adb85fc7dd0e7b35", "sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff",
"sha256:fb6934ef4744becbda3143d30c6604718871495a5e36c408431bf33d9c146889" "sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201"
], ],
"version": "==1.12.2" "version": "==1.12.3"
}, },
"chacha20poly1305": { "chacha20poly1305": {
"hashes": [ "hashes": [
@ -160,6 +160,7 @@
"sha256:d9ed28030797c00f4bc43c86bf819266c76a5ea61d006cd4078a93ebf7da6bfd", "sha256:d9ed28030797c00f4bc43c86bf819266c76a5ea61d006cd4078a93ebf7da6bfd",
"sha256:e603aa7bb52e4e8ed4119a58a03b60323918467ef209e6ff9db3ac382e5cf2c6" "sha256:e603aa7bb52e4e8ed4119a58a03b60323918467ef209e6ff9db3ac382e5cf2c6"
], ],
"index": "pypi",
"version": "==2.6.1" "version": "==2.6.1"
}, },
"ctypeslib2": { "ctypeslib2": {
@ -169,11 +170,26 @@
], ],
"version": "==2.2.2" "version": "==2.2.2"
}, },
"curve25519-donna": {
"hashes": [
"sha256:1818a9d5356a05c022cd504f44fe1d2f641a5c020f8a4c51b2294e02bd9c1bf0"
],
"index": "pypi",
"version": "==1.3"
},
"demjson": {
"hashes": [
"sha256:31de2038a0fdd9c4c11f8bf3b13fe77bc2a128307f965c8d5fb4dc6d6f6beb79"
],
"index": "pypi",
"version": "==2.2.4"
},
"ecdsa": { "ecdsa": {
"hashes": [ "hashes": [
"sha256:20c17e527e75acad8f402290e158a6ac178b91b881f941fc6ea305bfdfb9657c", "sha256:20c17e527e75acad8f402290e158a6ac178b91b881f941fc6ea305bfdfb9657c",
"sha256:5c034ffa23413ac923541ceb3ac14ec15a0d2530690413bff58c12b80e56d884" "sha256:5c034ffa23413ac923541ceb3ac14ec15a0d2530690413bff58c12b80e56d884"
], ],
"index": "pypi",
"version": "==0.13.2" "version": "==0.13.2"
}, },
"ed25519": { "ed25519": {
@ -205,6 +221,23 @@
"index": "pypi", "index": "pypi",
"version": "==3.7.7" "version": "==3.7.7"
}, },
"graphviz": {
"hashes": [
"sha256:0e1744a45b0d707bc44f99c7b8e5f25dc22cf96b6aaf2432ac308ed9822a9cb6",
"sha256:d311be4fddfe832a56986ac5e1d6e8715d7fcb0208560da79d1bb0f72abef41f"
],
"index": "pypi",
"version": "==0.10.1"
},
"hypothesis": {
"hashes": [
"sha256:4e1378aec40b109f2212f8416a0ef27635b40fdc22a7a8116cd5527776ce1f9e",
"sha256:63d33b2394410ab09a05a19354d826e2aa7814288b0800eb5e89857181def40a",
"sha256:905395b9da7fe04e5ce32b41eace83b613586a104db4b4b0a2552db980a40dd2"
],
"index": "pypi",
"version": "==4.18.0"
},
"idna": { "idna": {
"hashes": [ "hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
@ -441,6 +474,14 @@
"index": "pypi", "index": "pypi",
"version": "==0.1.1" "version": "==0.1.1"
}, },
"pyasn1": {
"hashes": [
"sha256:da2420fe13a9452d8ae97a0e478adde1dee153b11ba832a95b223a2ba01c10f7",
"sha256:da6b43a8c9ae93bc80e2739efb38cc776ba74a886e3e9318d65fe81a8b8a2c6e"
],
"index": "pypi",
"version": "==0.4.5"
},
"pyblake2": { "pyblake2": {
"hashes": [ "hashes": [
"sha256:3757f7ad709b0e1b2a6b3919fa79fe3261f166fc375cd521f2be480f8319dde9", "sha256:3757f7ad709b0e1b2a6b3919fa79fe3261f166fc375cd521f2be480f8319dde9",
@ -453,6 +494,7 @@
"sha256:c53417ee0bbe77db852d5fd1036749f03696ebc2265de359fe17418d800196c4", "sha256:c53417ee0bbe77db852d5fd1036749f03696ebc2265de359fe17418d800196c4",
"sha256:fbc9fcde75713930bc2a91b149e97be2401f7c9c56d735b46a109210f58d7358" "sha256:fbc9fcde75713930bc2a91b149e97be2401f7c9c56d735b46a109210f58d7358"
], ],
"index": "pypi",
"version": "==1.1.2" "version": "==1.1.2"
}, },
"pycodestyle": { "pycodestyle": {
@ -543,6 +585,14 @@
"index": "pypi", "index": "pypi",
"version": "==2.21.0" "version": "==2.21.0"
}, },
"scons": {
"hashes": [
"sha256:8c2353ae3ce559e9361baa254c0c85d3eb099d5f96e44b5bc586801b7c756a06",
"sha256:e95eaae17d9e490cf12cd37f091a6cbee8a628b5c8dbd3cab1f348f602f46462"
],
"index": "pypi",
"version": "==3.0.5"
},
"shlib": { "shlib": {
"hashes": [ "hashes": [
"sha256:f9798b0a3e37407171f06efca7c213269f034eee2c94dd9933a819730a6d528b" "sha256:f9798b0a3e37407171f06efca7c213269f034eee2c94dd9933a819730a6d528b"
@ -579,8 +629,16 @@
}, },
"trezor": { "trezor": {
"editable": true, "editable": true,
"git": "https://github.com/trezor/python-trezor", "path": "./python"
"ref": "2813522b05cef4e0e545a101f8b3559a3183b45b" },
"typing": {
"hashes": [
"sha256:4027c5f6127a6267a435201981ba156de91ad0d1d98e9ddc2aa173453453492d",
"sha256:57dcf675a99b74d64dacf6fba08fb17cf7e3d5fdff53d4a30ea2a5e7e52543d4",
"sha256:a4c8473ce11a65999c8f59cb093e70686b6c84c98df58c1dae9b3b196089858a"
],
"index": "pypi",
"version": "==3.6.6"
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
@ -599,10 +657,10 @@
}, },
"virtualenv": { "virtualenv": {
"hashes": [ "hashes": [
"sha256:6aebaf4dd2568a0094225ebbca987859e369e3e5c22dc7d52e5406d504890417", "sha256:15ee248d13e4001a691d9583948ad3947bcb8a289775102e4c4aa98a8b7a6d73",
"sha256:984d7e607b0a5d1329425dd8845bd971b957424b5ba664729fab51ab8c11bc39" "sha256:bfc98bb9b42a3029ee41b96dc00a34c2f254cbf7716bec824477b2c82741a5c4"
], ],
"version": "==16.4.3" "version": "==16.5.0"
}, },
"wheel": { "wheel": {
"hashes": [ "hashes": [
@ -626,6 +684,7 @@
"sha256:57dcf675a99b74d64dacf6fba08fb17cf7e3d5fdff53d4a30ea2a5e7e52543d4", "sha256:57dcf675a99b74d64dacf6fba08fb17cf7e3d5fdff53d4a30ea2a5e7e52543d4",
"sha256:a4c8473ce11a65999c8f59cb093e70686b6c84c98df58c1dae9b3b196089858a" "sha256:a4c8473ce11a65999c8f59cb093e70686b6c84c98df58c1dae9b3b196089858a"
], ],
"index": "pypi",
"version": "==3.6.6" "version": "==3.6.6"
} }
} }

View File

@ -1,17 +1,17 @@
# initialize from the image # initialize from the image
FROM debian:9 FROM python
ARG TOOLCHAIN_FLAVOR=linux ARG TOOLCHAIN_FLAVOR=linux
ENV TOOLCHAIN_FLAVOR=$TOOLCHAIN_FLAVOR ENV TOOLCHAIN_FLAVOR=$TOOLCHAIN_FLAVOR
# install build tools and dependencies # install build tools and dependencies
ARG EMULATOR=0
ENV EMULATOR=$EMULATOR
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
build-essential wget git python3-pip build-essential wget git libsodium-dev graphviz \
valgrind check libssl-dev libusb-1.0-0-dev libudev-dev
# TODO are all apt packages actually needed?
# install dependencies from toolchain source build # install dependencies from toolchain source build
@ -31,10 +31,6 @@ ENV TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-rm/$TOOL
ENV TOOLCHAIN_HASH_linux=fb31fbdfe08406ece43eef5df623c0b2deb8b53e405e2c878300f7a1f303ee52 ENV TOOLCHAIN_HASH_linux=fb31fbdfe08406ece43eef5df623c0b2deb8b53e405e2c878300f7a1f303ee52
ENV TOOLCHAIN_HASH_src=bc228325dbbfaf643f2ee5d19e01d8b1873fcb9c31781b5e1355d40a68704ce7 ENV TOOLCHAIN_HASH_src=bc228325dbbfaf643f2ee5d19e01d8b1873fcb9c31781b5e1355d40a68704ce7
RUN if [ "$EMULATOR" = 1 ]; then \
apt-get install -y libsdl2-dev libsdl2-image-dev; \
fi
# extract toolchain # extract toolchain
RUN cd /opt && wget $TOOLCHAIN_URL RUN cd /opt && wget $TOOLCHAIN_URL
@ -64,14 +60,19 @@ RUN echo "${PROTOBUF_HASH} protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" | sha256
ENV PATH=/opt/$TOOLCHAIN_LONGVER/bin:$PATH ENV PATH=/opt/$TOOLCHAIN_LONGVER/bin:$PATH
ENV PYTHON=python3
ENV LC_ALL=C.UTF-8 LANG=C.UTF-8 ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
# use zipfile module to extract files world-readable # use zipfile module to extract files world-readable
ENV PYTHON=python
RUN $PYTHON -m zipfile -e "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" /usr/local && chmod 755 /usr/local/bin/protoc RUN $PYTHON -m zipfile -e "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" /usr/local && chmod 755 /usr/local/bin/protoc
ENV WORKON_HOME=/tmp/.venvs ENV WORKON_HOME=/tmp/.venvs
# install python dependencies # install python dependencies
RUN $PYTHON -m pip install pipenv RUN pip install pipenv
RUN $PYTHON --version
RUN pip --version
RUN pipenv --version

58
ci/core.yml Normal file
View File

@ -0,0 +1,58 @@
image: registry.corp.sldev.cz/trezor/trezor-firmware/environment
build core firmware:
stage: build
script:
- cd core
- pipenv run make build_cross
- pipenv run make build_boardloader
- pipenv run make build_bootloader
- pipenv run make build_prodtest
- pipenv run make build_firmware
# - test "$TREZOR_MODEL" = "1" || pipenv run make sizecheck
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA"
paths:
- core/build/firmware/firmware.bin
- core/build/bootloader/bootloader.bin
expire_in: 1 week
build core unix:
stage: build
script:
- cd core
- pipenv run make build_unix_noui
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA"
untracked: true
expire_in: 1 day
test core unix unit:
stage: test
variables:
GIT_SUBMODULE_STRATEGY: none # no need to fetch submodules
dependencies:
- build core unix
script:
- cd core
- pipenv run make test
test core unix device:
stage: test
variables:
GIT_SUBMODULE_STRATEGY: none # no need to fetch submodules
dependencies:
- build core unix
script:
- cd core
- pipenv run make test_emu
test core unix monero:
stage: test
variables:
GIT_SUBMODULE_STRATEGY: none # no need to fetch submodules
dependencies:
- build core unix
script:
- cd core
- pipenv run make test_emu_monero

23
ci/crypto.yml Normal file
View File

@ -0,0 +1,23 @@
image: registry.corp.sldev.cz/trezor/trezor-firmware/environment
build crypto:
stage: build
script:
- cd crypto
- pipenv run make
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA"
untracked: true
expire_in: 1 day
test crypto:
stage: test
dependencies:
- build crypto
script:
- cd crypto
- ./tests/aestst
- ./tests/test_check
- CK_TIMEOUT_MULTIPLIER=20 valgrind -q --error-exitcode=1 ./tests/test_check
- ./tests/test_openssl 1000
- ITERS=10 pipenv run pytest tests/ # TODO are ITERS=10 propagated?

16
ci/environment.yml Normal file
View File

@ -0,0 +1,16 @@
environment:
stage: environment
image: docker:latest
variables:
GIT_SUBMODULE_STRATEGY: none # no need to fetch submodules
CONTAINER_NAME: "$CI_REGISTRY/trezor/trezor-firmware/environment"
services:
- docker:dind
before_script:
- docker login $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
when: manual
script:
- docker pull $CONTAINER_NAME:latest || true
- docker build --cache-from $CONTAINER_NAME:latest --tag $CONTAINER_NAME:$CI_COMMIT_SHA --tag $CONTAINER_NAME:latest ci/
- docker push $CONTAINER_NAME:$CI_COMMIT_SHA
- docker push $CONTAINER_NAME:latest

56
ci/legacy.yml Normal file
View File

@ -0,0 +1,56 @@
image: registry.corp.sldev.cz/trezor/trezor-firmware/environment
build legacy firmware:
stage: build
script:
- cd legacy
- pipenv run script/cibuild
- pipenv run make -C bootloader
- pipenv run make -C demo
build legacy firmware debug:
stage: build
variables:
DEBUG_LINK: "1"
script:
- cd legacy
- pipenv run script/cibuild
- pipenv run make -C bootloader
- pipenv run make -C demo
build legacy firmware bitcoinonly:
stage: build
variables:
BITCOIN_ONLY: "1"
script:
- cd legacy
- pipenv run script/cibuild
- pipenv run make -C bootloader
- pipenv run make -C demo
build legacy emu:
stage: build
variables:
HEADLESS: "1"
EMULATOR: "1"
DEBUG_LINK: "1"
script:
- cd legacy
- pipenv run script/cibuild
artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA"
untracked: true
expire_in: 1 day
# TODO: aren't some tests from .travis.yml missing?
test legacy emu:
variables:
GIT_SUBMODULE_STRATEGY: none # no need to fetch submodules
stage: test
dependencies:
- build legacy emu
variables:
EMULATOR: "1"
script:
- cd legacy
- pipenv run script/test

18
ci/prebuild.yml Normal file
View File

@ -0,0 +1,18 @@
image: registry.corp.sldev.cz/trezor/trezor-firmware/environment
prebuild style:
stage: prebuild
script:
- pipenv run make style_check
- cd core && pipenv run make templates_check # TODO
prebuild common:
stage: prebuild
script:
- cd common
- pipenv run jsonlint defs/*.json
- pipenv run jsonlint defs/*/*.json
- pipenv run python tools/cointool.py check
- pipenv run python tools/support.py check --ignore-missing
- pipenv run python protob/check.py
- pipenv run python protob/graph.py protob/*.proto # TODO: artifacts?

11
ci/storage.yml Normal file
View File

@ -0,0 +1,11 @@
image: registry.corp.sldev.cz/trezor/trezor-firmware/environment
test storage:
variables:
GIT_SUBMODULE_STRATEGY: none # no need to fetch submodules
stage: test
dependencies: []
script:
- cd storage/tests
- pipenv run make build
- pipenv run make tests_all

View File

@ -1,37 +0,0 @@
language: python
# Runs jobs on container based infrastructure
sudo: false
# Saves pip downloads/wheels between builds
cache:
directories:
- $HOME/.cache/pip
addons:
apt:
packages:
- graphviz
python:
- "3.6"
install:
- pip install demjson graphviz
- pip install -r tools/requirements.txt
script:
- jsonlint defs/*.json
- jsonlint defs/*/*.json
- python tools/cointool.py check
- python tools/support.py check --ignore-missing
- python protob/check.py
- python protob/graph.py protob/*.proto
notifications:
webhooks:
urls:
- http://ci-bot.satoshilabs.com:5000/travis
on_success: always
on_failure: always
on_start: always

View File

@ -0,0 +1,42 @@
{
"coin_name": "BlockStamp",
"coin_shortcut": "BST",
"coin_label": "BlockStamp",
"website": "https://blockstamp.info",
"github": "https://github.com/BlockStamp/bst",
"maintainer": "Krzysztof Kuchta <k.kuchta@blockstamp.info>",
"curve_name": "secp256k1",
"address_type": 26,
"address_type_p2sh": 5,
"maxfee_kb": 2000000,
"minfee_kb": 1000,
"signed_message_header": "BST Signed Message:\n",
"hash_genesis_block": "8000000049a2e26b0185be50b4b8ed58b707c8893762959f0b1673641cae1828",
"xprv_magic": 76066276,
"xpub_magic": 76067358,
"xpub_magic_segwit_p2sh": 77429938,
"xpub_magic_segwit_native": 78792518,
"bech32_prefix": "bst",
"cashaddr_prefix": null,
"slip44": 254,
"segwit": true,
"decred": false,
"fork_id": null,
"force_bip143": false,
"bip115": false,
"default_fee_b": {
"Low": 10,
"Economy": 70,
"Normal": 140,
"High": 200
},
"dust_limit": 546,
"blocktime_seconds": 60,
"uri_prefix": "blockstamp",
"min_address_length": 27,
"max_address_length": 34,
"bitcore": [],
"blockbook": [],
"cooldown": 1000,
"consensus_branch_id": null
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -8,8 +8,8 @@
"curve_name": "secp256k1", "curve_name": "secp256k1",
"address_type": 36, "address_type": 36,
"address_type_p2sh": 16, "address_type_p2sh": 16,
"maxfee_kb": 10000000, "maxfee_kb": 1000000000,
"minfee_kb": 100000, "minfee_kb": 10000000,
"signed_message_header": "FujiCoin Signed Message:\n", "signed_message_header": "FujiCoin Signed Message:\n",
"hash_genesis_block": "adb6d9cfd74075e7f91608add4bd2a2ea636f70856183086842667a1597714a0", "hash_genesis_block": "adb6d9cfd74075e7f91608add4bd2a2ea636f70856183086842667a1597714a0",
"xpub_magic": 76067358, "xpub_magic": 76067358,
@ -25,10 +25,10 @@
"force_bip143": false, "force_bip143": false,
"bip115": false, "bip115": false,
"default_fee_b": { "default_fee_b": {
"Low": 100, "Low": 10000,
"Economy": 200, "Economy": 20000,
"Normal": 500, "Normal": 50000,
"High": 1000 "High": 100000
}, },
"dust_limit": 546, "dust_limit": 546,
"blocktime_seconds": 60, "blocktime_seconds": 60,

View File

@ -96,6 +96,7 @@
"bitcoin:BCH": "1.6.2", "bitcoin:BCH": "1.6.2",
"bitcoin:BITC": "1.7.2", "bitcoin:BITC": "1.7.2",
"bitcoin:BSD": "1.7.2", "bitcoin:BSD": "1.7.2",
"bitcoin:BST": "soon",
"bitcoin:BTC": "1.5.2", "bitcoin:BTC": "1.5.2",
"bitcoin:BTCP": "1.6.2", "bitcoin:BTCP": "1.6.2",
"bitcoin:BTDX": "1.7.2", "bitcoin:BTDX": "1.7.2",
@ -106,6 +107,7 @@
"bitcoin:DGB": "1.6.3", "bitcoin:DGB": "1.6.3",
"bitcoin:DNR": "1.7.1", "bitcoin:DNR": "1.7.1",
"bitcoin:DOGE": "1.5.2", "bitcoin:DOGE": "1.5.2",
"bitcoin:FAIR": "soon",
"bitcoin:FJC": "1.6.1", "bitcoin:FJC": "1.6.1",
"bitcoin:FLASH": "1.7.1", "bitcoin:FLASH": "1.7.1",
"bitcoin:FLO": "1.7.2", "bitcoin:FLO": "1.7.2",
@ -122,8 +124,10 @@
"bitcoin:NIX": "1.7.2", "bitcoin:NIX": "1.7.2",
"bitcoin:NMC": "1.5.2", "bitcoin:NMC": "1.5.2",
"bitcoin:PIVX": "1.8.0", "bitcoin:PIVX": "1.8.0",
"bitcoin:POLIS": "soon",
"bitcoin:PTC": "1.7.1", "bitcoin:PTC": "1.7.1",
"bitcoin:QTUM": "1.8.1", "bitcoin:QTUM": "1.8.1",
"bitcoin:REGTEST": "1.8.2",
"bitcoin:RVN": "1.7.2", "bitcoin:RVN": "1.7.2",
"bitcoin:SMART": "1.7.1", "bitcoin:SMART": "1.7.1",
"bitcoin:TAZ": "1.6.2", "bitcoin:TAZ": "1.6.2",
@ -135,6 +139,7 @@
"bitcoin:VTC": "1.6.1", "bitcoin:VTC": "1.6.1",
"bitcoin:XMY": "1.7.1", "bitcoin:XMY": "1.7.1",
"bitcoin:XPM": "1.8.0", "bitcoin:XPM": "1.8.0",
"bitcoin:XRC": "soon",
"bitcoin:XSN": "1.8.0", "bitcoin:XSN": "1.8.0",
"bitcoin:XZC": "1.6.2", "bitcoin:XZC": "1.6.2",
"bitcoin:ZCL": "1.8.0", "bitcoin:ZCL": "1.8.0",
@ -284,7 +289,6 @@
"erc20:eth:BRD": "1.6.2", "erc20:eth:BRD": "1.6.2",
"erc20:eth:BRLN": "1.8.0", "erc20:eth:BRLN": "1.8.0",
"erc20:eth:BSDC": "1.6.2", "erc20:eth:BSDC": "1.6.2",
"erc20:eth:BST": "1.6.2",
"erc20:eth:BTCA": "1.8.0", "erc20:eth:BTCA": "1.8.0",
"erc20:eth:BTCE": "1.6.2", "erc20:eth:BTCE": "1.6.2",
"erc20:eth:BTCL": "1.6.2", "erc20:eth:BTCL": "1.6.2",
@ -1232,9 +1236,11 @@
"eth:ETC": "1.6.2", "eth:ETC": "1.6.2",
"eth:ETH": "1.6.2", "eth:ETH": "1.6.2",
"eth:ETHO": "1.6.3", "eth:ETHO": "1.6.3",
"eth:ETI": "soon",
"eth:ETSC": "1.6.2", "eth:ETSC": "1.6.2",
"eth:EXP": "1.6.2", "eth:EXP": "1.6.2",
"eth:GO": "1.6.2", "eth:GO": "1.6.2",
"eth:META": "soon",
"eth:MIX": "1.7.2", "eth:MIX": "1.7.2",
"eth:MUSIC": "1.6.3", "eth:MUSIC": "1.6.3",
"eth:PIRL": "1.6.3", "eth:PIRL": "1.6.3",
@ -1261,6 +1267,7 @@
"nem:XEM": "1.6.2" "nem:XEM": "1.6.2"
}, },
"unsupported": { "unsupported": {
"bitcoin:CPC": "not implemented",
"bitcoin:CRW": "address_type collides with Bitcoin", "bitcoin:CRW": "address_type collides with Bitcoin",
"bitcoin:TRC": "address_type collides with Bitcoin", "bitcoin:TRC": "address_type collides with Bitcoin",
"bitcoin:ZEN": "not implemented", "bitcoin:ZEN": "not implemented",
@ -1278,6 +1285,7 @@
"erc20:eth:BNC:ef51": "(AUTO) duplicate key", "erc20:eth:BNC:ef51": "(AUTO) duplicate key",
"erc20:eth:BOX:63f5": "(AUTO) duplicate key", "erc20:eth:BOX:63f5": "(AUTO) duplicate key",
"erc20:eth:BOX:e1a1": "(AUTO) duplicate key", "erc20:eth:BOX:e1a1": "(AUTO) duplicate key",
"erc20:eth:BST": "(AUTO) duplicate key",
"erc20:eth:BTL (Battle)": "(AUTO) duplicate key", "erc20:eth:BTL (Battle)": "(AUTO) duplicate key",
"erc20:eth:BTL (Bitlle)": "(AUTO) duplicate key", "erc20:eth:BTL (Bitlle)": "(AUTO) duplicate key",
"erc20:eth:BTR:499a": "(AUTO) duplicate key", "erc20:eth:BTR:499a": "(AUTO) duplicate key",
@ -1417,12 +1425,14 @@
"erc20:eth:YEED:6f7a": "(AUTO) duplicate key", "erc20:eth:YEED:6f7a": "(AUTO) duplicate key",
"erc20:eth:YEED:ca27": "(AUTO) duplicate key", "erc20:eth:YEED:ca27": "(AUTO) duplicate key",
"misc:ADA": "not implemented", "misc:ADA": "not implemented",
"misc:BNB": "not implemented",
"misc:EOS": "not implemented", "misc:EOS": "not implemented",
"misc:ONT": "not implemented", "misc:ONT": "not implemented",
"misc:TRX": "not implemented", "misc:TRX": "not implemented",
"misc:XMR": "not implemented", "misc:XMR": "not implemented",
"misc:XRP": "not implemented", "misc:XRP": "not implemented",
"misc:XTZ": "not implemented" "misc:XTZ": "not implemented",
"misc:tXRP": "not implemented"
} }
}, },
"trezor2": { "trezor2": {
@ -1432,6 +1442,7 @@
"bitcoin:BCH": "2.0.7", "bitcoin:BCH": "2.0.7",
"bitcoin:BITC": "2.0.10", "bitcoin:BITC": "2.0.10",
"bitcoin:BSD": "2.0.10", "bitcoin:BSD": "2.0.10",
"bitcoin:BST": "soon",
"bitcoin:BTC": "2.0.5", "bitcoin:BTC": "2.0.5",
"bitcoin:BTCP": "2.0.7", "bitcoin:BTCP": "2.0.7",
"bitcoin:BTDX": "2.0.10", "bitcoin:BTDX": "2.0.10",
@ -1443,6 +1454,7 @@
"bitcoin:DGB": "2.0.7", "bitcoin:DGB": "2.0.7",
"bitcoin:DNR": "2.0.8", "bitcoin:DNR": "2.0.8",
"bitcoin:DOGE": "2.0.5", "bitcoin:DOGE": "2.0.5",
"bitcoin:FAIR": "soon",
"bitcoin:FJC": "2.0.5", "bitcoin:FJC": "2.0.5",
"bitcoin:FLASH": "2.0.8", "bitcoin:FLASH": "2.0.8",
"bitcoin:FLO": "2.0.11", "bitcoin:FLO": "2.0.11",
@ -1459,8 +1471,10 @@
"bitcoin:NIX": "2.0.11", "bitcoin:NIX": "2.0.11",
"bitcoin:NMC": "2.0.5", "bitcoin:NMC": "2.0.5",
"bitcoin:PIVX": "2.0.11", "bitcoin:PIVX": "2.0.11",
"bitcoin:POLIS": "soon",
"bitcoin:PTC": "2.0.8", "bitcoin:PTC": "2.0.8",
"bitcoin:QTUM": "2.1.1", "bitcoin:QTUM": "2.1.1",
"bitcoin:REGTEST": "2.1.2",
"bitcoin:RVN": "2.0.10", "bitcoin:RVN": "2.0.10",
"bitcoin:SMART": "2.0.8", "bitcoin:SMART": "2.0.8",
"bitcoin:TAZ": "2.0.7", "bitcoin:TAZ": "2.0.7",
@ -1472,6 +1486,7 @@
"bitcoin:VTC": "2.0.5", "bitcoin:VTC": "2.0.5",
"bitcoin:XMY": "2.0.8", "bitcoin:XMY": "2.0.8",
"bitcoin:XPM": "2.0.11", "bitcoin:XPM": "2.0.11",
"bitcoin:XRC": "soon",
"bitcoin:XSN": "2.0.11", "bitcoin:XSN": "2.0.11",
"bitcoin:XZC": "2.0.7", "bitcoin:XZC": "2.0.7",
"bitcoin:ZCL": "2.0.11", "bitcoin:ZCL": "2.0.11",
@ -1622,7 +1637,6 @@
"erc20:eth:BRD": "2.0.7", "erc20:eth:BRD": "2.0.7",
"erc20:eth:BRLN": "2.0.10", "erc20:eth:BRLN": "2.0.10",
"erc20:eth:BSDC": "2.0.7", "erc20:eth:BSDC": "2.0.7",
"erc20:eth:BST": "2.0.7",
"erc20:eth:BTCA": "2.0.10", "erc20:eth:BTCA": "2.0.10",
"erc20:eth:BTCE": "2.0.7", "erc20:eth:BTCE": "2.0.7",
"erc20:eth:BTCL": "2.0.7", "erc20:eth:BTCL": "2.0.7",
@ -2570,9 +2584,11 @@
"eth:ETC": "2.0.7", "eth:ETC": "2.0.7",
"eth:ETH": "2.0.7", "eth:ETH": "2.0.7",
"eth:ETHO": "2.0.8", "eth:ETHO": "2.0.8",
"eth:ETI": "soon",
"eth:ETSC": "2.0.7", "eth:ETSC": "2.0.7",
"eth:EXP": "2.0.7", "eth:EXP": "2.0.7",
"eth:GO": "2.0.7", "eth:GO": "2.0.7",
"eth:META": "soon",
"eth:MIX": "2.0.10", "eth:MIX": "2.0.10",
"eth:MUSIC": "2.0.8", "eth:MUSIC": "2.0.8",
"eth:PIRL": "2.0.8", "eth:PIRL": "2.0.8",
@ -2620,6 +2636,7 @@
"erc20:eth:BNC:ef51": "(AUTO) duplicate key", "erc20:eth:BNC:ef51": "(AUTO) duplicate key",
"erc20:eth:BOX:63f5": "(AUTO) duplicate key", "erc20:eth:BOX:63f5": "(AUTO) duplicate key",
"erc20:eth:BOX:e1a1": "(AUTO) duplicate key", "erc20:eth:BOX:e1a1": "(AUTO) duplicate key",
"erc20:eth:BST": "(AUTO) duplicate key",
"erc20:eth:BTL (Battle)": "(AUTO) duplicate key", "erc20:eth:BTL (Battle)": "(AUTO) duplicate key",
"erc20:eth:BTL (Bitlle)": "(AUTO) duplicate key", "erc20:eth:BTL (Bitlle)": "(AUTO) duplicate key",
"erc20:eth:BTR:499a": "(AUTO) duplicate key", "erc20:eth:BTR:499a": "(AUTO) duplicate key",

View File

@ -1,13 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import json
import sys import sys
from glob import glob from glob import glob
import json
from hashlib import sha256 from hashlib import sha256
try: try:
opt = sys.argv[1] opt = sys.argv[1]
except: except IndexError:
print("Usage: gen.py [core|mcu|check])") print("Usage: gen.py [core|mcu|check])")
sys.exit(1) sys.exit(1)
@ -22,12 +21,12 @@ def gen_core(data):
for d in data: for d in data:
if "u2f" in d: if "u2f" in d:
url, label = d["u2f"], d["label"] url, label = d["u2f"], d["label"]
print(" \"%s\": \"%s\"," % (url, label)) print(' "%s": "%s",' % (url, label))
print(" # WebAuthn") print(" # WebAuthn")
for d in data: for d in data:
if "webauthn" in d: if "webauthn" in d:
origin, label = d["webauthn"], d["label"] origin, label = d["webauthn"], d["label"]
print(" \"%s\": \"%s\"," % (origin, label)) print(' "%s": "%s",' % (origin, label))
print("}") print("}")
@ -36,12 +35,17 @@ def gen_mcu(data):
if "u2f" in d: if "u2f" in d:
url, label = d["u2f"], d["label"] url, label = d["u2f"], d["label"]
h = sha256(url.encode()).digest() h = sha256(url.encode()).digest()
print("\t{\n\t\t// U2F: %s\n\t\t%s,\n\t\t\"%s\"\n\t}," % (url, c_bytes(h), label)) print(
'\t{\n\t\t// U2F: %s\n\t\t%s,\n\t\t"%s"\n\t},'
% (url, c_bytes(h), label)
)
if "webauthn" in d: if "webauthn" in d:
origin, label = d["webauthn"], d["label"] origin, label = d["webauthn"], d["label"]
h = sha256(origin.encode()).digest() h = sha256(origin.encode()).digest()
print("\t{\n\t\t// WebAuthn: %s\n\t\t%s,\n\t\t\"%s\"\n\t}," % (origin, c_bytes(h), label)) print(
'\t{\n\t\t// WebAuthn: %s\n\t\t%s,\n\t\t"%s"\n\t},'
% (origin, c_bytes(h), label)
)
data = [] data = []

View File

@ -1,3 +1,4 @@
// clang-format off
// TREZORv1 production public keys // TREZORv1 production public keys
"\x04\xd5\x71\xb7\xf1\x48\xc5\xe4\x23\x2c\x38\x14\xf7\x77\xd8\xfa\xea\xf1\xa8\x42\x16\xc7\x8d\x56\x9b\x71\x04\x1f\xfc\x76\x8a\x5b\x2d\x81\x0f\xc3\xbb\x13\x4d\xd0\x26\xb5\x7e\x65\x00\x52\x75\xae\xde\xf4\x3e\x15\x5f\x48\xfc\x11\xa3\x2e\xc7\x90\xa9\x33\x12\xbd\x58", "\x04\xd5\x71\xb7\xf1\x48\xc5\xe4\x23\x2c\x38\x14\xf7\x77\xd8\xfa\xea\xf1\xa8\x42\x16\xc7\x8d\x56\x9b\x71\x04\x1f\xfc\x76\x8a\x5b\x2d\x81\x0f\xc3\xbb\x13\x4d\xd0\x26\xb5\x7e\x65\x00\x52\x75\xae\xde\xf4\x3e\x15\x5f\x48\xfc\x11\xa3\x2e\xc7\x90\xa9\x33\x12\xbd\x58",
"\x04\x63\x27\x9c\x0c\x08\x66\xe5\x0c\x05\xc7\x99\xd3\x2b\xd6\xba\xb0\x18\x8b\x6d\xe0\x65\x36\xd1\x10\x9d\x2e\xd9\xce\x76\xcb\x33\x5c\x49\x0e\x55\xae\xe1\x0c\xc9\x01\x21\x51\x32\xe8\x53\x09\x7d\x54\x32\xed\xa0\x6b\x79\x20\x73\xbd\x77\x40\xc9\x4c\xe4\x51\x6c\xb1", "\x04\x63\x27\x9c\x0c\x08\x66\xe5\x0c\x05\xc7\x99\xd3\x2b\xd6\xba\xb0\x18\x8b\x6d\xe0\x65\x36\xd1\x10\x9d\x2e\xd9\xce\x76\xcb\x33\x5c\x49\x0e\x55\xae\xe1\x0c\xc9\x01\x21\x51\x32\xe8\x53\x09\x7d\x54\x32\xed\xa0\x6b\x79\x20\x73\xbd\x77\x40\xc9\x4c\xe4\x51\x6c\xb1",

View File

@ -1,2 +1,3 @@
// clang-format off
// sample public key "correct horse battery staple" // sample public key "correct horse battery staple"
"\x04\x78\xd4\x30\x27\x4f\x8c\x5e\xc1\x32\x13\x38\x15\x1e\x9f\x27\xf4\xc6\x76\xa0\x08\xbd\xf8\x63\x8d\x07\xc0\xb6\xbe\x9a\xb3\x5c\x71\xa1\x51\x80\x63\x24\x3a\xcd\x4d\xfe\x96\xb6\x6e\x3f\x2e\xc8\x01\x3c\x8e\x07\x2c\xd0\x9b\x38\x34\xa1\x9f\x81\xf6\x59\xcc\x34\x55" "\x04\x78\xd4\x30\x27\x4f\x8c\x5e\xc1\x32\x13\x38\x15\x1e\x9f\x27\xf4\xc6\x76\xa0\x08\xbd\xf8\x63\x8d\x07\xc0\xb6\xbe\x9a\xb3\x5c\x71\xa1\x51\x80\x63\x24\x3a\xcd\x4d\xfe\x96\xb6\x6e\x3f\x2e\xc8\x01\x3c\x8e\x07\x2c\xd0\x9b\x38\x34\xa1\x9f\x81\xf6\x59\xcc\x34\x55"

View File

@ -1,8 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from glob import glob
import os import os
import re import re
import sys import sys
from glob import glob
error = False error = False
@ -21,7 +21,9 @@ for fn in sorted(glob(os.path.join(MYDIR, "messages-*.proto"))):
line = line.strip().split(" ") line = line.strip().split(" ")
if line[0] not in ["enum", "message"]: if line[0] not in ["enum", "message"]:
continue continue
if not line[1].startswith(prefix) and not line[1].startswith("Debug" + prefix): if not line[1].startswith(prefix) and not line[1].startswith(
"Debug" + prefix
):
print("ERROR:", fn, line[1]) print("ERROR:", fn, line[1])
error = True error = True

View File

@ -55,6 +55,8 @@ message TezosSignTx {
optional TezosTransactionOp transaction = 4; // Tezos transaction operation optional TezosTransactionOp transaction = 4; // Tezos transaction operation
optional TezosOriginationOp origination = 5; // Tezos origination operation optional TezosOriginationOp origination = 5; // Tezos origination operation
optional TezosDelegationOp delegation = 6; // Tezos delegation operation optional TezosDelegationOp delegation = 6; // Tezos delegation operation
optional TezosProposalOp proposal = 7; // Tezos proposal operation
optional TezosBallotOp ballot = 8; // Tezos ballot operation
/* /*
* Tezos contract ID * Tezos contract ID
*/ */
@ -120,6 +122,29 @@ message TezosSignTx {
optional uint64 storage_limit = 5; optional uint64 storage_limit = 5;
optional bytes delegate = 6; optional bytes delegate = 6;
} }
/**
* Structure representing information for proposal
*/
message TezosProposalOp {
optional bytes source = 1; //Contains only public_key_hash, not to be confused with TezosContractID
optional uint64 period = 2;
repeated bytes proposals = 4;
}
/**
* Structure representing information for ballot
*/
message TezosBallotOp {
optional bytes source = 1; //Contains only public_key_hash, not to be confused with TezosContractID
optional uint64 period = 2;
optional bytes proposal = 3;
optional TezosBallotType ballot = 4;
enum TezosBallotType {
Yay = 0;
Nay = 1;
Pass = 2;
}
}
} }
/** /**

View File

@ -1,10 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from collections import defaultdict, OrderedDict
import re
import os
import json
import glob import glob
import json
import logging import logging
import os
import re
from collections import OrderedDict, defaultdict
try: try:
import requests import requests

View File

@ -3,38 +3,38 @@ from trezorlib import protobuf as p
class CoinDef(p.MessageType): class CoinDef(p.MessageType):
FIELDS = { FIELDS = {
1: ('coin_name', p.UnicodeType, 0), 1: ("coin_name", p.UnicodeType, 0),
2: ('coin_shortcut', p.UnicodeType, 0), 2: ("coin_shortcut", p.UnicodeType, 0),
3: ('coin_label', p.UnicodeType, 0), 3: ("coin_label", p.UnicodeType, 0),
4: ('curve_name', p.UnicodeType, 0), 4: ("curve_name", p.UnicodeType, 0),
5: ('address_type', p.UVarintType, 0), 5: ("address_type", p.UVarintType, 0),
6: ('address_type_p2sh', p.UVarintType, 0), 6: ("address_type_p2sh", p.UVarintType, 0),
7: ('maxfee_kb', p.UVarintType, 0), 7: ("maxfee_kb", p.UVarintType, 0),
8: ('minfee_kb', p.UVarintType, 0), 8: ("minfee_kb", p.UVarintType, 0),
9: ('signed_message_header', p.BytesType, 0), 9: ("signed_message_header", p.BytesType, 0),
10: ('hash_genesis_block', p.BytesType, 0), 10: ("hash_genesis_block", p.BytesType, 0),
11: ('xprv_magic', p.UVarintType, 0), 11: ("xprv_magic", p.UVarintType, 0),
12: ('xpub_magic', p.UVarintType, 0), 12: ("xpub_magic", p.UVarintType, 0),
13: ('xpub_magic_segwit_p2sh', p.UVarintType, 0), 13: ("xpub_magic_segwit_p2sh", p.UVarintType, 0),
14: ('xpub_magic_segwit_native', p.UVarintType, 0), 14: ("xpub_magic_segwit_native", p.UVarintType, 0),
15: ('bech32_prefix', p.UnicodeType, 0), 15: ("bech32_prefix", p.UnicodeType, 0),
16: ('cashaddr_prefix', p.UnicodeType, 0), 16: ("cashaddr_prefix", p.UnicodeType, 0),
17: ('slip44', p.UVarintType, 0), 17: ("slip44", p.UVarintType, 0),
18: ('segwit', p.BoolType, 0), 18: ("segwit", p.BoolType, 0),
19: ('decred', p.BoolType, 0), 19: ("decred", p.BoolType, 0),
20: ('fork_id', p.UVarintType, 0), 20: ("fork_id", p.UVarintType, 0),
21: ('force_bip143', p.BoolType, 0), 21: ("force_bip143", p.BoolType, 0),
22: ('dust_limit', p.UVarintType, 0), 22: ("dust_limit", p.UVarintType, 0),
23: ('uri_prefix', p.UnicodeType, 0), 23: ("uri_prefix", p.UnicodeType, 0),
24: ('min_address_length', p.UVarintType, 0), 24: ("min_address_length", p.UVarintType, 0),
25: ('max_address_length', p.UVarintType, 0), 25: ("max_address_length", p.UVarintType, 0),
26: ('icon', p.BytesType, 0), 26: ("icon", p.BytesType, 0),
28: ('website', p.UnicodeType, 0), 28: ("website", p.UnicodeType, 0),
29: ('github', p.UnicodeType, 0), 29: ("github", p.UnicodeType, 0),
30: ('maintainer', p.UnicodeType, 0), 30: ("maintainer", p.UnicodeType, 0),
31: ('blocktime_seconds', p.UVarintType, 0), 31: ("blocktime_seconds", p.UVarintType, 0),
32: ('bip115', p.BoolType, 0), 32: ("bip115", p.BoolType, 0),
33: ('cooldown', p.UVarintType, 0), 33: ("cooldown", p.UVarintType, 0),
} }
def __init__( def __init__(
@ -73,7 +73,7 @@ class CoinDef(p.MessageType):
default_fee_b: dict = None, default_fee_b: dict = None,
bitcore: dict = None, bitcore: dict = None,
blockbook: dict = None, blockbook: dict = None,
cooldown: int = None cooldown: int = None,
): ):
self.coin_name = coin_name self.coin_name = coin_name
self.coin_shortcut = coin_shortcut self.coin_shortcut = coin_shortcut

View File

@ -1,14 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Fetch information about coins and tokens supported by Trezor and update it in coins_details.json.""" """Fetch information about coins and tokens supported by Trezor and update it in coins_details.json."""
import os
import time
import json import json
import logging import logging
import requests import os
import sys import sys
import coin_info import time
import click import click
import requests
import coin_info
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -149,7 +150,7 @@ def summary(coins, api_key):
try: try:
ret = coinmarketcap_call("global-metrics/quotes/latest", api_key) ret = coinmarketcap_call("global-metrics/quotes/latest", api_key)
total_marketcap = int(ret["data"]["quote"]["USD"]["total_market_cap"]) total_marketcap = int(ret["data"]["quote"]["USD"]["total_market_cap"])
except: except Exception:
pass pass
return dict( return dict(

View File

@ -1,13 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import fnmatch import fnmatch
import glob
import io import io
import json import json
import logging import logging
import re
import sys
import os import os
import glob import re
import struct import struct
import sys
import zlib import zlib
from collections import defaultdict from collections import defaultdict
from hashlib import sha256 from hashlib import sha256
@ -209,7 +209,7 @@ def check_btc(coins):
for coin in bucket: for coin in bucket:
name = coin["name"] name = coin["name"]
prefix = "" prefix = ""
if name.endswith("Testnet"): if name.endswith("Testnet") or name.endswith("Regtest"):
color = "green" color = "green"
elif name == "Bitcoin": elif name == "Bitcoin":
color = "red" color = "red"
@ -232,7 +232,12 @@ def check_btc(coins):
""" """
failed = False failed = False
for key, bucket in buckets.items(): for key, bucket in buckets.items():
mainnets = [c for c in bucket if not c["name"].endswith("Testnet")] mainnets = [
c
for c in bucket
if not c["name"].endswith("Testnet")
and not c["name"].endswith("Regtest")
]
have_bitcoin = False have_bitcoin = False
for coin in mainnets: for coin in mainnets:
@ -524,8 +529,7 @@ def cli(colors):
# fmt: off # fmt: off
@click.option("--backend/--no-backend", "-b", default=False, help="Check blockbook/bitcore responses") @click.option("--backend/--no-backend", "-b", default=False, help="Check blockbook/bitcore responses")
@click.option("--icons/--no-icons", default=True, help="Check icon files") @click.option("--icons/--no-icons", default=True, help="Check icon files")
@click.option("-d", "--show-duplicates", type=click.Choice(("all", "nontoken", "errors")), @click.option("-d", "--show-duplicates", type=click.Choice(("all", "nontoken", "errors")), default="errors", help="How much information about duplicate shortcuts should be shown.")
default="errors", help="How much information about duplicate shortcuts should be shown.")
# fmt: on # fmt: on
def check(backend, icons, show_duplicates): def check(backend, icons, show_duplicates):
"""Validate coin definitions. """Validate coin definitions.
@ -779,8 +783,9 @@ def coindefs(outfile):
@click.argument("paths", metavar="[path]...", nargs=-1) @click.argument("paths", metavar="[path]...", nargs=-1)
@click.option("-o", "--outfile", type=click.File("w"), help="Alternate output file") @click.option("-o", "--outfile", type=click.File("w"), help="Alternate output file")
@click.option("-v", "--verbose", is_flag=True, help="Print rendered file names") @click.option("-v", "--verbose", is_flag=True, help="Print rendered file names")
@click.option("-b", "--bitcoin-only", is_flag=True, help="Accept only Bitcoin coins")
# fmt: on # fmt: on
def render(paths, outfile, verbose): def render(paths, outfile, verbose, bitcoin_only):
"""Generate source code from Mako templates. """Generate source code from Mako templates.
For every "foo.bar.mako" filename passed, runs the template and For every "foo.bar.mako" filename passed, runs the template and
@ -801,6 +806,13 @@ def render(paths, outfile, verbose):
defs = coin_info.coin_info() defs = coin_info.coin_info()
support_info = coin_info.support_info(defs) support_info = coin_info.support_info(defs)
if bitcoin_only:
defs["bitcoin"] = [
x
for x in defs["bitcoin"]
if x["coin_name"] in ("Bitcoin", "Testnet", "Regtest")
]
# munch dicts - make them attribute-accessible # munch dicts - make them attribute-accessible
for key, value in defs.items(): for key, value in defs.items():
defs[key] = [Munch(coin) for coin in value] defs[key] = [Munch(coin) for coin in value]

View File

@ -1,13 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import click
import json import json
import os import os
import requests
import tempfile
import subprocess import subprocess
import sys import tempfile
import click
import requests
LIVE_URL = "https://trezor.io/static/json/coins_details.json" LIVE_URL = "https://trezor.io/static/json/coins_details.json"
COINS_DETAILS = os.path.join( COINS_DETAILS = os.path.join(

View File

@ -1,16 +0,0 @@
click>=6
# for `coin_gen coindefs` and checking icons:
ed25519>=1.4
Pillow>=5.2.0
trezor>=0.10
# for checking backends, generating coins_details.json
requests>=2.19
# for rendering templates:
Mako>=1.0.7
munch>=2.3.2
# for pretty colors in checks
termcolor >= 0.1.2

View File

@ -1,11 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import re import json
import os import os
import re
import subprocess import subprocess
import sys import sys
import click import click
import coin_info import coin_info
import json
SUPPORT_INFO = coin_info.get_support_data() SUPPORT_INFO = coin_info.get_support_data()

View File

@ -1,78 +0,0 @@
sudo: false
dist: trusty
language: c
addons:
apt:
sources:
- deadsnakes
packages:
- build-essential
- python3.6
- python3.6-dev
- python3.6-venv
- libusb-1.0-0-dev
- libudev-dev
env:
global:
- MAKEFLAGS=-j2
- PYTHON=python3.6
- PROTOBUF_VERSION=3.4.0
- TOOLCHAIN_SHORTVER=8-2018q4
- TOOLCHAIN_LONGVER=gcc-arm-none-eabi-8-2018-q4-major
matrix:
- GOAL=stm32
- GOAL=unix
- GOAL=src
matrix:
include:
- compiler: clang
env: GOAL=unix
cache:
directories:
- $HOME/libsodium
before_install:
- $PYTHON -m ensurepip --user
- $PYTHON -m pip install --user pipenv
install:
- ./travis-install-libsodium.sh
- export PKG_CONFIG_PATH=$HOME/libsodium/lib/pkgconfig:$PKG_CONFIG_PATH
- export LD_LIBRARY_PATH=$HOME/libsodium/lib:$LD_LIBRARY_PATH
- wget "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip"
- unzip "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" -d protoc
- export PATH="$(pwd)/protoc/bin:$PATH"
- pipenv install
before_script:
- test "$GOAL" != "stm32" || wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/$TOOLCHAIN_SHORTVER/$TOOLCHAIN_LONGVER-linux.tar.bz2
- test "$GOAL" != "stm32" || tar xfj $TOOLCHAIN_LONGVER-linux.tar.bz2
- test "$GOAL" != "stm32" || export PATH=$PWD/$TOOLCHAIN_LONGVER/bin:$PATH
script:
- test "$GOAL" != "src" || pipenv run make style_check
- test "$GOAL" != "src" || pipenv run make templates_check
- test "$GOAL" != "stm32" || pipenv run make build_cross
- test "$GOAL" != "stm32" || pipenv run make build_boardloader
- test "$GOAL" != "stm32" || pipenv run make build_bootloader
- test "$GOAL" != "stm32" || pipenv run make build_prodtest
- test "$GOAL" != "stm32" || pipenv run make build_firmware
- test "$GOAL" != "stm32" || test "$TREZOR_MODEL" = "1" || pipenv run make sizecheck
- test "$GOAL" != "unix" || pipenv run make build_unix_noui
- test "$GOAL" != "unix" || pipenv run make test
- test "$GOAL" != "unix" || test "$TREZOR_MODEL" = "1" || pipenv run make test_emu
- test "$GOAL" != "unix" || test "$TREZOR_MODEL" = "1" || pipenv run make test_emu_monero
notifications:
webhooks:
urls:
- http://ci-bot.satoshilabs.com:5000/travis
on_success: always
on_failure: always
on_start: always

View File

@ -1,5 +1,11 @@
Version 2.1.0 Version 2.1.1 [unreleased]
* stable release, optional update * More strict path validations
* Display non-zero locktime values
* Don't rotate the screen via swipe gesture
* Set screen rotation via user setting
* Monero UI fixes
Version 2.1.0 [Mar 2019]
* Security improvements * Security improvements
* Upgraded to new storage format * Upgraded to new storage format
* Ripple, Stellar, Cardano and NEM fixes * Ripple, Stellar, Cardano and NEM fixes
@ -7,20 +13,17 @@ Version 2.1.0
PIVX, REOSC, XPM, XSN, ZCL PIVX, REOSC, XPM, XSN, ZCL
* New ETH tokens * New ETH tokens
Version 2.0.10 Version 2.0.10 [Dec 2018]
* stable release, optional update
* Fix Monero payment ID computation * Fix Monero payment ID computation
* Fix issue with touch screen and flickering * Fix issue with touch screen and flickering
* Add support for OMNI layer: OMNI/MAID/USDT * Add support for OMNI layer: OMNI/MAID/USDT
* Add support for new coins: BTX, CPC, GAME, RVN * Add support for new coins: BTX, CPC, GAME, RVN
* Add support for new Ethereum tokens * Add support for new Ethereum tokens
Version 2.0.9 Version 2.0.9 [Nov 2018]
* stable release, optional update
* Small Monero and Segwit bugfixes * Small Monero and Segwit bugfixes
Version 2.0.8 Version 2.0.8 [Oct 2018]
* stable release, optional update
* Monero support * Monero support
* Cardano support * Cardano support
* Stellar support * Stellar support
@ -32,25 +35,22 @@ Version 2.0.8
* Zcash sapling hardfork support * Zcash sapling hardfork support
* Implemented seedless setup * Implemented seedless setup
Version 2.0.7 Version 2.0.7 [Jun 2018]
* stable release, optional update
* Bitcoin Cash cashaddr support * Bitcoin Cash cashaddr support
* Zcash Overwinter hardfork support * Zcash Overwinter hardfork support
* NEM support * NEM support
* Lisk support * Lisk support
* Show warning on home screen if PIN is not set * Show warning on home screen if PIN is not set
* Support for new coins: * Support for new coins:
- Bitcoin Private, Fujicoin, Vertcoin, Viacoin, Zcoin Bitcoin Private, Fujicoin, Vertcoin, Viacoin, Zcoin
* Support for new Ethereum networks: * Support for new Ethereum networks:
- EOS Classic, Ethereum Social, Ellaism, Callisto, EtherGem, Wanchain EOS Classic, Ethereum Social, Ellaism, Callisto, EtherGem, Wanchain
* Support for 500+ new Ethereum tokens * Support for 500+ new Ethereum tokens
Version 2.0.6 Version 2.0.6 [Mar 2018]
* stable release, optional update
* fix layout for Ethereum transactions * fix layout for Ethereum transactions
* fix public key generation for SSH and GPG * fix public key generation for SSH and GPG
* add special characters to passphrase keyboard * add special characters to passphrase keyboard
Version 2.0.5 Version 2.0.5 [Mar 2018]
* stable release, required update
* first public release * first public release

View File

@ -1,69 +0,0 @@
# initialize from the image
FROM debian:9
ARG TOOLCHAIN_FLAVOR=linux
ENV TOOLCHAIN_FLAVOR=$TOOLCHAIN_FLAVOR
# install build tools and dependencies
RUN apt-get update && apt-get install -y \
build-essential wget git python3-pip
# install dependencies from toolchain source build
RUN if [ "$TOOLCHAIN_FLAVOR" = "src" ]; then \
apt-get install -y autoconf autogen bison dejagnu \
flex flip gawk git gperf gzip nsis \
openssh-client p7zip-full perl python-dev \
libisl-dev tcl tofrodos zip \
texinfo texlive texlive-extra-utils; \
fi
# download toolchain
ENV TOOLCHAIN_SHORTVER=8-2018q4
ENV TOOLCHAIN_LONGVER=gcc-arm-none-eabi-8-2018-q4-major
ENV TOOLCHAIN_URL=https://developer.arm.com/-/media/Files/downloads/gnu-rm/$TOOLCHAIN_SHORTVER/$TOOLCHAIN_LONGVER-$TOOLCHAIN_FLAVOR.tar.bz2
ENV TOOLCHAIN_HASH_linux=fb31fbdfe08406ece43eef5df623c0b2deb8b53e405e2c878300f7a1f303ee52
ENV TOOLCHAIN_HASH_src=bc228325dbbfaf643f2ee5d19e01d8b1873fcb9c31781b5e1355d40a68704ce7
# extract toolchain
RUN cd /opt && wget $TOOLCHAIN_URL
RUN cd /opt && echo "$TOOLCHAIN_HASH_linux $TOOLCHAIN_LONGVER-linux.tar.bz2\n$TOOLCHAIN_HASH_src $TOOLCHAIN_LONGVER-src.tar.bz2" | sha256sum -c --ignore-missing
RUN cd /opt && tar xfj $TOOLCHAIN_LONGVER-$TOOLCHAIN_FLAVOR.tar.bz2
# build toolchain (if required)
RUN if [ "$TOOLCHAIN_FLAVOR" = "src" ]; then \
pushd /opt/$TOOLCHAIN_LONGVER ; \
./install-sources.sh --skip_steps=mingw32 ; \
./build-prerequisites.sh --skip_steps=mingw32 ; \
./build-toolchain.sh --skip_steps=mingw32,manual ; \
popd ; \
fi
# download protobuf
ENV PROTOBUF_VERSION=3.4.0
ENV PROTOBUF_HASH=e4b51de1b75813e62d6ecdde582efa798586e09b5beaebfb866ae7c9eaadace4
RUN wget "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip"
RUN echo "${PROTOBUF_HASH} protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" | sha256sum -c
# setup toolchain
ENV PATH=/opt/$TOOLCHAIN_LONGVER/bin:$PATH
ENV PYTHON=python3
ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
RUN ln -s /usr/bin/python3 /usr/bin/python
# use zipfile module to extract files world-readable
RUN $PYTHON -m zipfile -e "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" /usr/local && chmod 755 /usr/local/bin/protoc
# install python dependencies
RUN $PYTHON -m pip install scons trezor

View File

@ -39,7 +39,7 @@ CFLAGS += -DGITREV=$(GITREV)
## help commands: ## help commands:
help: ## show this help help: ## show this help
@awk -f help.awk $(MAKEFILE_LIST) @awk -f ../tools/help.awk $(MAKEFILE_LIST)
## dependencies commands: ## dependencies commands:
@ -71,27 +71,6 @@ test_emu_monero: ## run selected monero device tests from monero-agent
pylint: ## run pylint on application sources and tests pylint: ## run pylint on application sources and tests
pylint -E $(shell find src tests -name *.py) pylint -E $(shell find src tests -name *.py)
## style commands:
style_check: ## run code style check on application sources and tests
flake8 --version
isort --version | grep "VERSION"
black --version
flake8 $(shell find src -name *.py)
isort --check-only $(shell find src -name *.py ! -path 'src/trezor/messages/*')
black --check $(shell find src -name *.py ! -path 'src/trezor/messages/*')
style: ## apply code style on application sources and tests
isort $(shell find src -name *.py ! -path 'src/trezor/messages/*')
black $(shell find src -name *.py ! -path 'src/trezor/messages/*')
cstyle_check: ## run code style check on low-level C code
./tools/clang-format-check embed/*/*.{c,h} embed/extmod/modtrezor*/*.{c,h}
cstyle: ## apply code style on low-level C code
clang-format -i embed/*/*.{c,h} embed/extmod/modtrezor*/*.{c,h}
## code generation: ## code generation:
templates: ## render Mako templates (for lists of coins, tokens, etc.) templates: ## render Mako templates (for lists of coins, tokens, etc.)

View File

@ -1,6 +1,8 @@
#!/bin/sh #!/bin/sh
set -e set -e
cd "$(dirname $0)/.."
if [ "$1" = "--gcc_source" ]; then if [ "$1" = "--gcc_source" ]; then
TOOLCHAIN_FLAVOR=src TOOLCHAIN_FLAVOR=src
shift shift
@ -16,16 +18,19 @@ PRODUCTION=${PRODUCTION:-0}
if [ "$REPOSITORY" = "local" ]; then if [ "$REPOSITORY" = "local" ]; then
REPOSITORY=file:///local/ REPOSITORY=file:///local/
else else
REPOSITORY=https://github.com/$REPOSITORY/trezor-core.git REPOSITORY=https://github.com/$REPOSITORY/trezor-firmware.git
fi fi
docker build -t $IMAGE --build-arg TOOLCHAIN_FLAVOR=$TOOLCHAIN_FLAVOR . docker build -t $IMAGE --build-arg TOOLCHAIN_FLAVOR=$TOOLCHAIN_FLAVOR ci/
mkdir -p $(pwd)/build-docker USER=$(ls -lnd . | awk '{ print $3 }')
docker run -t -v $(pwd):/local -v $(pwd)/build-docker:/build:z --user="$(stat -c "%u:%g" .)" $IMAGE /bin/sh -c "\ GROUP=$(ls -lnd . | awk '{ print $4 }')
mkdir -p $(pwd)/build/core
docker run -t -v $(pwd):/local -v $(pwd)/build/core:/build:z --user="$USER:$GROUP" $IMAGE /bin/sh -c "\
cd /tmp && \ cd /tmp && \
git clone $REPOSITORY trezor-core && \ git clone $REPOSITORY trezor-firmware && \
cd trezor-core && \ cd trezor-firmware/core && \
ln -s /build build && ln -s /build build &&
git checkout $TAG && \ git checkout $TAG && \
git submodule update --init --recursive && \ git submodule update --init --recursive && \

View File

@ -236,7 +236,7 @@ void ui_screen_install_confirm_newvendor(const vendor_header *const vhdr,
void ui_screen_install(void) { void ui_screen_install(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE); display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(0, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install, display_loader(0, false, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install,
sizeof(toi_icon_install), COLOR_BLACK); sizeof(toi_icon_install), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24,
"Installing firmware", -1, FONT_NORMAL, COLOR_BLACK, "Installing firmware", -1, FONT_NORMAL, COLOR_BLACK,
@ -244,13 +244,13 @@ void ui_screen_install(void) {
} }
void ui_screen_install_progress_erase(int pos, int len) { void ui_screen_install_progress_erase(int pos, int len) {
display_loader(250 * pos / len, -20, COLOR_BL_PROCESS, COLOR_WHITE, display_loader(250 * pos / len, false, -20, COLOR_BL_PROCESS, COLOR_WHITE,
toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK); toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
} }
void ui_screen_install_progress_upload(int pos) { void ui_screen_install_progress_upload(int pos) {
display_loader(pos, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install, display_loader(pos, false, -20, COLOR_BL_PROCESS, COLOR_WHITE,
sizeof(toi_icon_install), COLOR_BLACK); toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
} }
// wipe UI // wipe UI
@ -274,14 +274,14 @@ void ui_screen_wipe_confirm(void) {
void ui_screen_wipe(void) { void ui_screen_wipe(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE); display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(0, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_wipe, display_loader(0, false, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_wipe,
sizeof(toi_icon_wipe), COLOR_BLACK); sizeof(toi_icon_wipe), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Wiping device", -1, display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Wiping device", -1,
FONT_NORMAL, COLOR_BLACK, COLOR_WHITE); FONT_NORMAL, COLOR_BLACK, COLOR_WHITE);
} }
void ui_screen_wipe_progress(int pos, int len) { void ui_screen_wipe_progress(int pos, int len) {
display_loader(1000 * pos / len, -20, COLOR_BL_PROCESS, COLOR_WHITE, display_loader(1000 * pos / len, false, -20, COLOR_BL_PROCESS, COLOR_WHITE,
toi_icon_wipe, sizeof(toi_icon_wipe), COLOR_BLACK); toi_icon_wipe, sizeof(toi_icon_wipe), COLOR_BLACK);
} }
@ -300,7 +300,7 @@ void ui_screen_done(int restart_seconds, secbool full_redraw) {
if (sectrue == full_redraw) { if (sectrue == full_redraw) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE); display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
} }
display_loader(1000, -20, COLOR_BL_DONE, COLOR_WHITE, toi_icon_done, display_loader(1000, false, -20, COLOR_BL_DONE, COLOR_WHITE, toi_icon_done,
sizeof(toi_icon_done), COLOR_BLACK); sizeof(toi_icon_done), COLOR_BLACK);
if (secfalse == full_redraw) { if (secfalse == full_redraw) {
display_bar(0, DISPLAY_RESY - 24 - 18, 240, 23, COLOR_WHITE); display_bar(0, DISPLAY_RESY - 24 - 18, 240, 23, COLOR_WHITE);
@ -313,7 +313,7 @@ void ui_screen_done(int restart_seconds, secbool full_redraw) {
void ui_screen_fail(void) { void ui_screen_fail(void) {
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE); display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(1000, -20, COLOR_BL_FAIL, COLOR_WHITE, toi_icon_fail, display_loader(1000, false, -20, COLOR_BL_FAIL, COLOR_WHITE, toi_icon_fail,
sizeof(toi_icon_fail), COLOR_BLACK); sizeof(toi_icon_fail), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24,
"Failed! Please, reconnect.", -1, FONT_NORMAL, "Failed! Please, reconnect.", -1, FONT_NORMAL,

View File

@ -1,6 +1,6 @@
#define VERSION_MAJOR 2 #define VERSION_MAJOR 2
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_PATCH 3 #define VERSION_PATCH 4
#define VERSION_BUILD 0 #define VERSION_BUILD 0
#define VERSION_UINT32 \ #define VERSION_UINT32 \
(VERSION_MAJOR | (VERSION_MINOR << 8) | (VERSION_PATCH << 16) | \ (VERSION_MAJOR | (VERSION_MINOR << 8) | (VERSION_PATCH << 16) | \

View File

@ -241,6 +241,4 @@ void display_refresh(void) {
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD
} }
const char *display_save(const char *prefix) { const char *display_save(const char *prefix) { return NULL; }
return NULL;
}

View File

@ -498,6 +498,4 @@ void display_refresh(void) {
} }
} }
const char *display_save(const char *prefix) { const char *display_save(const char *prefix) { return NULL; }
return NULL;
}

View File

@ -316,9 +316,9 @@ static void inflate_callback_loader(uint8_t byte, uint32_t pos,
#endif #endif
void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, void display_loader(uint16_t progress, bool indeterminate, int yoffset,
uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon,
uint16_t iconfgcolor) { uint32_t iconlen, uint16_t iconfgcolor) {
#if TREZOR_MODEL == T #if TREZOR_MODEL == T
uint16_t colortable[16], iconcolortable[16]; uint16_t colortable[16], iconcolortable[16];
set_color_table(colortable, fgcolor, bgcolor); set_color_table(colortable, fgcolor, bgcolor);
@ -362,6 +362,7 @@ void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor,
} }
// inside of circle - draw glyph // inside of circle - draw glyph
#define LOADER_ICON_CORNER_CUT 2 #define LOADER_ICON_CORNER_CUT 2
#define LOADER_INDETERMINATE_WIDTH 100
if (icon && if (icon &&
mx + my > (((LOADER_ICON_SIZE / 2) + LOADER_ICON_CORNER_CUT) * 2) && mx + my > (((LOADER_ICON_SIZE / 2) + LOADER_ICON_CORNER_CUT) * 2) &&
mx >= img_loader_size - (LOADER_ICON_SIZE / 2) && mx >= img_loader_size - (LOADER_ICON_SIZE / 2) &&
@ -378,11 +379,22 @@ void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor,
PIXELDATA(iconcolortable[c]); PIXELDATA(iconcolortable[c]);
} else { } else {
uint8_t c; uint8_t c;
if (indeterminate) {
uint16_t diff =
(progress > a) ? (progress - a) : (1000 + progress - a);
if (diff < LOADER_INDETERMINATE_WIDTH ||
diff > 1000 - LOADER_INDETERMINATE_WIDTH) {
c = (img_loader[my][mx] & 0x00F0) >> 4;
} else {
c = img_loader[my][mx] & 0x000F;
}
} else {
if (progress > a) { if (progress > a) {
c = (img_loader[my][mx] & 0x00F0) >> 4; c = (img_loader[my][mx] & 0x00F0) >> 4;
} else { } else {
c = img_loader[my][mx] & 0x000F; c = img_loader[my][mx] & 0x000F;
} }
}
PIXELDATA(colortable[c]); PIXELDATA(colortable[c]);
} }
} }

View File

@ -21,6 +21,7 @@
#define __DISPLAY_H__ #define __DISPLAY_H__
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#if TREZOR_MODEL == T #if TREZOR_MODEL == T
@ -82,9 +83,9 @@ void display_avatar(int x, int y, const void *data, int datalen,
uint16_t fgcolor, uint16_t bgcolor); uint16_t fgcolor, uint16_t bgcolor);
void display_icon(int x, int y, int w, int h, const void *data, int datalen, void display_icon(int x, int y, int w, int h, const void *data, int datalen,
uint16_t fgcolor, uint16_t bgcolor); uint16_t fgcolor, uint16_t bgcolor);
void display_loader(uint16_t progress, int yoffset, uint16_t fgcolor, void display_loader(uint16_t progress, bool indeterminate, int yoffset,
uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon,
uint16_t iconfgcolor); uint32_t iconlen, uint16_t iconfgcolor);
#ifndef TREZOR_PRINT_DISABLE #ifndef TREZOR_PRINT_DISABLE
void display_print_color(uint16_t fgcolor, uint16_t bgcolor); void display_print_color(uint16_t fgcolor, uint16_t bgcolor);

View File

@ -197,8 +197,8 @@ STATIC mp_obj_t mod_trezorui_Display_icon(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_icon_obj, 6, 6, STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_icon_obj, 6, 6,
mod_trezorui_Display_icon); mod_trezorui_Display_icon);
/// def loader(self, progress: int, yoffset: int, fgcolor: int, bgcolor: int, /// def loader(self, progress: int, indeterminate: bool, yoffset: int, fgcolor:
/// icon: bytes = None, iconfgcolor: int = None) -> None: /// int, bgcolor: int, icon: bytes = None, iconfgcolor: int = None) -> None:
/// ''' /// '''
/// Renders a rotating loader graphic. /// Renders a rotating loader graphic.
/// Progress determines its position (0-1000), fgcolor is used as foreground /// Progress determines its position (0-1000), fgcolor is used as foreground
@ -210,12 +210,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_icon_obj, 6, 6,
STATIC mp_obj_t mod_trezorui_Display_loader(size_t n_args, STATIC mp_obj_t mod_trezorui_Display_loader(size_t n_args,
const mp_obj_t *args) { const mp_obj_t *args) {
mp_int_t progress = mp_obj_get_int(args[1]); mp_int_t progress = mp_obj_get_int(args[1]);
mp_int_t yoffset = mp_obj_get_int(args[2]); bool indeterminate = args[2] == mp_const_true;
mp_int_t fgcolor = mp_obj_get_int(args[3]); mp_int_t yoffset = mp_obj_get_int(args[3]);
mp_int_t bgcolor = mp_obj_get_int(args[4]); mp_int_t fgcolor = mp_obj_get_int(args[4]);
if (n_args > 5) { // icon provided mp_int_t bgcolor = mp_obj_get_int(args[5]);
if (n_args > 6) { // icon provided
mp_buffer_info_t icon; mp_buffer_info_t icon;
mp_get_buffer_raise(args[5], &icon, MP_BUFFER_READ); mp_get_buffer_raise(args[6], &icon, MP_BUFFER_READ);
const uint8_t *data = icon.buf; const uint8_t *data = icon.buf;
if (icon.len < 8 || memcmp(data, "TOIg", 4) != 0) { if (icon.len < 8 || memcmp(data, "TOIg", 4) != 0) {
mp_raise_ValueError("Invalid image format"); mp_raise_ValueError("Invalid image format");
@ -230,20 +231,21 @@ STATIC mp_obj_t mod_trezorui_Display_loader(size_t n_args,
mp_raise_ValueError("Invalid size of data"); mp_raise_ValueError("Invalid size of data");
} }
uint16_t iconfgcolor; uint16_t iconfgcolor;
if (n_args > 6) { // icon color provided if (n_args > 7) { // icon color provided
iconfgcolor = mp_obj_get_int(args[6]); iconfgcolor = mp_obj_get_int(args[7]);
} else { } else {
iconfgcolor = ~bgcolor; // invert iconfgcolor = ~bgcolor; // invert
} }
display_loader(progress, yoffset, fgcolor, bgcolor, icon.buf, icon.len, display_loader(progress, indeterminate, yoffset, fgcolor, bgcolor, icon.buf,
iconfgcolor); icon.len, iconfgcolor);
} else { } else {
display_loader(progress, yoffset, fgcolor, bgcolor, NULL, 0, 0); display_loader(progress, indeterminate, yoffset, fgcolor, bgcolor, NULL, 0,
0);
} }
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_loader_obj, 5, STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_loader_obj, 6,
7, mod_trezorui_Display_loader); 8, mod_trezorui_Display_loader);
/// def print(self, text: str) -> None: /// def print(self, text: str) -> None:
/// ''' /// '''

View File

@ -1,6 +1,6 @@
#define VERSION_MAJOR 2 #define VERSION_MAJOR 2
#define VERSION_MINOR 1 #define VERSION_MINOR 1
#define VERSION_PATCH 0 #define VERSION_PATCH 1
#define VERSION_BUILD 0 #define VERSION_BUILD 0
#define FIX_VERSION_MAJOR 2 #define FIX_VERSION_MAJOR 2

View File

@ -1,3 +1,5 @@
// clang-format off
/* /*
* This file is part of the MicroPython project, http://micropython.org/ * This file is part of the MicroPython project, http://micropython.org/
* *

View File

@ -5,7 +5,6 @@ source emu.config 2>/dev/null
EXE=build/unix/micropython EXE=build/unix/micropython
PYOPT="${PYOPT:-1}" PYOPT="${PYOPT:-1}"
MAIN="${MAIN:-${PWD}/src/main.py}" MAIN="${MAIN:-${PWD}/src/main.py}"
BROWSER="${BROWSER:-chromium}"
HEAPSIZE="${HEAPSIZE:-50M}" HEAPSIZE="${HEAPSIZE:-50M}"
SOURCE_PY_DIR="${SOURCE_PY_DIR:-src}" SOURCE_PY_DIR="${SOURCE_PY_DIR:-src}"
@ -33,14 +32,6 @@ case "$1" in
kill $UPY_PID kill $UPY_PID
done done
;; ;;
"-p")
shift
../$EXE $ARGS $* $MAIN &
perf record -F 100 -p $! -g -- sleep 600
perf script > perf.trace
../vendor/flamegraph/stackcollapse-perf.pl perf.trace | ../vendor/flamegraph/flamegraph.pl > perf.svg
$BROWSER perf.svg
;;
*) *)
../$EXE $ARGS $* $MAIN ../$EXE $ARGS $* $MAIN
esac esac

View File

@ -24,5 +24,5 @@ def report_init(text):
def report(): def report():
p = int(1000 * _progress / _steps) p = 1000 * _progress // _steps
ui.display.loader(p, 18, ui.WHITE, ui.BG) ui.display.loader(p, False, 18, ui.WHITE, ui.BG)

View File

@ -549,7 +549,7 @@ COINS = [
coin_shortcut="FJC", coin_shortcut="FJC",
address_type=36, address_type=36,
address_type_p2sh=16, address_type_p2sh=16,
maxfee_kb=10000000, maxfee_kb=1000000000,
signed_message_header="FujiCoin Signed Message:\n", signed_message_header="FujiCoin Signed Message:\n",
xpub_magic=0x0488b21e, xpub_magic=0x0488b21e,
xpub_magic_segwit_p2sh=0x049d7cb2, xpub_magic_segwit_p2sh=0x049d7cb2,
@ -984,6 +984,26 @@ COINS = [
decred=False, decred=False,
curve_name='secp256k1', curve_name='secp256k1',
), ),
CoinInfo(
coin_name="Regtest",
coin_shortcut="REGTEST",
address_type=111,
address_type_p2sh=196,
maxfee_kb=10000000,
signed_message_header="Bitcoin Signed Message:\n",
xpub_magic=0x043587cf,
xpub_magic_segwit_p2sh=0x044a5262,
xpub_magic_segwit_native=0x045f1cf6,
bech32_prefix="bcrt",
cashaddr_prefix=None,
slip44=1,
segwit=True,
fork_id=None,
force_bip143=False,
bip115=False,
decred=False,
curve_name='secp256k1',
),
CoinInfo( CoinInfo(
coin_name="SmartCash", coin_name="SmartCash",
coin_shortcut="SMART", coin_shortcut="SMART",

View File

@ -44,6 +44,6 @@ def _start_progress():
def _render_progress(progress: int, total: int): def _render_progress(progress: int, total: int):
p = int(1000 * progress / total) p = 1000 * progress // total
ui.display.loader(p, 18, ui.WHITE, ui.BG) ui.display.loader(p, False, 18, ui.WHITE, ui.BG)
ui.display.refresh() ui.display.refresh()

View File

@ -24,6 +24,13 @@ def write_uint16_le(w: bytearray, n: int) -> int:
return 2 return 2
def write_uint16_be(w: bytearray, n: int):
ensure(0 <= n <= 0xFFFF)
w.append((n >> 8) & 0xFF)
w.append(n & 0xFF)
return 2
def write_uint32_le(w: bytearray, n: int) -> int: def write_uint32_le(w: bytearray, n: int) -> int:
ensure(0 <= n <= 0xFFFFFFFF) ensure(0 <= n <= 0xFFFFFFFF)
w.append(n & 0xFF) w.append(n & 0xFF)

View File

@ -159,7 +159,6 @@ tokens = [
(1, b"\x80\x04\x63\x05\xaa\xab\x08\xf6\x03\x3b\x56\xa3\x60\xc1\x84\x39\x11\x65\xdc\x2d", "BRLN", 18), # eth / Berlin Coin (1, b"\x80\x04\x63\x05\xaa\xab\x08\xf6\x03\x3b\x56\xa3\x60\xc1\x84\x39\x11\x65\xdc\x2d", "BRLN", 18), # eth / Berlin Coin
(1, b"\xb2\x2c\x27\x86\xa5\x49\xb0\x08\x51\x7b\x67\x62\x5f\x52\x96\xe8\xfa\xf9\x58\x9e", "BRP", 18), # eth / Rental Processor Token (1, b"\xb2\x2c\x27\x86\xa5\x49\xb0\x08\x51\x7b\x67\x62\x5f\x52\x96\xe8\xfa\xf9\x58\x9e", "BRP", 18), # eth / Rental Processor Token
(1, b"\xf2\x6e\xf5\xe0\x54\x53\x84\xb7\xdc\xc0\xf2\x97\xf2\x67\x41\x89\x58\x68\x30\xdf", "BSDC", 18), # eth / BSDC (1, b"\xf2\x6e\xf5\xe0\x54\x53\x84\xb7\xdc\xc0\xf2\x97\xf2\x67\x41\x89\x58\x68\x30\xdf", "BSDC", 18), # eth / BSDC
(1, b"\x50\x9a\x38\xb7\xa1\xcc\x0d\xcd\x83\xaa\x9d\x06\x21\x46\x63\xd9\xec\x7c\x7f\x4a", "BST", 18), # eth / BlocksquareToken
(1, b"\x02\x72\x58\x36\xeb\xf3\xec\xdb\x1c\xdf\x1c\x7b\x02\xfc\xbb\xfa\xa2\x73\x6a\xf8", "BTCA", 8), # eth / BitAir (1, b"\x02\x72\x58\x36\xeb\xf3\xec\xdb\x1c\xdf\x1c\x7b\x02\xfc\xbb\xfa\xa2\x73\x6a\xf8", "BTCA", 8), # eth / BitAir
(1, b"\x08\x86\x94\x9c\x1b\x8c\x41\x28\x60\xc4\x26\x4c\xeb\x80\x83\xd1\x36\x5e\x86\xcf", "BTCE", 8), # eth / EthereumBitcoin (1, b"\x08\x86\x94\x9c\x1b\x8c\x41\x28\x60\xc4\x26\x4c\xeb\x80\x83\xd1\x36\x5e\x86\xcf", "BTCE", 8), # eth / EthereumBitcoin
(1, b"\x5a\xcd\x19\xb9\xc9\x1e\x59\x6b\x1f\x06\x2f\x18\xe3\xd0\x2d\xa7\xed\x8d\x1e\x50", "BTCL", 8), # eth / BTC Lite (1, b"\x5a\xcd\x19\xb9\xc9\x1e\x59\x6b\x1f\x06\x2f\x18\xe3\xd0\x2d\xa7\xed\x8d\x1e\x50", "BTCL", 8), # eth / BTC Lite

View File

@ -42,7 +42,7 @@ async def require_confirm_tx_key(ctx, export_key=False):
return await require_confirm(ctx, content, ButtonRequestType.SignTx) return await require_confirm(ctx, content, ButtonRequestType.SignTx)
async def require_confirm_transaction(ctx, tsx_data, network_type): async def require_confirm_transaction(ctx, state, tsx_data, network_type):
""" """
Ask for confirmation from user. Ask for confirmation from user.
""" """
@ -70,10 +70,7 @@ async def require_confirm_transaction(ctx, tsx_data, network_type):
await _require_confirm_payment_id(ctx, tsx_data.payment_id) await _require_confirm_payment_id(ctx, tsx_data.payment_id)
await _require_confirm_fee(ctx, tsx_data.fee) await _require_confirm_fee(ctx, tsx_data.fee)
await transaction_step(state, 0)
text = Text("Signing transaction", ui.ICON_SEND, icon_color=ui.BLUE)
text.normal("Signing...")
text.render()
async def _require_confirm_output(ctx, dst, network_type, payment_id): async def _require_confirm_output(ctx, dst, network_type, payment_id):
@ -119,46 +116,66 @@ async def _require_confirm_fee(ctx, fee):
await require_hold_to_confirm(ctx, content, ButtonRequestType.ConfirmOutput) await require_hold_to_confirm(ctx, content, ButtonRequestType.ConfirmOutput)
@ui.layout @ui.layout_no_slide
async def transaction_step(ctx, step, sub_step=None, sub_step_total=None): async def transaction_step(state, step, sub_step=None):
info = [] info = []
if step == 100: if step == 0:
info = ["Processing inputs", "%d/%d" % (sub_step + 1, sub_step_total)] info = ["Signing..."]
elif step == 100:
info = ["Processing inputs", "%d/%d" % (sub_step + 1, state.input_count)]
elif step == 200: elif step == 200:
info = ["Sorting"] info = ["Sorting..."]
elif step == 300: elif step == 300:
info = [ info = ["Hashing inputs", "%d/%d" % (sub_step + 1, state.input_count)]
"Processing inputs", elif step == 350:
"phase 2", info = ["Processing..."]
"%d/%d" % (sub_step + 1, sub_step_total),
]
elif step == 400: elif step == 400:
info = ["Processing outputs", "%d/%d" % (sub_step + 1, sub_step_total)] info = ["Processing outputs", "%d/%d" % (sub_step + 1, state.output_count)]
elif step == 500: elif step == 500:
info = ["Postprocessing..."] info = ["Postprocessing..."]
elif step == 600: elif step == 600:
info = ["Signing inputs", "%d/%d" % (sub_step + 1, sub_step_total)] info = ["Signing inputs", "%d/%d" % (sub_step + 1, state.input_count)]
else: else:
info = ["Processing..."] info = ["Processing..."]
state.progress_cur += 1
ui.display.clear()
text = Text("Signing transaction", ui.ICON_SEND, icon_color=ui.BLUE) text = Text("Signing transaction", ui.ICON_SEND, icon_color=ui.BLUE)
text.normal(*info)
text.render() text.render()
p = 1000 * state.progress_cur // state.progress_total
ui.display.loader(p, False, -4, ui.WHITE, ui.BG)
ui.display.text_center(ui.WIDTH // 2, 210, info[0], ui.NORMAL, ui.FG, ui.BG)
if len(info) > 1:
ui.display.text_center(ui.WIDTH // 2, 235, info[1], ui.NORMAL, ui.FG, ui.BG)
ui.display.refresh()
@ui.layout
@ui.layout_no_slide
async def keyimage_sync_step(ctx, current, total_num): async def keyimage_sync_step(ctx, current, total_num):
if current is None: if current is None:
return return
ui.display.clear()
text = Text("Syncing", ui.ICON_SEND, icon_color=ui.BLUE) text = Text("Syncing", ui.ICON_SEND, icon_color=ui.BLUE)
text.normal("%d/%d" % (current + 1, total_num))
text.render() text.render()
p = (1000 * (current + 1) // total_num) if total_num > 0 else 0
ui.display.loader(p, False, 18, ui.WHITE, ui.BG)
ui.display.refresh()
@ui.layout
@ui.layout_no_slide
async def live_refresh_step(ctx, current): async def live_refresh_step(ctx, current):
if current is None: if current is None:
return return
ui.display.clear()
text = Text("Refreshing", ui.ICON_SEND, icon_color=ui.BLUE) text = Text("Refreshing", ui.ICON_SEND, icon_color=ui.BLUE)
text.normal("%d" % current)
text.render() text.render()
step = 8
p = (1000 * current // step) % 1000
ui.display.loader(p, True, 18, ui.WHITE, ui.BG)
ui.display.text_center(ui.WIDTH // 2, 145, "%d" % current, ui.NORMAL, ui.FG, ui.BG)
ui.display.refresh()

View File

@ -37,7 +37,7 @@ async def live_refresh(ctx, msg: MoneroLiveRefreshStartRequest, keychain):
class LiveRefreshState: class LiveRefreshState:
def __init__(self): def __init__(self):
self.current_output = -1 self.current_output = 0
self.creds = None self.creds = None

View File

@ -68,6 +68,9 @@ class State:
self.input_count = 0 self.input_count = 0
self.output_count = 0 self.output_count = 0
self.progress_total = 0
self.progress_cur = 0
self.output_change = None self.output_change = None
self.fee = 0 self.fee = 0

View File

@ -36,16 +36,19 @@ async def init_transaction(
state.mem_trace(1) state.mem_trace(1)
state.input_count = tsx_data.num_inputs
state.output_count = len(tsx_data.outputs)
state.progress_total = 4 + 3 * state.input_count + state.output_count
state.progress_cur = 0
# Ask for confirmation # Ask for confirmation
await confirms.require_confirm_transaction( await confirms.require_confirm_transaction(
state.ctx, tsx_data, state.creds.network_type state.ctx, state, tsx_data, state.creds.network_type
) )
gc.collect() gc.collect()
state.mem_trace(3) state.mem_trace(3)
# Basic transaction parameters # Basic transaction parameters
state.input_count = tsx_data.num_inputs
state.output_count = len(tsx_data.outputs)
state.output_change = tsx_data.change_dts state.output_change = tsx_data.change_dts
state.mixin = tsx_data.mixin state.mixin = tsx_data.mixin
state.fee = tsx_data.fee state.fee = tsx_data.fee

View File

@ -32,9 +32,7 @@ async def set_input(state: State, src_entr: MoneroTransactionSourceEntry):
state.current_input_index += 1 state.current_input_index += 1
await confirms.transaction_step( await confirms.transaction_step(state, state.STEP_INP, state.current_input_index)
state.ctx, state.STEP_INP, state.current_input_index, state.input_count
)
if state.current_input_index >= state.input_count: if state.current_input_index >= state.input_count:
raise ValueError("Too many inputs") raise ValueError("Too many inputs")

View File

@ -21,7 +21,7 @@ async def tsx_inputs_permutation(state: State, permutation: list):
MoneroTransactionInputsPermutationAck, MoneroTransactionInputsPermutationAck,
) )
await transaction_step(state.ctx, state.STEP_PERM) await transaction_step(state, state.STEP_PERM)
""" """
Set permutation on the inputs - sorted by key image on host. Set permutation on the inputs - sorted by key image on host.

View File

@ -33,7 +33,7 @@ async def input_vini(
) )
await confirms.transaction_step( await confirms.transaction_step(
state.ctx, state.STEP_VINI, state.current_input_index + 1, state.input_count state, state.STEP_VINI, state.current_input_index + 1
) )
if state.current_input_index >= state.input_count: if state.current_input_index >= state.input_count:
raise ValueError("Too many inputs") raise ValueError("Too many inputs")

View File

@ -12,7 +12,7 @@ from apps.monero.xmr import crypto
async def all_inputs_set(state: State): async def all_inputs_set(state: State):
state.mem_trace(0) state.mem_trace(0)
await confirms.transaction_step(state.ctx, state.STEP_ALL_IN) await confirms.transaction_step(state, state.STEP_ALL_IN)
from trezor.messages.MoneroTransactionAllInputsSetAck import ( from trezor.messages.MoneroTransactionAllInputsSetAck import (
MoneroTransactionAllInputsSetAck, MoneroTransactionAllInputsSetAck,

View File

@ -23,10 +23,7 @@ async def set_output(
# Progress update only for master message (skip for offloaded BP msg) # Progress update only for master message (skip for offloaded BP msg)
if not is_offloaded_bp: if not is_offloaded_bp:
await confirms.transaction_step( await confirms.transaction_step(
state.ctx, state, state.STEP_OUT, state.current_output_index + 1
state.STEP_OUT,
state.current_output_index + 1,
state.output_count,
) )
state.mem_trace(1, True) state.mem_trace(1, True)

View File

@ -18,7 +18,7 @@ from apps.monero.xmr import crypto
async def all_outputs_set(state: State): async def all_outputs_set(state: State):
state.mem_trace(0) state.mem_trace(0)
await confirms.transaction_step(state.ctx, state.STEP_ALL_OUT) await confirms.transaction_step(state, state.STEP_ALL_OUT)
state.mem_trace(1) state.mem_trace(1)
_validate(state) _validate(state)

View File

@ -48,7 +48,7 @@ async def sign_input(
:return: Generated signature MGs[i] :return: Generated signature MGs[i]
""" """
await confirms.transaction_step( await confirms.transaction_step(
state.ctx, state.STEP_SIGN, state.current_input_index + 1, state.input_count state, state.STEP_SIGN, state.current_input_index + 1
) )
state.current_input_index += 1 state.current_input_index += 1

View File

@ -3,6 +3,7 @@ from micropython import const
from trezor.crypto import base58 from trezor.crypto import base58
from apps.common import HARDENED from apps.common import HARDENED
from apps.common.writers import write_uint8
TEZOS_AMOUNT_DIVISIBILITY = const(6) TEZOS_AMOUNT_DIVISIBILITY = const(6)
TEZOS_ED25519_ADDRESS_PREFIX = "tz1" TEZOS_ED25519_ADDRESS_PREFIX = "tz1"
@ -21,6 +22,8 @@ TEZOS_PREFIX_BYTES = {
"edsig": [9, 245, 205, 134, 18], "edsig": [9, 245, 205, 134, 18],
# operation hash # operation hash
"o": [5, 116], "o": [5, 116],
# protocol hash
"P": [2, 170],
} }
@ -42,13 +45,29 @@ def validate_full_path(path: list) -> bool:
""" """
Validates derivation path to equal 44'/1729'/a', Validates derivation path to equal 44'/1729'/a',
where `a` is an account index from 0 to 1 000 000. where `a` is an account index from 0 to 1 000 000.
Additional component added to allow ledger migration
44'/1729'/0'/b' where `b` is an account index from 0 to 1 000 000
""" """
if len(path) != 3: length = len(path)
if length < 3 or length > 4:
return False return False
if path[0] != 44 | HARDENED: if path[0] != 44 | HARDENED:
return False return False
if path[1] != 1729 | HARDENED: if path[1] != 1729 | HARDENED:
return False return False
if length == 3:
if path[2] < HARDENED or path[2] > 1000000 | HARDENED: if path[2] < HARDENED or path[2] > 1000000 | HARDENED:
return False return False
if length == 4:
if path[2] != 0 | HARDENED:
return False
if path[3] < HARDENED or path[3] > 1000000 | HARDENED:
return False
return True return True
def write_bool(w: bytearray, boolean: bool):
if boolean:
write_uint8(w, 255)
else:
write_uint8(w, 0)

View File

@ -1,5 +1,10 @@
from trezor import ui from micropython import const
from trezor.messages import ButtonRequestType
from trezor import ui, wire
from trezor.messages import ButtonRequestType, MessageType
from trezor.messages.ButtonRequest import ButtonRequest
from trezor.ui.confirm import CANCELLED, ConfirmDialog
from trezor.ui.scroll import Scrollpage, animate_swipe, paginate
from trezor.ui.text import Text from trezor.ui.text import Text
from trezor.utils import chunks, format_amount from trezor.utils import chunks, format_amount
@ -66,6 +71,45 @@ def split_address(address):
return chunks(address, 18) return chunks(address, 18)
def split_proposal(proposal):
return chunks(proposal, 17)
def format_tezos_amount(value): def format_tezos_amount(value):
formatted_value = format_amount(value, TEZOS_AMOUNT_DIVISIBILITY) formatted_value = format_amount(value, TEZOS_AMOUNT_DIVISIBILITY)
return formatted_value + " XTZ" return formatted_value + " XTZ"
async def require_confirm_ballot(ctx, proposal, ballot):
text = Text("Submit ballot", ui.ICON_SEND, icon_color=ui.PURPLE)
text.bold("Ballot: {}".format(ballot))
text.bold("Proposal:")
text.mono(*split_proposal(proposal))
await require_confirm(ctx, text, ButtonRequestType.SignTx)
# use, when there are more then one proposals in one operation
async def require_confirm_proposals(ctx, proposals):
await ctx.call(ButtonRequest(code=ButtonRequestType.SignTx), MessageType.ButtonAck)
first_page = const(0)
pages = proposals
title = "Submit proposals" if len(proposals) > 1 else "Submit proposal"
paginator = paginate(show_proposal_page, len(pages), first_page, pages, title)
return await ctx.wait(paginator)
@ui.layout
async def show_proposal_page(page: int, page_count: int, pages: list, title: str):
text = Text(title, ui.ICON_SEND, icon_color=ui.PURPLE)
text.bold("Proposal {}: ".format(page + 1))
text.mono(*split_proposal(pages[page]))
content = Scrollpage(text, page, page_count)
if page + 1 >= page_count:
confirm = await ConfirmDialog(content)
if confirm == CANCELLED:
raise wire.ActionCancelled("Cancelled")
else:
content.render()
await animate_swipe()

View File

@ -1,13 +1,17 @@
from micropython import const
from trezor import wire from trezor import wire
from trezor.crypto import hashlib from trezor.crypto import hashlib
from trezor.crypto.curve import ed25519 from trezor.crypto.curve import ed25519
from trezor.messages import TezosContractType from trezor.messages import TezosBallotType, TezosContractType
from trezor.messages.TezosSignedTx import TezosSignedTx from trezor.messages.TezosSignedTx import TezosSignedTx
from apps.common import paths from apps.common import paths
from apps.common.writers import write_bytes, write_uint8 from apps.common.writers import write_bytes, write_uint8, write_uint32_be
from apps.tezos import CURVE, helpers, layout from apps.tezos import CURVE, helpers, layout
PROPOSAL_LENGTH = const(32)
async def sign_tx(ctx, msg, keychain): async def sign_tx(ctx, msg, keychain):
await paths.validate_path( await paths.validate_path(
@ -52,6 +56,15 @@ async def sign_tx(ctx, msg, keychain):
ctx, source, msg.delegation.fee ctx, source, msg.delegation.fee
) )
elif msg.proposal is not None:
proposed_protocols = [_get_protocol_hash(p) for p in msg.proposal.proposals]
await layout.require_confirm_proposals(ctx, proposed_protocols)
elif msg.ballot is not None:
proposed_protocol = _get_protocol_hash(msg.ballot.proposal)
submitted_ballot = _get_ballot(msg.ballot.ballot)
await layout.require_confirm_ballot(ctx, proposed_protocol, submitted_ballot)
else: else:
raise wire.DataError("Invalid operation") raise wire.DataError("Invalid operation")
@ -101,11 +114,24 @@ def _get_address_from_contract(address):
raise wire.DataError("Invalid contract type") raise wire.DataError("Invalid contract type")
def _get_protocol_hash(proposal):
return helpers.base58_encode_check(proposal, prefix="P")
def _get_ballot(ballot):
if ballot == TezosBallotType.Yay:
return "yay"
elif ballot == TezosBallotType.Nay:
return "nay"
elif ballot == TezosBallotType.Pass:
return "pass"
def _get_operation_bytes(w: bytearray, msg): def _get_operation_bytes(w: bytearray, msg):
write_bytes(w, msg.branch) write_bytes(w, msg.branch)
# when the account sends first operation in lifetime, # when the account sends first operation in lifetime,
# we need to reveal its publickey # we need to reveal its public key
if msg.reveal is not None: if msg.reveal is not None:
_encode_common(w, msg.reveal, "reveal") _encode_common(w, msg.reveal, "reveal")
write_bytes(w, msg.reveal.public_key) write_bytes(w, msg.reveal.public_key)
@ -121,14 +147,18 @@ def _get_operation_bytes(w: bytearray, msg):
_encode_common(w, msg.origination, "origination") _encode_common(w, msg.origination, "origination")
write_bytes(w, msg.origination.manager_pubkey) write_bytes(w, msg.origination.manager_pubkey)
_encode_zarith(w, msg.origination.balance) _encode_zarith(w, msg.origination.balance)
_encode_bool(w, msg.origination.spendable) helpers.write_bool(w, msg.origination.spendable)
_encode_bool(w, msg.origination.delegatable) helpers.write_bool(w, msg.origination.delegatable)
_encode_data_with_bool_prefix(w, msg.origination.delegate) _encode_data_with_bool_prefix(w, msg.origination.delegate)
_encode_data_with_bool_prefix(w, msg.origination.script) _encode_data_with_bool_prefix(w, msg.origination.script)
# delegation operation # delegation operation
elif msg.delegation is not None: elif msg.delegation is not None:
_encode_common(w, msg.delegation, "delegation") _encode_common(w, msg.delegation, "delegation")
_encode_data_with_bool_prefix(w, msg.delegation.delegate) _encode_data_with_bool_prefix(w, msg.delegation.delegate)
elif msg.proposal is not None:
_encode_proposal(w, msg.proposal)
elif msg.ballot is not None:
_encode_ballot(w, msg.ballot)
def _encode_common(w: bytearray, operation, str_operation): def _encode_common(w: bytearray, operation, str_operation):
@ -146,19 +176,12 @@ def _encode_contract_id(w: bytearray, contract_id):
write_bytes(w, contract_id.hash) write_bytes(w, contract_id.hash)
def _encode_bool(w: bytearray, boolean):
if boolean:
write_uint8(w, 255)
else:
write_uint8(w, 0)
def _encode_data_with_bool_prefix(w: bytearray, data): def _encode_data_with_bool_prefix(w: bytearray, data):
if data: if data:
_encode_bool(w, True) helpers.write_bool(w, True)
write_bytes(w, data) write_bytes(w, data)
else: else:
_encode_bool(w, False) helpers.write_bool(w, False)
def _encode_zarith(w: bytearray, num): def _encode_zarith(w: bytearray, num):
@ -171,3 +194,24 @@ def _encode_zarith(w: bytearray, num):
break break
write_uint8(w, 128 | byte) write_uint8(w, 128 | byte)
def _encode_proposal(w: bytearray, proposal):
proposal_tag = 5
write_uint8(w, proposal_tag)
write_bytes(w, proposal.source)
write_uint32_be(w, proposal.period)
write_uint32_be(w, len(proposal.proposals) * PROPOSAL_LENGTH)
for proposal_hash in proposal.proposals:
write_bytes(w, proposal_hash)
def _encode_ballot(w: bytearray, ballot):
ballot_tag = 6
write_uint8(w, ballot_tag)
write_bytes(w, ballot.source)
write_uint32_be(w, ballot.period)
write_bytes(w, ballot.proposal)
write_uint8(w, ballot.ballot)

View File

@ -204,7 +204,7 @@ def validate_full_path(
See docs/coins for what paths are allowed. Please note that this is not See docs/coins for what paths are allowed. Please note that this is not
a comprehensive check, some nuances are omitted for simplification. a comprehensive check, some nuances are omitted for simplification.
""" """
if len(path) != 5: if len(path) not in (4, 5, 6):
return False return False
if not validate_purpose(path[0], coin): if not validate_purpose(path[0], coin):
@ -214,21 +214,29 @@ def validate_full_path(
): ):
return False return False
if path[1] != coin.slip44 | HARDENED: if path[1] > 20 and path[1] != coin.slip44 | HARDENED:
return False return False
if path[2] < HARDENED or path[2] > 20 | HARDENED: if (path[2] > 20 and path[2] < HARDENED) or path[2] > 20 | HARDENED:
return False return False
if path[3] not in [0, 1]: if path[3] not in (0, 1, 0 | HARDENED, 1 | HARDENED, 2 | HARDENED):
return False return False
if path[4] > 1000000: if len(path) > 4 and path[4] > 1000000:
return False
if len(path) > 5 and path[5] > 1000000:
return False return False
return True return True
def validate_purpose(purpose: int, coin: CoinInfo) -> bool: def validate_purpose(purpose: int, coin: CoinInfo) -> bool:
if purpose not in (44 | HARDENED, 48 | HARDENED, 49 | HARDENED, 84 | HARDENED): if purpose not in (
44 | HARDENED,
45 | HARDENED,
48 | HARDENED,
49 | HARDENED,
84 | HARDENED,
):
return False return False
if not coin.segwit and purpose not in (44 | HARDENED, 48 | HARDENED): if not coin.segwit and purpose not in (44 | HARDENED, 45 | HARDENED, 48 | HARDENED):
return False return False
return True return True
@ -239,21 +247,23 @@ def validate_purpose_against_script_type(
""" """
Validates purpose against provided input's script type: Validates purpose against provided input's script type:
- 44 for spending address (script_type == SPENDADDRESS) - 44 for spending address (script_type == SPENDADDRESS)
- 48 for multisig (script_type == SPENDMULTISIG) - 45, 48 for multisig (script_type == SPENDMULTISIG)
- 49 for p2sh-segwit spend (script_type == SPENDP2SHWITNESS) - 49 for p2wsh-nested-in-p2sh spend (script_type == SPENDP2SHWITNESS)
- 84 for native segwit spend (script_type == SPENDWITNESS) - 84 for p2wsh native segwit spend (script_type == SPENDWITNESS)
""" """
if purpose == 44 | HARDENED and script_type != InputScriptType.SPENDADDRESS: if purpose == 44 | HARDENED and script_type != InputScriptType.SPENDADDRESS:
return False return False
if purpose == 48 | HARDENED and script_type != InputScriptType.SPENDMULTISIG: if purpose == 45 | HARDENED and script_type != InputScriptType.SPENDMULTISIG:
return False return False
if ( # p2wsh-nested-in-p2sh if purpose == 48 | HARDENED and script_type not in (
purpose == 49 | HARDENED and script_type != InputScriptType.SPENDP2SHWITNESS InputScriptType.SPENDMULTISIG,
InputScriptType.SPENDP2SHWITNESS,
InputScriptType.SPENDWITNESS,
): ):
return False return False
if ( # p2wsh if purpose == 49 | HARDENED and script_type != InputScriptType.SPENDP2SHWITNESS:
purpose == 84 | HARDENED and script_type != InputScriptType.SPENDWITNESS return False
): if purpose == 84 | HARDENED and script_type != InputScriptType.SPENDWITNESS:
return False return False
return True return True

View File

@ -24,5 +24,5 @@ def report_init():
def report(): def report():
p = int(1000 * _progress / _steps) p = 1000 * _progress // _steps
ui.display.loader(p, 18, ui.WHITE, ui.BG) ui.display.loader(p, False, 18, ui.WHITE, ui.BG)

View File

@ -29,6 +29,8 @@ class MoneroTransactionData(p.MessageType):
rsig_data: MoneroTransactionRsigData = None, rsig_data: MoneroTransactionRsigData = None,
integrated_indices: List[int] = None, integrated_indices: List[int] = None,
client_version: int = None, client_version: int = None,
hard_fork: int = None,
monero_version: bytes = None,
) -> None: ) -> None:
self.version = version self.version = version
self.payment_id = payment_id self.payment_id = payment_id
@ -43,6 +45,8 @@ class MoneroTransactionData(p.MessageType):
self.rsig_data = rsig_data self.rsig_data = rsig_data
self.integrated_indices = integrated_indices if integrated_indices is not None else [] self.integrated_indices = integrated_indices if integrated_indices is not None else []
self.client_version = client_version self.client_version = client_version
self.hard_fork = hard_fork
self.monero_version = monero_version
@classmethod @classmethod
def get_fields(cls): def get_fields(cls):
@ -60,4 +64,6 @@ class MoneroTransactionData(p.MessageType):
11: ('rsig_data', MoneroTransactionRsigData, 0), 11: ('rsig_data', MoneroTransactionRsigData, 0),
12: ('integrated_indices', p.UVarintType, p.FLAG_REPEATED), 12: ('integrated_indices', p.UVarintType, p.FLAG_REPEATED),
13: ('client_version', p.UVarintType, 0), 13: ('client_version', p.UVarintType, 0),
14: ('hard_fork', p.UVarintType, 0),
15: ('monero_version', p.BytesType, 0),
} }

View File

@ -0,0 +1,27 @@
# Automatically generated by pb2py
# fmt: off
import protobuf as p
class TezosBallotOp(p.MessageType):
def __init__(
self,
source: bytes = None,
period: int = None,
proposal: bytes = None,
ballot: int = None,
) -> None:
self.source = source
self.period = period
self.proposal = proposal
self.ballot = ballot
@classmethod
def get_fields(cls):
return {
1: ('source', p.BytesType, 0),
2: ('period', p.UVarintType, 0),
3: ('proposal', p.BytesType, 0),
4: ('ballot', p.UVarintType, 0),
}

View File

@ -0,0 +1,5 @@
# Automatically generated by pb2py
# fmt: off
Yay = 0
Nay = 1
Pass = 2

View File

@ -0,0 +1,30 @@
# Automatically generated by pb2py
# fmt: off
import protobuf as p
if __debug__:
try:
from typing import List
except ImportError:
List = None # type: ignore
class TezosProposalOp(p.MessageType):
def __init__(
self,
source: bytes = None,
period: int = None,
proposals: List[bytes] = None,
) -> None:
self.source = source
self.period = period
self.proposals = proposals if proposals is not None else []
@classmethod
def get_fields(cls):
return {
1: ('source', p.BytesType, 0),
2: ('period', p.UVarintType, 0),
4: ('proposals', p.BytesType, p.FLAG_REPEATED),
}

View File

@ -2,8 +2,10 @@
# fmt: off # fmt: off
import protobuf as p import protobuf as p
from .TezosBallotOp import TezosBallotOp
from .TezosDelegationOp import TezosDelegationOp from .TezosDelegationOp import TezosDelegationOp
from .TezosOriginationOp import TezosOriginationOp from .TezosOriginationOp import TezosOriginationOp
from .TezosProposalOp import TezosProposalOp
from .TezosRevealOp import TezosRevealOp from .TezosRevealOp import TezosRevealOp
from .TezosTransactionOp import TezosTransactionOp from .TezosTransactionOp import TezosTransactionOp
@ -25,6 +27,8 @@ class TezosSignTx(p.MessageType):
transaction: TezosTransactionOp = None, transaction: TezosTransactionOp = None,
origination: TezosOriginationOp = None, origination: TezosOriginationOp = None,
delegation: TezosDelegationOp = None, delegation: TezosDelegationOp = None,
proposal: TezosProposalOp = None,
ballot: TezosBallotOp = None,
) -> None: ) -> None:
self.address_n = address_n if address_n is not None else [] self.address_n = address_n if address_n is not None else []
self.branch = branch self.branch = branch
@ -32,6 +36,8 @@ class TezosSignTx(p.MessageType):
self.transaction = transaction self.transaction = transaction
self.origination = origination self.origination = origination
self.delegation = delegation self.delegation = delegation
self.proposal = proposal
self.ballot = ballot
@classmethod @classmethod
def get_fields(cls): def get_fields(cls):
@ -42,4 +48,6 @@ class TezosSignTx(p.MessageType):
4: ('transaction', TezosTransactionOp, 0), 4: ('transaction', TezosTransactionOp, 0),
5: ('origination', TezosOriginationOp, 0), 5: ('origination', TezosOriginationOp, 0),
6: ('delegation', TezosDelegationOp, 0), 6: ('delegation', TezosDelegationOp, 0),
7: ('proposal', TezosProposalOp, 0),
8: ('ballot', TezosBallotOp, 0),
} }

View File

@ -31,6 +31,6 @@ def get_type(wire_type):
for msg_name in dir(MessageType): for msg_name in dir(MessageType):
# Modules contain internal variables that may cause exception here. # Modules contain internal variables that may cause exception here.
# No Message begins with underscore so it's safe to skip those. # No Message begins with underscore so it's safe to skip those.
if (msg_name[0] == '_'): if msg_name[0] == "_":
continue continue
type_to_name[getattr(MessageType, msg_name)] = msg_name type_to_name[getattr(MessageType, msg_name)] = msg_name

View File

@ -18,7 +18,7 @@ def show_pin_timeout(seconds: int, progress: int, message: str) -> bool:
ui.display.text_center( ui.display.text_center(
ui.WIDTH // 2, 37, message, ui.BOLD, ui.FG, ui.BG, ui.WIDTH ui.WIDTH // 2, 37, message, ui.BOLD, ui.FG, ui.BG, ui.WIDTH
) )
ui.display.loader(progress, 0, ui.FG, ui.BG) ui.display.loader(progress, False, 0, ui.FG, ui.BG)
if seconds == 0: if seconds == 0:
ui.display.text_center( ui.display.text_center(
ui.WIDTH // 2, ui.HEIGHT - 22, "Done", ui.BOLD, ui.FG, ui.BG, ui.WIDTH ui.WIDTH // 2, ui.HEIGHT - 22, "Done", ui.BOLD, ui.FG, ui.BG, ui.WIDTH

View File

@ -47,12 +47,15 @@ class Loader(ui.Widget):
else: else:
s = self.normal_style s = self.normal_style
if s["icon"] is None: if s["icon"] is None:
ui.display.loader(r, -24, s["fg-color"], s["bg-color"]) ui.display.loader(r, False, -24, s["fg-color"], s["bg-color"])
elif s["icon-fg-color"] is None: elif s["icon-fg-color"] is None:
ui.display.loader(r, -24, s["fg-color"], s["bg-color"], res.load(s["icon"])) ui.display.loader(
r, False, -24, s["fg-color"], s["bg-color"], res.load(s["icon"])
)
else: else:
ui.display.loader( ui.display.loader(
r, r,
False,
-24, -24,
s["fg-color"], s["fg-color"],
s["bg-color"], s["bg-color"],

View File

@ -21,9 +21,9 @@ async def change_page(page, page_count):
else: else:
s = await swipe s = await swipe
if s == SWIPE_UP: if s == SWIPE_UP:
return page + 1 # scroll down return min(page + 1, page_count - 1) # scroll down
elif s == SWIPE_DOWN: elif s == SWIPE_DOWN:
return page - 1 # scroll up return max(page - 1, 0) # scroll up
async def paginate(render_page, page_count, page=0, *args): async def paginate(render_page, page_count, page=0, *args):

View File

@ -62,7 +62,6 @@ bus = io.USB(
product="TREZOR", product="TREZOR",
interface="TREZOR Interface", interface="TREZOR Interface",
serial_number=get_device_id(), serial_number=get_device_id(),
usb21_landing=False,
) )
bus.add(iface_wire) bus.add(iface_wire)
if __debug__: if __debug__:

View File

@ -46,10 +46,11 @@ class TestTezosAddress(unittest.TestCase):
[44 | HARDENED], [44 | HARDENED],
[44 | HARDENED, 1729 | HARDENED], [44 | HARDENED, 1729 | HARDENED],
[44 | HARDENED, 1729 | HARDENED, 0], [44 | HARDENED, 1729 | HARDENED, 0],
[44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 0 | HARDENED], [44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 0],
[44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 0 | HARDENED, 0 | HARDENED], [44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 0 | HARDENED, 0 | HARDENED],
[44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 1, 0], [44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 1, 0],
[44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 0, 0], [44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 0, 0],
[44 | HARDENED, 1729 | HARDENED, 1 | HARDENED, 1 | HARDENED],
[44 | HARDENED, 1729 | HARDENED, 9999000 | HARDENED], [44 | HARDENED, 1729 | HARDENED, 9999000 | HARDENED],
[44 | HARDENED, 60 | HARDENED, 0 | HARDENED, 0, 0], [44 | HARDENED, 60 | HARDENED, 0 | HARDENED, 0, 0],
[1 | HARDENED, 1 | HARDENED, 1 | HARDENED], [1 | HARDENED, 1 | HARDENED, 1 | HARDENED],
@ -58,6 +59,9 @@ class TestTezosAddress(unittest.TestCase):
[44 | HARDENED, 1729 | HARDENED, 0 | HARDENED], [44 | HARDENED, 1729 | HARDENED, 0 | HARDENED],
[44 | HARDENED, 1729 | HARDENED, 3 | HARDENED], [44 | HARDENED, 1729 | HARDENED, 3 | HARDENED],
[44 | HARDENED, 1729 | HARDENED, 9 | HARDENED], [44 | HARDENED, 1729 | HARDENED, 9 | HARDENED],
[44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 0 | HARDENED],
[44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 3 | HARDENED],
[44 | HARDENED, 1729 | HARDENED, 0 | HARDENED, 9 | HARDENED],
] ]
for path in incorrect_paths: for path in incorrect_paths:

View File

@ -4,9 +4,8 @@ from common import *
from trezor.messages import TezosContractType from trezor.messages import TezosContractType
from trezor.messages.TezosContractID import TezosContractID from trezor.messages.TezosContractID import TezosContractID
from apps.tezos.helpers import base58_decode_check, base58_encode_check from apps.tezos.helpers import base58_decode_check, base58_encode_check, write_bool
from apps.tezos.sign_tx import ( from apps.tezos.sign_tx import (
_encode_bool,
_encode_contract_id, _encode_contract_id,
_encode_data_with_bool_prefix, _encode_data_with_bool_prefix,
_encode_zarith, _encode_zarith,
@ -35,11 +34,11 @@ class TestTezosEncoding(unittest.TestCase):
def test_tezos_encode_bool(self): def test_tezos_encode_bool(self):
w = bytearray() w = bytearray()
_encode_bool(w, True) write_bool(w, True)
self.assertEqual(bytes(w), bytes([255])) self.assertEqual(bytes(w), bytes([255]))
w = bytearray() w = bytearray()
_encode_bool(w, False) write_bool(w, False)
self.assertEqual(bytes(w), bytes([0])) self.assertEqual(bytes(w), bytes([0]))
def test_tezos_encode_contract_id(self): def test_tezos_encode_contract_id(self):

View File

@ -130,7 +130,7 @@ class TestAddress(unittest.TestCase):
([49 | HARDENED], InputScriptType.SPENDP2SHWITNESS), # invalid length ([49 | HARDENED], InputScriptType.SPENDP2SHWITNESS), # invalid length
([49 | HARDENED, 0 | HARDENED, 0 | HARDENED, 0 | HARDENED, 0 | HARDENED], InputScriptType.SPENDP2SHWITNESS), # too many HARDENED ([49 | HARDENED, 0 | HARDENED, 0 | HARDENED, 0 | HARDENED, 0 | HARDENED], InputScriptType.SPENDP2SHWITNESS), # too many HARDENED
([49 | HARDENED, 0 | HARDENED], InputScriptType.SPENDP2SHWITNESS), # invalid length ([49 | HARDENED, 0 | HARDENED], InputScriptType.SPENDP2SHWITNESS), # invalid length
([49 | HARDENED, 0 | HARDENED, 0 | HARDENED, 0, 0, 0], InputScriptType.SPENDP2SHWITNESS), # invalid length ([49 | HARDENED, 0 | HARDENED, 0 | HARDENED, 0, 0, 0, 0], InputScriptType.SPENDP2SHWITNESS), # invalid length
([49 | HARDENED, 123 | HARDENED, 0 | HARDENED, 0, 0, 0], InputScriptType.SPENDP2SHWITNESS), # invalid slip44 ([49 | HARDENED, 123 | HARDENED, 0 | HARDENED, 0, 0, 0], InputScriptType.SPENDP2SHWITNESS), # invalid slip44
([49 | HARDENED, 0 | HARDENED, 1000 | HARDENED, 0, 0], InputScriptType.SPENDP2SHWITNESS), # account too high ([49 | HARDENED, 0 | HARDENED, 1000 | HARDENED, 0, 0], InputScriptType.SPENDP2SHWITNESS), # account too high
([49 | HARDENED, 0 | HARDENED, 1 | HARDENED, 2, 0], InputScriptType.SPENDP2SHWITNESS), # invalid y ([49 | HARDENED, 0 | HARDENED, 1 | HARDENED, 2, 0], InputScriptType.SPENDP2SHWITNESS), # invalid y
@ -172,7 +172,7 @@ class TestAddress(unittest.TestCase):
([49 | HARDENED, 145 | HARDENED, 0 | HARDENED, 0, 0], InputScriptType.SPENDP2SHWITNESS), # bch is not segwit coin so 49' is not allowed ([49 | HARDENED, 145 | HARDENED, 0 | HARDENED, 0, 0], InputScriptType.SPENDP2SHWITNESS), # bch is not segwit coin so 49' is not allowed
([84 | HARDENED, 145 | HARDENED, 1 | HARDENED, 0, 1], InputScriptType.SPENDWITNESS), # and neither is 84' ([84 | HARDENED, 145 | HARDENED, 1 | HARDENED, 0, 1], InputScriptType.SPENDWITNESS), # and neither is 84'
([44 | HARDENED, 145 | HARDENED], InputScriptType.SPENDADDRESS), # invalid length ([44 | HARDENED, 145 | HARDENED], InputScriptType.SPENDADDRESS), # invalid length
([44 | HARDENED, 145 | HARDENED, 0 | HARDENED, 0, 0, 0], InputScriptType.SPENDADDRESS), # invalid length ([44 | HARDENED, 145 | HARDENED, 0 | HARDENED, 0, 0, 0, 0], InputScriptType.SPENDADDRESS), # invalid length
([44 | HARDENED, 123 | HARDENED, 0 | HARDENED, 0, 0, 0], InputScriptType.SPENDADDRESS), # invalid slip44 ([44 | HARDENED, 123 | HARDENED, 0 | HARDENED, 0, 0, 0], InputScriptType.SPENDADDRESS), # invalid slip44
([44 | HARDENED, 145 | HARDENED, 1000 | HARDENED, 0, 0], InputScriptType.SPENDADDRESS), # account too high ([44 | HARDENED, 145 | HARDENED, 1000 | HARDENED, 0, 0], InputScriptType.SPENDADDRESS), # account too high
([44 | HARDENED, 145 | HARDENED, 1 | HARDENED, 2, 0], InputScriptType.SPENDADDRESS), # invalid y ([44 | HARDENED, 145 | HARDENED, 1 | HARDENED, 2, 0], InputScriptType.SPENDADDRESS), # invalid y

View File

@ -39,7 +39,7 @@ class TestDisplay(unittest.TestCase):
display.qrcode(0, 0, 'Test', 4) display.qrcode(0, 0, 'Test', 4)
def test_loader(self): def test_loader(self):
display.loader(333, 0, 0xFFFF, 0x0000) display.loader(333, False, 0, 0xFFFF, 0x0000)
def test_orientation(self): def test_orientation(self):
for o in [0, 90, 180, 270]: for o in [0, 90, 180, 270]:

View File

@ -1,5 +1,6 @@
#!/bin/bash #!/bin/bash
set -e set -e
cd $(dirname $0)
rm -f ../src/trezor/messages/[A-Z]*.py rm -f ../src/trezor/messages/[A-Z]*.py
../vendor/trezor-common/protob/pb2py \ ../vendor/trezor-common/protob/pb2py \

View File

@ -1,21 +0,0 @@
#!/bin/sh
# libsodium-dev replacement
#
# The purpose of this file is to install libsodium in
# the Travis CI environment. Outside this environment,
# you would probably not want to install it like this.
set -e
export LIBSODIUM_VER="1.0.16"
# check if libsodium is already installed
if [ ! -d "$HOME/libsodium/lib" ]; then
wget "https://github.com/jedisct1/libsodium/releases/download/${LIBSODIUM_VER}/libsodium-${LIBSODIUM_VER}.tar.gz"
tar xvfz "libsodium-${LIBSODIUM_VER}.tar.gz"
cd "libsodium-${LIBSODIUM_VER}"
./configure --prefix=$HOME/libsodium
make
make install
else
echo 'Using cached directory.'
fi

File diff suppressed because it is too large Load Diff

View File

@ -1,257 +0,0 @@
#!/usr/bin/perl -w
#
# stackcolllapse-perf.pl collapse perf samples into single lines.
#
# Parses a list of multiline stacks generated by "perf script", and
# outputs a semicolon separated stack followed by a space and a count.
# If memory addresses (+0xd) are present, they are stripped, and resulting
# identical stacks are colased with their counts summed.
#
# USAGE: ./stackcollapse-perf.pl [options] infile > outfile
#
# Run "./stackcollapse-perf.pl -h" to list options.
#
# Example input:
#
# swapper 0 [000] 158665.570607: cpu-clock:
# ffffffff8103ce3b native_safe_halt ([kernel.kallsyms])
# ffffffff8101c6a3 default_idle ([kernel.kallsyms])
# ffffffff81013236 cpu_idle ([kernel.kallsyms])
# ffffffff815bf03e rest_init ([kernel.kallsyms])
# ffffffff81aebbfe start_kernel ([kernel.kallsyms].init.text)
# [...]
#
# Example output:
#
# swapper;start_kernel;rest_init;cpu_idle;default_idle;native_safe_halt 1
#
# Input may be created and processed using:
#
# perf record -a -g -F 997 sleep 60
# perf script | ./stackcollapse-perf.pl > out.stacks-folded
#
# The output of "perf script" should include stack traces. If these are missing
# for you, try manually selecting the perf script output; eg:
#
# perf script -f comm,pid,tid,cpu,time,event,ip,sym,dso,trace | ...
#
# This is also required for the --pid or --tid options, so that the output has
# both the PID and TID.
#
# Copyright 2012 Joyent, Inc. All rights reserved.
# Copyright 2012 Brendan Gregg. All rights reserved.
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at docs/cddl1.txt or
# http://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at docs/cddl1.txt.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# 02-Mar-2012 Brendan Gregg Created this.
# 02-Jul-2014 " " Added process name to stacks.
use strict;
use Getopt::Long;
my %collapsed;
sub remember_stack {
my ($stack, $count) = @_;
$collapsed{$stack} += $count;
}
my $annotate_kernel = 0; # put an annotation on kernel function
my $include_pname = 1; # include process names in stacks
my $include_pid = 0; # include process ID with process name
my $include_tid = 0; # include process & thread ID with process name
my $tidy_java = 1; # condense Java signatures
my $tidy_generic = 1; # clean up function names a little
my $target_pname; # target process name from perf invocation
my $show_inline = 0;
my $show_context = 0;
GetOptions('inline' => \$show_inline,
'context' => \$show_context,
'pid' => \$include_pid,
'kernel' => \$annotate_kernel,
'tid' => \$include_tid)
or die <<USAGE_END;
USAGE: $0 [options] infile > outfile\n
--pid # include PID with process names [1]
--tid # include TID and PID with process names [1]
--inline # un-inline using addr2line
--kernel # annotate kernel functions with a _[k]
--context # include source context from addr2line\n
[1] perf script must emit both PID and TIDs for these to work; eg:
perf script -f comm,pid,tid,cpu,time,event,ip,sym,dso,trace
USAGE_END
# for the --inline option
sub inline {
my ($pc, $mod) = @_;
# capture addr2line output
my $a2l_output = `addr2line -a $pc -e $mod -i -f -s -C`;
# remove first line
$a2l_output =~ s/^(.*\n){1}//;
my @fullfunc;
my $one_item = "";
for (split /^/, $a2l_output) {
chomp $_;
# remove discriminator info if exists
$_ =~ s/ \(discriminator \S+\)//;
if ($one_item eq "") {
$one_item = $_;
} else {
if ($show_context == 1) {
unshift @fullfunc, $one_item . ":$_";
} else {
unshift @fullfunc, $one_item;
}
$one_item = "";
}
}
return join(";", @fullfunc);
}
my @stack;
my $pname;
#
# Main loop
#
while (defined($_ = <>)) {
# find the name of the process launched by perf, by stepping backwards
# over the args to find the first non-option (no dash):
if (/^# cmdline/) {
my @args = split ' ', $_;
foreach my $arg (reverse @args) {
if ($arg !~ /^-/) {
$target_pname = $arg;
$target_pname =~ s:.*/::; # strip pathname
last;
}
}
}
# skip remaining comments
next if m/^#/;
chomp;
# end of stack. save cached data.
if (m/^$/) {
if ($include_pname) {
if (defined $pname) {
unshift @stack, $pname;
} else {
unshift @stack, "";
}
}
remember_stack(join(";", @stack), 1) if @stack;
undef @stack;
undef $pname;
next;
}
# event record start
if (/^(\S+\s*?\S*?)\s+(\d+)\s/) {
# default "perf script" output has TID but not PID
# eg, "java 25607 4794564.109216: cycles:"
# eg, "java 12688 [002] 6544038.708352: cpu-clock:"
# eg, "V8 WorkerThread 25607 4794564.109216: cycles:"
# other combinations possible
if ($include_tid) {
$pname = "$1-?/$2";
} elsif ($include_pid) {
$pname = "$1-?";
} else {
$pname = $1;
}
$pname =~ tr/ /_/;
} elsif (/^(\S+\s*?\S*?)\s+(\d+)\/(\d+)/) {
# eg, "java 24636/25607 [000] 4794564.109216: cycles:"
# eg, "java 12688/12764 6544038.708352: cpu-clock:"
# eg, "V8 WorkerThread 24636/25607 [000] 94564.109216: cycles:"
# other combinations possible
if ($include_tid) {
$pname = "$1-$2/$3";
} elsif ($include_pid) {
$pname = "$1-$2";
} else {
$pname = $1;
}
$pname =~ tr/ /_/;
# stack line
} elsif (/^\s*(\w+)\s*(.+) \((\S*)\)/) {
my ($pc, $rawfunc, $mod) = ($1, $2, $3);
$rawfunc.="_[k]" if ($annotate_kernel == 1 && $mod =~ m/kernel\./);
if ($show_inline == 1 && $mod !~ m/(perf-\d+.map|kernel\.|\[[^\]]+\])/) {
unshift @stack, inline($pc, $mod);
next;
}
next if $rawfunc =~ /^\(/; # skip process names
my @inline;
for (split /\->/, $rawfunc) {
my $func = $_;
if ($tidy_generic) {
$func =~ s/;/:/g;
$func =~ tr/<>//d;
if ($func !~ m/\.\(.*\)\./) {
# This doesn't look like a Go method name (such as
# "net/http.(*Client).Do"), so everything after the first open
# paren is just noise.
$func =~ s/\(.*//;
}
# now tidy this horrible thing:
# 13a80b608e0a RegExp:[&<>\"\'] (/tmp/perf-7539.map)
$func =~ tr/"\'//d;
# fall through to $tidy_java
}
if ($tidy_java and $pname eq "java") {
# along with $tidy_generic, converts the following:
# Lorg/mozilla/javascript/ContextFactory;.call(Lorg/mozilla/javascript/ContextAction;)Ljava/lang/Object;
# Lorg/mozilla/javascript/ContextFactory;.call(Lorg/mozilla/javascript/C
# Lorg/mozilla/javascript/MemberBox;.<init>(Ljava/lang/reflect/Method;)V
# into:
# org/mozilla/javascript/ContextFactory:.call
# org/mozilla/javascript/ContextFactory:.call
# org/mozilla/javascript/MemberBox:.init
$func =~ s/^L// if $func =~ m:/:;
}
$func .= "_[i]" if scalar(@inline) > 0; #inlined
push @inline, $func;
}
unshift @stack, @inline;
} else {
warn "Unrecognized line: $_";
}
}
foreach my $k (sort { $a cmp $b } keys %collapsed) {
print "$k $collapsed{$k}\n";
}

View File

@ -1,2 +0,0 @@
---
BasedOnStyle: Google

View File

@ -1,38 +0,0 @@
sudo: false
dist: trusty
language: c
compiler:
- clang
- gcc
addons:
apt:
packages:
- check
- libssl-dev
- python3-pip
- valgrind
env:
global:
- PYTHON=python3
install:
- $PYTHON -m pip install --user pytest ecdsa curve25519-donna pyasn1
script:
- make
- ./tests/aestst
- ./tests/test_check
- CK_TIMEOUT_MULTIPLIER=20 valgrind -q --error-exitcode=1 ./tests/test_check
- ./tests/test_openssl 1000
- ITERS=10 $PYTHON -m pytest tests/
notifications:
webhooks:
urls:
- http://ci-bot.satoshilabs.com:5000/travis
on_success: always
on_failure: always
on_start: always

View File

@ -63,6 +63,7 @@ SRCS += rc4.c
SRCS += nem.c SRCS += nem.c
SRCS += segwit_addr.c cash_addr.c SRCS += segwit_addr.c cash_addr.c
SRCS += memzero.c SRCS += memzero.c
SRCS += schnorr.c
SRCS += shamir.c SRCS += shamir.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)

104
crypto/schnorr.c Normal file
View File

@ -0,0 +1,104 @@
/**
* Copyright (c) 2019 Anatolii Kurotych
*
* 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 "schnorr.h"
#include "memzero.h"
// r = H(Q, kpub, m)
static void calc_r(const curve_point *Q, const uint8_t pub_key[33],
const uint8_t *msg, const uint32_t msg_len, bignum256 *r) {
uint8_t Q_compress[33];
compress_coords(Q, Q_compress);
SHA256_CTX ctx;
uint8_t digest[SHA256_DIGEST_LENGTH];
sha256_Init(&ctx);
sha256_Update(&ctx, Q_compress, 33);
sha256_Update(&ctx, pub_key, 33);
sha256_Update(&ctx, msg, msg_len);
sha256_Final(&ctx, digest);
bn_read_be(digest, r);
}
// returns 0 if signing succeeded
int schnorr_sign(const ecdsa_curve *curve, const uint8_t *priv_key,
const bignum256 *k, const uint8_t *msg, const uint32_t msg_len,
schnorr_sign_pair *result) {
bignum256 private_key_scalar;
bn_read_be(priv_key, &private_key_scalar);
uint8_t pub_key[33];
ecdsa_get_public_key33(curve, priv_key, pub_key);
/* Q = kG */
curve_point Q;
scalar_multiply(curve, k, &Q);
/* r = H(Q, kpub, m) */
calc_r(&Q, pub_key, msg, msg_len, &result->r);
/* s = k - r*kpriv mod(order) */
bignum256 s_temp;
bn_copy(&result->r, &s_temp);
bn_multiply(&private_key_scalar, &s_temp, &curve->order);
bn_subtractmod(k, &s_temp, &result->s, &curve->order);
memzero(&private_key_scalar, sizeof(private_key_scalar));
while (bn_is_less(&curve->order, &result->s)) {
bn_mod(&result->s, &curve->order);
}
if (bn_is_zero(&result->s) || bn_is_zero(&result->r)) {
return 1;
}
return 0;
}
// returns 0 if verification succeeded
int schnorr_verify(const ecdsa_curve *curve, const uint8_t *pub_key,
const uint8_t *msg, const uint32_t msg_len,
const schnorr_sign_pair *sign) {
if (msg_len == 0) return 1;
if (bn_is_zero(&sign->r)) return 2;
if (bn_is_zero(&sign->s)) return 3;
if (bn_is_less(&curve->order, &sign->r)) return 4;
if (bn_is_less(&curve->order, &sign->s)) return 5;
curve_point pub_key_point;
if (!ecdsa_read_pubkey(curve, pub_key, &pub_key_point)) {
return 6;
}
// Compute Q = sG + r*kpub
curve_point sG, Q;
scalar_multiply(curve, &sign->s, &sG);
point_multiply(curve, &sign->r, &pub_key_point, &Q);
point_add(curve, &sG, &Q);
/* r = H(Q, kpub, m) */
bignum256 r;
calc_r(&Q, pub_key, msg, msg_len, &r);
if (bn_is_equal(&r, &sign->r)) return 0; // success
return 10;
}

42
crypto/schnorr.h Normal file
View File

@ -0,0 +1,42 @@
/**
* Copyright (c) 2019 Anatolii Kurotych
*
* 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 __SCHNORR_H__
#define __SCHNORR_H__
#include "ecdsa.h"
// result of sign operation
typedef struct {
bignum256 r, s;
} schnorr_sign_pair;
// sign/verify returns 0 if operation succeeded
// k is a random from [1, ..., order-1]
int schnorr_sign(const ecdsa_curve *curve, const uint8_t *priv_key,
const bignum256 *k, const uint8_t *msg, const uint32_t msg_len,
schnorr_sign_pair *result);
int schnorr_verify(const ecdsa_curve *curve, const uint8_t *pub_key,
const uint8_t *msg, const uint32_t msg_len,
const schnorr_sign_pair *sign);
#endif

View File

@ -61,6 +61,7 @@
#include "rand.h" #include "rand.h"
#include "rc4.h" #include "rc4.h"
#include "rfc6979.h" #include "rfc6979.h"
#include "schnorr.h"
#include "script.h" #include "script.h"
#include "secp256k1.h" #include "secp256k1.h"
#include "sha2.h" #include "sha2.h"
@ -8448,6 +8449,195 @@ START_TEST(test_compress_coords) {
} }
END_TEST END_TEST
// vectors generated using Schnorr::Sign function defined in
// https://github.com/Zilliqa/Zilliqa/blob/master/src/libCrypto/Schnorr.cpp#L88
START_TEST(test_schnorr_sign_verify) {
static struct {
const char *message;
const char *priv_key;
const char *k_hex;
const char *s_hex;
const char *r_hex;
} test_cases[] = {
{
"123",
"3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6",
"669301F724C555D7BB1185C04909E9CACA3EC7A292B3A1C92DDCCD5A5A7DDDD3",
"FFD72C290B98C93A4BCEDC0EDCDF040C35579BE962FE83E6821D4F3CB4B795D2",
"74AAE9C3E069E2806E1B0D890970BE387AEBED8040F37991AACAD70B27895E39",
},
{
"1234",
"51a2758eed776c40b367364909c8a9c98cc969104f69ff316f7a287495c37c9b",
"A0A1A9B3570AAE963535B8D4376C58A61646C18182C9FDDA5FB13703F88D4D1E",
"99A0CB942C81571B77C682F79CD3CB663CE9E1C55BB425BA24B9F11A0DE84FE2",
"C3C10363E38158BBA20556A36DE9358DFD81A31C180ABC9E7617C1CC1CAF03B3",
},
{
"12345",
"2685adffdbb4b2c515054cffc25cfcbfe2e462df65bbe82fb50f71e1e68dd285",
"38DE7B3315F201433D271E91FBE62966576CA05CBFEC1770B77D7EC9D6A01D6D",
"28982FA6C2B620CBC550F7EF9EAB605F409C584FBE5A765678877B79AB517086",
"9A0788E5B0947DEDEDE386DF57A006CF3FE43919A74D9CA630F8A1A9D97B4650",
},
{
"fun",
"7457dc574d927e5dae84b05264a5b637b5a68e34a85b3965084ed6fed5b7f12d",
"E005ABD242C7C602AB5EED080C5083C7C5F8DAEC6D046A54F384A8B8CDECF740",
"51070ABCA039DAC294F6BA3BFC8C36CFC66020EDF66D1ACF1A9B545B0BF09F52",
"330A924525EF722FA20E8E25CB6E8BD7DF4394886FA4414E4A0B6812AA25BBC0",
},
{
"funny",
"52c395a6d304de1a959e73e4604e32c5ad3f2bf01c8f730af426b38d7d5dd908",
"0CF28B5C40A8830F3195BB99A9F0E2808F576105F41D16ABCF596AC5A8CFE88A",
"3D60FB4664C994AD956378B9402BC68F7B4799D74F4783A6199C0D74865EA2B6",
"5ED5EDEE0314DFFBEE39EE4E9C76DE8BC3EB8CB891AEC32B83957514284B205B",
},
{
"What is great in man is that he is a bridge and not a goal",
"52c395a6d304de1a959e73e4604e32c5ad3f2bf01c8f730af426b38d7d5dd908",
"000000000000000000000000000000000000000000000000000000000000007B",
"546F70AA1FEE3718C95508240CDC073B9FEFED05959C5319DD8E2BF07A1DD028",
"B8667BE5E10B113608BFE5327C44E9F0462BE26F789177E10DCE53019AA33DAA",
},
{
"123456789147258369qwertyuiopasdfghjklzxcvbnm,",
"2685adffdbb4b2c515054cffc25cfcbfe2e462df65bbe82fb50f71e1e68dd285",
"1D0CB70310C4D793A4561FE592B7C156771E3E26283B28AB588E968243B52DD0",
"54D7A435E5E3F2811AA542F8895C20CCB760F2713DBDDB7291DAB6DA4E4F927E",
"20A3BDABFFF2C1BF8E2AF709F6CDCAFE70DA9A1DBC22305B6332E36844092984",
},
{
"11111111111111111111111111111111111111111111111111111111111111111"
"11111111111111111111111111111111111111111111111111111111111111111"
"111111111111111111",
"3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6",
"A669F372B3C2EEA351210082CAEC3B96767A7B222D19FF2EE3D814860F0D703A",
"4890F9AC3A8D102EE3A2A473930C01CAD29DCE3860ACB7A5DADAEF16FE808991",
"979F088E58F1814D5E462CB9F935D2924ABD8D32211D8F02DD7E0991726DF573",
},
{
"qwertyuiop[]asdfghjkl;'zxcvbnm,./1234567890-=",
"7457dc574d927e5dae84b05264a5b637b5a68e34a85b3965084ed6fed5b7f12d",
"000000000000000000000000000000000000000000000000000000000000007C",
"0AA595A649E517133D3448CA657424DD07BBED289030F0C0AA6738D26AB9A910",
"83812632F1443A70B198D112D075D886BE7BBC6EC6275AE52661E52B7358BB8B",
},
};
const ecdsa_curve *curve = &secp256k1;
bignum256 k;
uint8_t priv_key[32], buf_raw[32];
schnorr_sign_pair result;
for (size_t i = 0; i < sizeof(test_cases) / sizeof(*test_cases); i++) {
memcpy(priv_key, fromhex(test_cases[i].priv_key), 32);
memcpy(&buf_raw, fromhex(test_cases[i].k_hex), 32);
bn_read_be(buf_raw, &k);
schnorr_sign(curve, priv_key, &k, (const uint8_t *)test_cases[i].message,
strlen(test_cases[i].message), &result);
schnorr_sign_pair expected;
memcpy(&buf_raw, fromhex(test_cases[i].s_hex), 32);
bn_read_be(buf_raw, &expected.s);
memcpy(&buf_raw, fromhex(test_cases[i].r_hex), 32);
bn_read_be(buf_raw, &expected.r);
ck_assert_mem_eq(&expected.r, &result.r, 32);
ck_assert_mem_eq(&expected.s, &result.s, 32);
uint8_t pub_key[33];
ecdsa_get_public_key33(curve, priv_key, pub_key);
int res =
schnorr_verify(curve, pub_key, (const uint8_t *)test_cases[i].message,
strlen(test_cases[i].message), &result);
ck_assert_int_eq(res, 0);
}
}
END_TEST
// vectors generated using Schnorr::Sign function defined in
// https://github.com/Zilliqa/Zilliqa/blob/master/src/libCrypto/Schnorr.cpp#L88
START_TEST(test_schnorr_fail_verify) {
static struct {
const char *message;
const char *priv_key;
const char *k_hex;
const char *s_hex;
const char *r_hex;
} test_case = {
"123",
"3382266517e2ebe6df51faf4bfe612236ad46fb8bd59ac982a223b045e080ac6",
"669301F724C555D7BB1185C04909E9CACA3EC7A292B3A1C92DDCCD5A5A7DDDD3",
"FFD72C290B98C93A4BCEDC0EDCDF040C35579BE962FE83E6821D4F3CB4B795D2",
"74AAE9C3E069E2806E1B0D890970BE387AEBED8040F37991AACAD70B27895E39",
};
const ecdsa_curve *curve = &secp256k1;
bignum256 k;
uint8_t priv_key[32], buf_raw[32];
memcpy(priv_key, fromhex(test_case.priv_key), 32);
memcpy(&buf_raw, fromhex(test_case.k_hex), 32);
bn_read_be(buf_raw, &k);
schnorr_sign_pair result;
schnorr_sign(curve, priv_key, &k, (const uint8_t *)test_case.message,
strlen(test_case.message), &result);
uint8_t pub_key[33];
ecdsa_get_public_key33(curve, priv_key, pub_key);
// OK
int res = schnorr_verify(curve, pub_key, (const uint8_t *)test_case.message,
strlen(test_case.message), &result);
ck_assert_int_eq(res, 0);
res = schnorr_verify(curve, pub_key, (const uint8_t *)test_case.message, 0,
&result);
ck_assert_int_eq(res, 1);
schnorr_sign_pair bad_result;
bn_copy(&result.s, &bad_result.s);
bn_zero(&bad_result.r);
// r == 0
res = schnorr_verify(curve, pub_key, (const uint8_t *)test_case.message,
strlen(test_case.message), &bad_result);
ck_assert_int_eq(res, 2);
bn_copy(&result.r, &bad_result.r);
bn_zero(&bad_result.s);
// s == 0
res = schnorr_verify(curve, pub_key, (const uint8_t *)test_case.message,
strlen(test_case.message), &bad_result);
ck_assert_int_eq(res, 3);
bn_copy(&result.s, &bad_result.s);
bn_copy(&curve->order, &bad_result.r);
bn_addi(&bad_result.r, 1);
// r == curve->order + 1
res = schnorr_verify(curve, pub_key, (const uint8_t *)test_case.message,
strlen(test_case.message), &bad_result);
ck_assert_int_eq(res, 4);
bn_copy(&result.r, &bad_result.r);
bn_copy(&curve->order, &bad_result.s);
bn_addi(&bad_result.s, 1);
// s == curve->order + 1
res = schnorr_verify(curve, pub_key, (const uint8_t *)test_case.message,
strlen(test_case.message), &bad_result);
ck_assert_int_eq(res, 5);
bn_copy(&result.r, &bad_result.r);
bn_copy(&result.s, &bad_result.s);
// change message
test_case.message = "12";
res = schnorr_verify(curve, pub_key, (const uint8_t *)test_case.message,
strlen(test_case.message), &bad_result);
ck_assert_int_eq(res, 10);
}
END_TEST
static int my_strncasecmp(const char *s1, const char *s2, size_t n) { static int my_strncasecmp(const char *s1, const char *s2, size_t n) {
size_t i = 0; size_t i = 0;
while (i < n) { while (i < n) {
@ -8729,6 +8919,11 @@ Suite *test_suite(void) {
tcase_add_test(tc, test_compress_coords); tcase_add_test(tc, test_compress_coords);
suite_add_tcase(s, tc); suite_add_tcase(s, tc);
tc = tcase_create("schnorr");
tcase_add_test(tc, test_schnorr_sign_verify);
tcase_add_test(tc, test_schnorr_fail_verify);
suite_add_tcase(s, tc);
#if USE_CARDANO #if USE_CARDANO
tc = tcase_create("bip32-cardano"); tc = tcase_create("bip32-cardano");

View File

@ -5,9 +5,7 @@ START_TEST(test_ed25519_cardano_sign_vectors) {
ed25519_secret_key secret_key_extension; ed25519_secret_key secret_key_extension;
ed25519_signature signature; ed25519_signature signature;
static const char static const char *vectors[] = {
*vectors[] =
{
"6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5" "6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5"
"3", // private key "3", // private key
"60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8" "60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8"

View File

@ -30,48 +30,48 @@ class Point:
points = [ points = [
Point( Point(
"secp256k1", "secp256k1",
0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8,
), ),
Point( Point(
"secp256k1", "secp256k1",
0x1, 0x1,
0x4218f20ae6c646b363db68605822fb14264ca8d2587fdd6fbc750d587e76a7ee, 0x4218F20AE6C646B363DB68605822FB14264CA8D2587FDD6FBC750D587E76A7EE,
), ),
Point( Point(
"secp256k1", "secp256k1",
0x2, 0x2,
0x66fbe727b2ba09e09f5a98d70a5efce8424c5fa425bbda1c511f860657b8535e, 0x66FBE727B2BA09E09F5A98D70A5EFCE8424C5FA425BBDA1C511F860657B8535E,
), ),
Point( Point(
"secp256k1", "secp256k1",
0x1b, 0x1B,
0x1adcea1cf831b0ad1653e769d1a229091d0cc68d4b0328691b9caacc76e37c90, 0x1ADCEA1CF831B0AD1653E769D1A229091D0CC68D4B0328691B9CAACC76E37C90,
), ),
Point( Point(
"nist256p1", "nist256p1",
0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296,
0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5, 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5,
), ),
Point( Point(
"nist256p1", "nist256p1",
0x0, 0x0,
0x66485c780e2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4, 0x66485C780E2F83D72433BD5D84A06BB6541C2AF31DAE871728BF856A174F93F4,
), ),
Point( Point(
"nist256p1", "nist256p1",
0x0, 0x0,
0x99b7a386f1d07c29dbcc42a27b5f9449abe3d50de25178e8d7407a95e8b06c0b, 0x99B7A386F1D07C29DBCC42A27B5F9449ABE3D50DE25178E8D7407A95E8B06C0B,
), ),
Point( Point(
"nist256p1", "nist256p1",
0xaf8bbdfe8cdd5577acbf345b543d28cf402f4e94d3865b97ea0787f2d3aa5d22, 0xAF8BBDFE8CDD5577ACBF345B543D28CF402F4E94D3865B97EA0787F2D3AA5D22,
0x35802b8b376b995265918b078bc109c21a535176585c40f519aca52d6afc147c, 0x35802B8B376B995265918B078BC109C21A535176585C40F519ACA52D6AFC147C,
), ),
Point( Point(
"nist256p1", "nist256p1",
0x80000, 0x80000,
0x580610071f440f0dcc14a22e2d5d5afc1224c0cd11a3b4b51b8ecd2224ee1ce2, 0x580610071F440F0DCC14A22E2D5D5AFC1224C0CD11A3B4B51B8ECD2224EE1CE2,
), ),
] ]

View File

@ -102,7 +102,7 @@ def is_valid_der(data):
try: try:
structure, _ = der_decode(data) structure, _ = der_decode(data)
return data == der_encode(structure) return data == der_encode(structure)
except: except Exception:
return False return False
@ -140,7 +140,7 @@ def parse_ec_pubkey(public_key):
try: try:
public_key = bytes(public_key["public_key"].asOctets()) public_key = bytes(public_key["public_key"].asOctets())
except: except Exception:
raise ParseError("Not a BER encoded named elliptic curve public key") raise ParseError("Not a BER encoded named elliptic curve public key")
return curve_name, public_key return curve_name, public_key
@ -152,13 +152,13 @@ def parse_ecdsa256_signature(signature):
raise ParseError("Not a valid DER") raise ParseError("Not a valid DER")
try: try:
signature, _ = der_decode(signature, asn1Spec=EcSignature()) signature, _ = der_decode(signature, asn1Spec=EcSignature())
except: except Exception:
raise ParseError("Not a valid DER encoded ECDSA signature") raise ParseError("Not a valid DER encoded ECDSA signature")
try: try:
r = int(signature["r"]).to_bytes(32, byteorder="big") r = int(signature["r"]).to_bytes(32, byteorder="big")
s = int(signature["s"]).to_bytes(32, byteorder="big") s = int(signature["s"]).to_bytes(32, byteorder="big")
signature = r + s signature = r + s
except: except Exception:
raise ParseError("Not a valid DER encoded 256 bit ECDSA signature") raise ParseError("Not a valid DER encoded 256 bit ECDSA signature")
return signature return signature
@ -281,7 +281,7 @@ def aes_cbc_decrypt(key, iv, ciphertext):
def load_json_testvectors(filename): def load_json_testvectors(filename):
try: try:
result = json.loads(open(os.path.join(testvectors_directory, filename)).read()) result = json.loads(open(os.path.join(testvectors_directory, filename)).read())
except: except Exception:
raise DataError() raise DataError()
return result return result
@ -310,7 +310,7 @@ def generate_aes(filename):
plaintext = unhexlify(test["msg"]) plaintext = unhexlify(test["msg"])
ciphertext = unhexlify(test["ct"]) ciphertext = unhexlify(test["ct"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if len(key) not in [128 / 8, 192 / 8, 256 / 8]: if len(key) not in [128 / 8, 192 / 8, 256 / 8]:
@ -359,7 +359,7 @@ def generate_chacha_poly(filename):
ciphertext = unhexlify(test["ct"]) ciphertext = unhexlify(test["ct"])
tag = unhexlify(test["tag"]) tag = unhexlify(test["tag"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if result is None: if result is None:
@ -406,7 +406,7 @@ def generate_curve25519_dh(filename):
private_key = unhexlify(test["private"]) private_key = unhexlify(test["private"])
shared = unhexlify(test["shared"]) shared = unhexlify(test["shared"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if curve_name != "curve25519": if curve_name != "curve25519":
@ -448,7 +448,7 @@ def generate_ecdh(filename):
private_key = parse_signed_hex(test["private"]) private_key = parse_signed_hex(test["private"])
shared = unhexlify(test["shared"]) shared = unhexlify(test["shared"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
try: try:
@ -498,7 +498,7 @@ def generate_ecdsa(filename):
try: try:
public_key = unhexlify(test_group["keyDer"]) public_key = unhexlify(test_group["keyDer"])
except: except Exception:
raise DataError() raise DataError()
try: try:
@ -521,7 +521,7 @@ def generate_ecdsa(filename):
signature = unhexlify(test["sig"]) signature = unhexlify(test["sig"])
message = unhexlify(test["msg"]) message = unhexlify(test["msg"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if result is None: if result is None:
@ -563,7 +563,7 @@ def generate_eddsa(filename):
try: try:
public_key = unhexlify(test_group["keyDer"]) public_key = unhexlify(test_group["keyDer"])
except: except Exception:
raise DataError() raise DataError()
try: try:
@ -579,7 +579,7 @@ def generate_eddsa(filename):
signature = unhexlify(test["sig"]) signature = unhexlify(test["sig"])
message = unhexlify(test["msg"]) message = unhexlify(test["msg"])
result = parse_result(test["result"]) result = parse_result(test["result"])
except: except Exception:
raise DataError() raise DataError()
if result is None: if result is None:

View File

@ -1,2 +0,0 @@
---
BasedOnStyle: Google

View File

@ -1,63 +0,0 @@
sudo: false
dist: trusty
language: c
addons:
apt:
sources:
- deadsnakes
packages:
- build-essential
- python3.6
- python3.6-dev
- python3.6-venv
env:
global:
- MAKEFLAGS=-j2
- PYTHON=python3.6
- PROTOBUF_VERSION=3.4.0
- TOOLCHAIN_SHORTVER=8-2018q4
- TOOLCHAIN_LONGVER=gcc-arm-none-eabi-8-2018-q4-major
matrix:
- DEBUG_LINK=0
- DEBUG_LINK=1
matrix:
include:
- name: "Emulator GCC"
env: EMULATOR=1 HEADLESS=1 DEBUG_LINK=1
compiler: gcc
script: pipenv run ./script/cibuild && pipenv run script/test
- name: "Emulator Clang"
env: EMULATOR=1 HEADLESS=1 DEBUG_LINK=1
compiler: clang
script: pipenv run ./script/cibuild && pipenv run script/test
before_install:
- $PYTHON -m ensurepip --user
- $PYTHON -m pip install --user pipenv
install:
- wget "https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip"
- unzip "protoc-${PROTOBUF_VERSION}-linux-x86_64.zip" -d protoc
- export PATH="$(pwd)/protoc/bin:$PATH"
- pipenv install
before_script:
- test "$EMULATOR" = "1" || wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/$TOOLCHAIN_SHORTVER/$TOOLCHAIN_LONGVER-linux.tar.bz2
- test "$EMULATOR" = "1" || tar xfj $TOOLCHAIN_LONGVER-linux.tar.bz2
- test "$EMULATOR" = "1" || export PATH=$PWD/$TOOLCHAIN_LONGVER/bin:$PATH
script:
- pipenv run script/cibuild
- pipenv run make -C bootloader
- pipenv run make -C demo
notifications:
webhooks:
urls:
- http://ci-bot.satoshilabs.com:5000/travis
on_success: always
on_failure: always
on_start: always

View File

@ -132,6 +132,14 @@ LDLIBS += -lopencm3_stm32f2
LIBDEPS += $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f2.a LIBDEPS += $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f2.a
endif endif
ifeq ($(BITCOIN_ONLY), 1)
CFLAGS += -DBITCOIN_ONLY=1
CFLAGS += -DU2F_ENABLED=0
else
CFLAGS += -DBITCOIN_ONLY=0
CFLAGS += -DU2F_ENABLED=1
endif
ifeq ($(MEMORY_PROTECT), 0) ifeq ($(MEMORY_PROTECT), 0)
CFLAGS += -DMEMORY_PROTECT=0 CFLAGS += -DMEMORY_PROTECT=0
$(info MEMORY_PROTECT=0) $(info MEMORY_PROTECT=0)

View File

@ -1,14 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
name = "pypi"
verify_ssl = true
[packages]
setuptools = ">=24.2.0"
trezor = {git = "https://github.com/trezor/python-trezor", editable = true, ref = "master"}
pytest = "*"
mock = "*"
typing = "*"
protobuf = "==3.4.0"
mako = "*"
munch = "*"

214
legacy/Pipfile.lock generated
View File

@ -1,214 +0,0 @@
{
"_meta": {
"hash": {
"sha256": "0c77aa21c1e385d7c3833a2f95bc6129394f6d9ce67e1181700a76a5e15074cb"
},
"pipfile-spec": 6,
"requires": {},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"atomicwrites": {
"hashes": [
"sha256:240831ea22da9ab882b551b31d4225591e5e447a68c5e188db5b89ca1d487585",
"sha256:a24da68318b08ac9c9c45029f4a10371ab5b20e4226738e150e6e7c571630ae6"
],
"version": "==1.1.5"
},
"attrs": {
"hashes": [
"sha256:4b90b09eeeb9b88c35bc642cbac057e45a5fd85367b985bd2809c62b7b939265",
"sha256:e0d0eb91441a3b53dab4d9b743eafc1ac44476296a2053b6ca3af0b139faf87b"
],
"version": "==18.1.0"
},
"certifi": {
"hashes": [
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7",
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0"
],
"version": "==2018.4.16"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"click": {
"hashes": [
"sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
"sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b"
],
"version": "==6.7"
},
"ecdsa": {
"hashes": [
"sha256:40d002cf360d0e035cf2cb985e1308d41aaa087cbfc135b2dc2d844296ea546c",
"sha256:64cf1ee26d1cde3c73c6d7d107f835fed7c6a2904aef9eac223d57ad800c43fa"
],
"version": "==0.13"
},
"idna": {
"hashes": [
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
],
"version": "==2.7"
},
"libusb1": {
"hashes": [
"sha256:4707f81e933a97fed1c5bf7d4957f07bae1139cb8084bdee1f50201a40e3fd7c"
],
"version": "==1.6.5"
},
"mako": {
"hashes": [
"sha256:4e02fde57bd4abb5ec400181e4c314f56ac3e49ba4fb8b0d50bba18cb27d25ae"
],
"index": "pypi",
"version": "==1.0.7"
},
"markupsafe": {
"hashes": [
"sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
],
"version": "==1.0"
},
"mnemonic": {
"hashes": [
"sha256:02a7306a792370f4a0c106c2cf1ce5a0c84b9dbd7e71c6792fdb9ad88a727f1d"
],
"version": "==0.18"
},
"mock": {
"hashes": [
"sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1",
"sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba"
],
"index": "pypi",
"version": "==2.0.0"
},
"more-itertools": {
"hashes": [
"sha256:2b6b9893337bfd9166bee6a62c2b0c9fe7735dcf85948b387ec8cba30e85d8e8",
"sha256:6703844a52d3588f951883005efcf555e49566a48afd4db4e965d69b883980d3",
"sha256:a18d870ef2ffca2b8463c0070ad17b5978056f403fb64e3f15fe62a52db21cc0"
],
"version": "==4.2.0"
},
"munch": {
"hashes": [
"sha256:6ae3d26b837feacf732fb8aa5b842130da1daf221f5af9f9d4b2a0a6414b0d51"
],
"index": "pypi",
"version": "==2.3.2"
},
"pbkdf2": {
"hashes": [
"sha256:ac6397369f128212c43064a2b4878038dab78dab41875364554aaf2a684e6979"
],
"version": "==1.3"
},
"pbr": {
"hashes": [
"sha256:1b8be50d938c9bb75d0eaf7eda111eec1bf6dc88a62a6412e33bf077457e0f45",
"sha256:b486975c0cafb6beeb50ca0e17ba047647f229087bd74e37f4a7e2cac17d2caa"
],
"version": "==4.2.0"
},
"pluggy": {
"hashes": [
"sha256:6e3836e39f4d36ae72840833db137f7b7d35105079aee6ec4a62d9f80d594dd1",
"sha256:95eb8364a4708392bae89035f45341871286a333f749c3141c20573d2b3876e1"
],
"markers": "python_version != '3.2.*' and python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.3.*'",
"version": "==0.7.1"
},
"protobuf": {
"hashes": [
"sha256:1fcb9b704bc2e30767352d86b2664d8f65f8ed49654d7a80e7a150739724e80a",
"sha256:41c4555d9754b985352ce5289fa3ba6b21ed715f595111e46e2b90ca53112475",
"sha256:4d4815467f8a61b06d648699842b233017b201f7a16275d680ec5480f10e30e9",
"sha256:5b816951df388f4ab2adbd3f9ae5619b9a5d7033d14b005c345dc3ee88a7faf4",
"sha256:61dbf86993a9312c3a0816b5252079a3943856003bf0380fea3098c929084ad4",
"sha256:9f3be25ad48b051186ee88f9567a3f3f548facd360e0cb62568e2736d9cfda11",
"sha256:ef02609ef445987976a3a26bff77119c518e0915c96661c3a3b17856d0ef6374"
],
"index": "pypi",
"version": "==3.4.0"
},
"py": {
"hashes": [
"sha256:3fd59af7435864e1a243790d322d763925431213b6b8529c6ca71081ace3bbf7",
"sha256:e31fb2767eb657cbde86c454f02e99cb846d3cd9d61b318525140214fdc0e98e"
],
"version": "==1.5.4"
},
"pyblake2": {
"hashes": [
"sha256:3757f7ad709b0e1b2a6b3919fa79fe3261f166fc375cd521f2be480f8319dde9",
"sha256:407e02c7f8f36fcec1b7aa114ddca0c1060c598142ea6f6759d03710b946a7e3",
"sha256:4d47b4a2c1d292b1e460bde1dda4d13aa792ed2ed70fcc263b6bc24632c8e902",
"sha256:5ccc7eb02edb82fafb8adbb90746af71460fbc29aa0f822526fc976dff83e93f",
"sha256:8043267fbc0b2f3748c6920591cd0b8b5609dcce60c504c32858aa36206386f2",
"sha256:982295a87907d50f4723db6bc724660da76b6547826d52160171d54f95b919ac",
"sha256:baa2190bfe549e36163aa44664d4ee3a9080b236fc5d42f50dc6fd36bbdc749e",
"sha256:c53417ee0bbe77db852d5fd1036749f03696ebc2265de359fe17418d800196c4",
"sha256:fbc9fcde75713930bc2a91b149e97be2401f7c9c56d735b46a109210f58d7358"
],
"version": "==1.1.2"
},
"pytest": {
"hashes": [
"sha256:341ec10361b64a24accaec3c7ba5f7d5ee1ca4cebea30f76fad3dd12db9f0541",
"sha256:952c0389db115437f966c4c2079ae9d54714b9455190e56acebe14e8c38a7efa"
],
"index": "pypi",
"version": "==3.6.4"
},
"requests": {
"hashes": [
"sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1",
"sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a"
],
"version": "==2.19.1"
},
"six": {
"hashes": [
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
],
"version": "==1.11.0"
},
"trezor": {
"editable": true,
"git": "https://github.com/trezor/python-trezor",
"ref": "master"
},
"typing": {
"hashes": [
"sha256:3a887b021a77b292e151afb75323dea88a7bc1b3dfa92176cff8e44c8b68bddf",
"sha256:b2c689d54e1144bbcfd191b0832980a21c2dbcf7b5ff7a66248a60c90e951eb8",
"sha256:d400a9344254803a2368533e4533a4200d21eb7b6b729c173bc38201a74db3f2"
],
"index": "pypi",
"version": "==3.6.4"
},
"urllib3": {
"hashes": [
"sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf",
"sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5"
],
"version": "==1.23"
}
},
"develop": {}
}

Some files were not shown because too many files have changed in this diff Show More