diff --git a/.clangd b/.clangd index 0605ccdb7..cd9c5e1db 100644 --- a/.clangd +++ b/.clangd @@ -4,3 +4,6 @@ CompileFlags: - "-I../ext" - "-I../ext/prometheus-cpp-lite-1.0/core/include" - "-I../ext/prometheus-cpp-lite-1.0/simpleapi/include" + - "-I./ext" + - "-I./ext/prometheus-cpp-lite-1.0/core/include" + - "-I./ext/prometheus-cpp-lite-1.0/simpleapi/include" diff --git a/.drone.jsonnet b/.drone.jsonnet deleted file mode 100644 index 7daef37fe..000000000 --- a/.drone.jsonnet +++ /dev/null @@ -1,256 +0,0 @@ -// -// tweakables -// - -local registry = "084037375216.dkr.ecr.us-east-2.amazonaws.com"; -local build_channel = "zerotier-builds"; -local release_channel = "zerotier-releases"; - -local targets = [ - { "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag", "custom" ] }, - { "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, - { "os": "linux", distro: "redhat", "name": "el7", "isas": [ "386", "amd64", "ppc64le"], "events": [ "tag" ] }, - { "os": "linux", distro: "amazon", "name": "amzn2", "isas": [ "amd64", "arm64" ], "events": [ "tag" ] }, - { "os": "linux", distro: "amazon", "name": "amzn2022", "isas": [ "amd64", "arm64" ], "events": [ "tag" ] }, - { "os": "linux", distro: "fedora", "name": "fc38", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, - { "os": "linux", distro: "fedora", "name": "fc37", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, - { "os": "linux", distro: "fedora", "name": "fc36", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, - { "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "tag" ] }, - { "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "tag" ] }, - { "os": "linux", distro: "ubuntu", "name": "bionic", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, - { "os": "linux", distro: "ubuntu", "name": "xenial", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "tag" ] }, - { "os": "linux", distro: "ubuntu", "name": "trusty", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] }, - { "os": "linux", distro: "debian", "name": "bookworm", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "tag"] }, - { "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "debian", "name": "buster", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] }, - { "os": "linux", distro: "debian", "name": "stretch", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "tag" ] }, - { "os": "linux", distro: "debian", "name": "jessie", "isas": [ "386", "armv7", "amd64" ], "events": [ "tag" ] }, - -// { "os": "windows", distro: "windows", "name": "windows", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] }, -// { "os": "darwin", distro: "darwin", "name": "darwin", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] }, - -]; - -local less_targets = [ - { "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, -]; - - -local native_targets = [ - { "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, -]; - -local master_targets = [ - // - // copypasta from here - // - { "os": "linux", distro: "redhat", "name": "el9", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "redhat", "name": "el8", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "redhat", "name": "el7", "isas": [ "386", "amd64", "ppc64le"], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "amazon", "name": "amzn2", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "amazon", "name": "amzn2022", "isas": [ "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "fedora", "name": "fc38", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "fedora", "name": "fc37", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "fedora", "name": "fc36", "isas": [ "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "ubuntu", "name": "jammy", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "ubuntu", "name": "focal", "isas": [ "armv7", "amd64", "arm64", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "ubuntu", "name": "bionic", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "ubuntu", "name": "xenial", "isas": [ "386", "armv7", "amd64", "arm64", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "ubuntu", "name": "trusty", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "debian", "name": "sid", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x", "riscv64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "debian", "name": "bookworm", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "debian", "name": "bullseye", "isas": [ "386", "armv7", "amd64", "arm64", "mips64le", "ppc64le", "s390x" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "debian", "name": "buster", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "debian", "name": "stretch", "isas": [ "386", "armv7", "amd64", "arm64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "linux", distro: "debian", "name": "jessie", "isas": [ "386", "armv7", "amd64" ], "events": [ "push", "tag", "custom" ] }, - { "os": "windows", distro: "windows", "name": "win2k22", "isas": [ "amd64" ], "events": [ "push", "tag", "custom" ] } -]; - -// -// functions -// - -local pipeline_type(os) = if os == "darwin" then "exec" else "docker"; -local builder_image(os) = if os == "linux" then registry + "/honda-builder" else registry + "/windows-builder"; -local tester_image(os) = if os == "linux" then registry + "/honda-builder" else registry + "/windows-tester"; -local build_step_volumes(os) = if os == "linux" then [ { name: "zerotier-builds", path: "/zerotier-builds" } ] else []; -local release_step_volumes(os) = if os == "linux" then [ { name: "zerotier-releases", path: "/zerotier-releases" } ] else []; -local host_volumes(os) = if os == "linux" then [ - { name: "zerotier-builds", host: { path: "/zerotier-builds" } }, - { name: "zerotier-releases", host: { path: "/zerotier-releases" } }, -] else []; - -local index_image(distro) = - if distro == "debian" || distro == "ubuntu" then - registry + "/apt-builder" - else if distro == "redhat" || distro == "fedora" || distro == "amazon" then - registry + "/dnf-builder" - else if distro == "windows" then - registry + "/msi-builder" -; - -local copy_commands(os, distro, name, isa, version) = - if os == "linux" then [ - std.join(" ", [ "./ci/scripts/publish.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ]) - ] - else if os == "windows" then [ - "C:\\scripts\\fix-ec2-metadata.ps1", - "Get-ChildItem windows", - // "aws s3 cp windows\\bytey-SetupFiles\\bytey.msi s3://zerotier-builds/windows/" + version + "/bytey.msi", - ] else if os == "darwin" then [ - "echo hello" - ] -; - -local index_commands(os, channel, distro, name, isas) = - if os == "linux" then - [ "/usr/local/bin/index " + channel + " " + distro + " " + name + " " + std.join(" ", isas) ] - else if os == "windows" then - [ "Get-ChildItem -Recurse windows" ] -; - -local build_commands(os, distro, name, isa, version) = - if os == "linux" then - [ std.join(" ", [ "./ci/scripts/build.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ]) ] - else - if os == "windows" then - [ "windows/build.ps1", "windows/package.ps1" ] - else - if os == "darwin" then - [ "whoami" ] -; - -local test_commands(os, distro, name, isa, version) = - if os == "linux" then - [ std.join(" ", [ "./ci/scripts/test.sh", name, distro, isa, version, "${DRONE_BUILD_EVENT}" ]) ] - else - if os == "windows" then - [ "windows/testpackage.ps1 " + version ] -; - -// -// render -// - -local Build(os, distro, name, isa, events) = { - "kind": "pipeline", - "type": pipeline_type(os), - "name": std.join(" ", [ name, isa, "build" ]), - "pull": "always", - "clone": { "depth": 1, [ if os == "darwin" then "disable" ]: true }, - "steps": [ - { - "name": "build", - "image": builder_image(os), - "commands": build_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"), - "when": { "event": [ "push" ]}, - }, - { - "name": "release", - "image": builder_image(os), - "commands": build_commands(os, distro, name, isa, "${DRONE_TAG}"), - "when": { "event": [ "tag" ]}, - }, - { - "name": "copy build", - "image": builder_image(os), - "commands": copy_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"), - "volumes": build_step_volumes(os), - "when": { "event": [ "push" ]}, - }, - { - "name": "copy relase", - "image": builder_image(os), - "commands": copy_commands(os, distro, name, isa, "${DRONE_TAG}"), - "volumes": release_step_volumes(os), - "when": { "event": [ "tag" ]}, - }, - ], - "volumes": host_volumes(os), - "platform": { "os": os, [ if isa == "arm64" || isa == "armv7" then "arch" ]: "arm64" }, - "trigger": { "event": events } -}; - -local Test(os, distro, name, isa, events) = { - "kind": "pipeline", - "type": pipeline_type(os), - "name": std.join(" ", [ name, isa, "test"]), - "pull": "always", - "clone": { "depth": 1 }, - "steps": [ - { - "name": "test build", - "image": tester_image(os), - "volumes": build_step_volumes(os), - "commands": test_commands(os, distro, name, isa, "100.0.0+${DRONE_COMMIT_SHA:0:8}"), - "when": { "event": [ "push" ]}, - }, - { - "name": "test release", - "image": tester_image(os), - "volumes": release_step_volumes(os), - "commands": test_commands(os, distro, name, isa, "${DRONE_TAG}"), - "when": { "event": [ "tag" ]}, - }, - ], - "volumes": host_volumes(os), - "platform": { "os": os, [ if isa == "arm64" || isa == "armv7" then "arch" ]: "arm64" }, - "depends_on": [ std.join(" ", [ name, "index" ]) ], - "trigger": { "event": events } -}; - -local Index(p) = { - "kind": "pipeline", - "type": pipeline_type(p.os), - "name": std.join(" ", [ p.name, "index" ]), - "pull": "always", - "clone": { "depth": 1 }, - "steps": [ - { - "name": "index build", - "image": index_image(p.distro), - "commands": index_commands(p.os, "zerotier-builds", p.distro, p.name, p.isas), - "volumes": build_step_volumes(p.os), - "environment":{ "GPG_PRIVATE_KEY": { from_secret: "gpg-private-key" }}, - "when": { "event": [ "push" ]}, - }, - { - "name": "index release", - "image": index_image(p.distro), - "commands": index_commands(p.os, "zerotier-releases", p.distro, p.name, p.isas), - "volumes": release_step_volumes(p.os), - "environment":{ "GPG_PRIVATE_KEY": { from_secret: "gpg-private-key" }}, - "when": { "event": [ "tag" ]}, - }, - ], - "volumes": host_volumes(p.os), - "platform": { "os": p.os }, - depends_on: std.flattenArrays([ [ std.join(" ", [ p.name, isa, "build" ]) ] for isa in p.isas ]), - "trigger": { "event": p.events } -}; - -// -// print -// - -std.flattenArrays([ - [ - Build(p.os, p.distro, p.name, isa, p.events) - for isa in p.isas - ] + - [ - Index(p) - ] - for p in native_targets - ]) + - std.flattenArrays([ - [ - Test(p.os, p.distro, p.name, isa, p.events) - for isa in p.isas - ] - for p in native_targets - ]) - \ No newline at end of file diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index b837b1b21..000000000 --- a/.drone.yml +++ /dev/null @@ -1,465 +0,0 @@ ---- -clone: - depth: 1 -kind: pipeline -name: bullseye 386 build -platform: - os: linux -pull: always -steps: -- commands: - - ./ci/scripts/build.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: build - when: - event: - - push -- commands: - - ./ci/scripts/build.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: release - when: - event: - - tag -- commands: - - ./ci/scripts/publish.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: copy build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - ./ci/scripts/publish.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: copy relase - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -clone: - depth: 1 -kind: pipeline -name: bullseye armv7 build -platform: - arch: arm64 - os: linux -pull: always -steps: -- commands: - - ./ci/scripts/build.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: build - when: - event: - - push -- commands: - - ./ci/scripts/build.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: release - when: - event: - - tag -- commands: - - ./ci/scripts/publish.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} - ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: copy build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - ./ci/scripts/publish.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: copy relase - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -clone: - depth: 1 -kind: pipeline -name: bullseye amd64 build -platform: - os: linux -pull: always -steps: -- commands: - - ./ci/scripts/build.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: build - when: - event: - - push -- commands: - - ./ci/scripts/build.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: release - when: - event: - - tag -- commands: - - ./ci/scripts/publish.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} - ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: copy build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - ./ci/scripts/publish.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: copy relase - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -clone: - depth: 1 -kind: pipeline -name: bullseye arm64 build -platform: - arch: arm64 - os: linux -pull: always -steps: -- commands: - - ./ci/scripts/build.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: build - when: - event: - - push -- commands: - - ./ci/scripts/build.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: release - when: - event: - - tag -- commands: - - ./ci/scripts/publish.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} - ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: copy build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - ./ci/scripts/publish.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: copy relase - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -clone: - depth: 1 -depends_on: -- bullseye 386 build -- bullseye armv7 build -- bullseye amd64 build -- bullseye arm64 build -kind: pipeline -name: bullseye index -platform: - os: linux -pull: always -steps: -- commands: - - /usr/local/bin/index zerotier-builds debian bullseye 386 armv7 amd64 arm64 - environment: - GPG_PRIVATE_KEY: - from_secret: gpg-private-key - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/apt-builder - name: index build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - /usr/local/bin/index zerotier-releases debian bullseye 386 armv7 amd64 arm64 - environment: - GPG_PRIVATE_KEY: - from_secret: gpg-private-key - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/apt-builder - name: index release - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -clone: - depth: 1 -depends_on: -- bullseye index -kind: pipeline -name: bullseye 386 test -platform: - os: linux -pull: always -steps: -- commands: - - ./ci/scripts/test.sh bullseye debian 386 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: test build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - ./ci/scripts/test.sh bullseye debian 386 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: test release - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -clone: - depth: 1 -depends_on: -- bullseye index -kind: pipeline -name: bullseye armv7 test -platform: - arch: arm64 - os: linux -pull: always -steps: -- commands: - - ./ci/scripts/test.sh bullseye debian armv7 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: test build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - ./ci/scripts/test.sh bullseye debian armv7 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: test release - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -clone: - depth: 1 -depends_on: -- bullseye index -kind: pipeline -name: bullseye amd64 test -platform: - os: linux -pull: always -steps: -- commands: - - ./ci/scripts/test.sh bullseye debian amd64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: test build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - ./ci/scripts/test.sh bullseye debian amd64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: test release - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -clone: - depth: 1 -depends_on: -- bullseye index -kind: pipeline -name: bullseye arm64 test -platform: - arch: arm64 - os: linux -pull: always -steps: -- commands: - - ./ci/scripts/test.sh bullseye debian arm64 100.0.0+${DRONE_COMMIT_SHA:0:8} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: test build - volumes: - - name: zerotier-builds - path: /zerotier-builds - when: - event: - - push -- commands: - - ./ci/scripts/test.sh bullseye debian arm64 ${DRONE_TAG} ${DRONE_BUILD_EVENT} - image: 084037375216.dkr.ecr.us-east-2.amazonaws.com/honda-builder - name: test release - volumes: - - name: zerotier-releases - path: /zerotier-releases - when: - event: - - tag -trigger: - event: - - push - - tag - - custom -type: docker -volumes: -- host: - path: /zerotier-builds - name: zerotier-builds -- host: - path: /zerotier-releases - name: zerotier-releases ---- -kind: signature -hmac: 887a3ef78d3fe8f0149911e1e4876401dd7dd313b36eb893e791fa42f45d7768 - -... diff --git a/.kick b/.kick deleted file mode 100644 index 28b8ee7f3..000000000 --- a/.kick +++ /dev/null @@ -1,14 +0,0 @@ -kick -kick -kick -kick -kick -kick -kick -kick -kick -kick -kick -kick -kick -kick diff --git a/AUTHORS.md b/AUTHORS.md deleted file mode 100644 index 84bb86316..000000000 --- a/AUTHORS.md +++ /dev/null @@ -1,75 +0,0 @@ -# Authors and Third Party Code Licensing Information - -## Primary Authors - - * ZeroTier Core and ZeroTier One virtual networking service
- Adam Ierymenko / adam.ierymenko@zerotier.com - Joseph Henry / joseph.henry@zerotier.com (QoS and multipath) - - * Java JNI Interface to enable Android application development, and Android app itself (code for that is elsewhere)
- Grant Limberg / glimberg@gmail.com - - * ZeroTier SDK (formerly known as Network Containers)
- Joseph Henry / joseph.henry@zerotier.com - -## Third Party Contributors - - * A number of fixes and improvements to the new controller, other stuff.
- Kees Bos / https://github.com/keesbos/ - - * Debugging and testing, OpenWRT support fixes.
- Moritz Warning / moritzwarning@web.de - - * Debian GNU/Linux packaging, manual pages, and license compliance edits.
- Ben Finney - - * Several others made smaller contributions, which GitHub tracks here:
- https://github.com/zerotier/ZeroTierOne/graphs/contributors/ - -## Third-Party Code - -ZeroTier includes the following third party code, either in ext/ or incorporated into the ZeroTier core. This third party code remains licensed under its original license and is not subject to ZeroTier's BSL license. - - * LZ4 compression algorithm by Yann Collet - - * Files: node/Packet.cpp (bundled within anonymous namespace) - * Home page: http://code.google.com/p/lz4/ - * License grant: BSD 2-clause - - * http-parser by Joyent, Inc. (many authors) - - * Files: ext/http-parser/* - * Home page: https://github.com/joyent/http-parser/ - * License grant: MIT/Expat - - * C++11 json (nlohmann/json) by Niels Lohmann - - * Files: ext/json/* - * Home page: https://github.com/nlohmann/json - * License grant: MIT - - * tap-windows6 by the OpenVPN project - - * Files: windows/TapDriver6/* - * Home page: https://github.com/OpenVPN/tap-windows6/ - * License grant: GNU GPL v2 - * ZeroTier Modifications: change name of driver to ZeroTier, add ioctl() to get L2 multicast memberships (source is in ext/ and modifications inherit GPL) - - * Salsa20 stream cipher, Curve25519 elliptic curve cipher, Ed25519 digital signature algorithm, and Poly1305 MAC algorithm, all by Daniel J. Bernstein - - * Files: node/Salsa20.* node/C25519.* node/Poly1305.* - * Home page: http://cr.yp.to/ - * License grant: public domain - * ZeroTier Modifications: slight cryptographically-irrelevant modifications for inclusion into ZeroTier core - - * MiniUPNPC and libnatpmp by Thomas Bernard - - * Files: ext/libnatpmp/* ext/miniupnpc/* - * Home page: http://miniupnp.free.fr/ - * License grant: BSD attribution no-endorsement - - * cpp-httplib by yhirose - - * Files: ext/cpp-httplib/* - * Home page: https://github.com/yhirose/cpp-httplib - * License grant: MIT diff --git a/COPYING b/COPYING index d07f35240..7f0801e20 100644 --- a/COPYING +++ b/COPYING @@ -1,7 +1,7 @@ ZeroTier One, an endpoint server for the ZeroTier virtual network layer. Copyright © 2011–2019 ZeroTier, Inc. -ZeroTier is released under the terms of the BSL version 1.1. See the +ZeroTier is released under the terms of the BUSL version 1.1. See the file LICENSE.txt for details. .. diff --git a/OFFICIAL-RELEASE-STEPS.md b/OFFICIAL-RELEASE-STEPS.md index f7842e9fc..0c198bd68 100644 --- a/OFFICIAL-RELEASE-STEPS.md +++ b/OFFICIAL-RELEASE-STEPS.md @@ -30,4 +30,4 @@ You will need [Packages](http://s.sudre.free.fr/Software/Packages/about.html) an ## Windows -First load the Visual Studio solution and rebuild the UI and ZeroTier One in both x64 and i386 `Release` mode. Then load [Advanced Installer Enterprise](http://www.advancedinstaller.com/), check that the version is correct, and build. The build will fail if any build artifacts are missing, and Windows must have our product singing key (from DigiCert) available to sign the resulting MSI file. The MSI must then be tested on at least a few different CLEAN Windows VMs to ensure that the installer is valid and properly signed. +First load the Visual Studio solution and rebuild the UI and ZeroTier One in both x64, i386, and arm64 `Release` mode. Then load [Advanced Installer Enterprise](http://www.advancedinstaller.com/), check that the version is correct, and build. The build will fail if any build artifacts are missing, and Windows must have our product singing key (from DigiCert) available to sign the resulting MSI file. The MSI must then be tested on at least a few different CLEAN Windows VMs to ensure that the installer is valid and properly signed. diff --git a/attic/WinUI/APIHandler.cs b/attic/WinUI/APIHandler.cs deleted file mode 100644 index 7192f3f2f..000000000 --- a/attic/WinUI/APIHandler.cs +++ /dev/null @@ -1,459 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Net; -using System.IO; -using System.Windows; -using Newtonsoft.Json; -using System.Diagnostics; -using System.Windows.Threading; - -namespace WinUI -{ - - - public class APIHandler - { - private string authtoken; - - private string url = null; - - private static volatile APIHandler instance; - private static object syncRoot = new Object(); - - public delegate void NetworkListCallback(List networks); - public delegate void StatusCallback(ZeroTierStatus status); - - private string ZeroTierAddress = ""; - - public static APIHandler Instance - { - get - { - if (instance == null) - { - lock (syncRoot) - { - if (instance == null) - { - if (!initHandler()) - { - return null; - } - } - } - } - - return instance; - } - } - - private static bool initHandler(bool resetToken = false) - { - String localZtDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One"; - String globalZtDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\ZeroTier\\One"; - - String authToken = ""; - Int32 port = 9993; - - if (resetToken) - { - instance = null; - if (File.Exists(localZtDir + "\\authtoken.secret")) - { - File.Delete(localZtDir + "\\authtoken.secret"); - } - - if (File.Exists(localZtDir + "\\zerotier-one.port")) - { - File.Delete(localZtDir + "\\zerotier-one.port"); - } - } - - if (!File.Exists(localZtDir + "\\authtoken.secret") || !File.Exists(localZtDir + "\\zerotier-one.port")) - { - // launch external process to copy file into place - String curPath = System.Reflection.Assembly.GetEntryAssembly().Location; - int index = curPath.LastIndexOf("\\"); - curPath = curPath.Substring(0, index); - ProcessStartInfo startInfo = new ProcessStartInfo(curPath + "\\copyutil.exe", "\"" + globalZtDir + "\"" + " " + "\"" + localZtDir + "\""); - startInfo.Verb = "runas"; - - - var process = Process.Start(startInfo); - process.WaitForExit(); - } - - authToken = readAuthToken(localZtDir + "\\authtoken.secret"); - - if ((authToken == null) || (authToken.Length <= 0)) - { - MessageBox.Show("Unable to read ZeroTier One authtoken", "ZeroTier One"); - return false; - } - - port = readPort(localZtDir + "\\zerotier-one.port"); - instance = new APIHandler(port, authToken); - return true; - } - - private static String readAuthToken(String path) - { - String authToken = ""; - - if (File.Exists(path)) - { - try - { - byte[] tmp = File.ReadAllBytes(path); - authToken = System.Text.Encoding.UTF8.GetString(tmp).Trim(); - } - catch - { - MessageBox.Show("Unable to read ZeroTier One Auth Token from:\r\n" + path, "ZeroTier One"); - } - } - - return authToken; - } - - private static Int32 readPort(String path) - { - Int32 port = 9993; - - try - { - byte[] tmp = File.ReadAllBytes(path); - port = Int32.Parse(System.Text.Encoding.ASCII.GetString(tmp).Trim()); - if ((port <= 0) || (port > 65535)) - port = 9993; - } - catch - { - } - - return port; - } - - private APIHandler() - { - url = "http://127.0.0.1:9993"; - } - - public APIHandler(int port, string authtoken) - { - url = "http://127.0.0.1:" + port; - this.authtoken = authtoken; - } - - - - public void GetStatus(StatusCallback cb) - { - var request = WebRequest.Create(url + "/status" + "?auth=" + authtoken) as HttpWebRequest; - if (request != null) - { - request.Method = "GET"; - request.ContentType = "application/json"; - } - - try - { - var httpResponse = (HttpWebResponse)request.GetResponse(); - if (httpResponse.StatusCode == HttpStatusCode.OK) - { - using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - { - var responseText = streamReader.ReadToEnd(); - - ZeroTierStatus status = null; - try - { - status = JsonConvert.DeserializeObject(responseText); - - if (ZeroTierAddress != status.Address) - { - ZeroTierAddress = status.Address; - } - } - catch (JsonReaderException e) - { - Console.WriteLine(e.ToString()); - } - cb(status); - } - } - else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - } - catch (System.Net.Sockets.SocketException) - { - cb(null); - } - catch (System.Net.WebException e) - { - HttpWebResponse res = (HttpWebResponse)e.Response; - if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - else - { - cb(null); - } - } - } - - - - public void GetNetworks(NetworkListCallback cb) - { - var request = WebRequest.Create(url + "/network" + "?auth=" + authtoken) as HttpWebRequest; - if (request == null) - { - cb(null); - } - - request.Method = "GET"; - request.ContentType = "application/json"; - request.Timeout = 10000; - - try - { - var httpResponse = (HttpWebResponse)request.GetResponse(); - - if (httpResponse.StatusCode == HttpStatusCode.OK) - { - using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - { - var responseText = streamReader.ReadToEnd(); - - List networkList = null; - try - { - networkList = JsonConvert.DeserializeObject>(responseText); - foreach (ZeroTierNetwork n in networkList) - { - // all networks received via JSON are connected by definition - n.IsConnected = true; - } - } - catch (JsonReaderException e) - { - Console.WriteLine(e.ToString()); - } - cb(networkList); - } - } - else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - } - catch (System.Net.Sockets.SocketException) - { - cb(null); - } - catch (System.Net.WebException e) - { - HttpWebResponse res = (HttpWebResponse)e.Response; - if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - else - { - cb(null); - } - } - } - - public void JoinNetwork(Dispatcher d, string nwid, bool allowManaged = true, bool allowGlobal = false, bool allowDefault = false, bool allowDNS = false) - { - Task.Factory.StartNew(() => - { - var request = WebRequest.Create(url + "/network/" + nwid + "?auth=" + authtoken) as HttpWebRequest; - if (request == null) - { - return; - } - - request.Method = "POST"; - request.ContentType = "applicaiton/json"; - request.Timeout = 30000; - try - { - using (var streamWriter = new StreamWriter(((HttpWebRequest)request).GetRequestStream())) - { - string json = "{\"allowManaged\":" + (allowManaged ? "true" : "false") + "," + - "\"allowGlobal\":" + (allowGlobal ? "true" : "false") + "," + - "\"allowDefault\":" + (allowDefault ? "true" : "false") + "," + - "\"allowDNS\":" + (allowDNS ? "true" : "false") + "}"; - streamWriter.Write(json); - streamWriter.Flush(); - streamWriter.Close(); - } - } - catch (System.Net.WebException) - { - d.BeginInvoke(DispatcherPriority.Normal, new Action(() => - { - MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); - })); - return; - } - - try - { - var httpResponse = (HttpWebResponse)request.GetResponse(); - - if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - else if (httpResponse.StatusCode != HttpStatusCode.OK) - { - Console.WriteLine("Error sending join network message"); - } - } - catch (System.Net.Sockets.SocketException) - { - d.BeginInvoke(DispatcherPriority.Normal, new Action(() => - { - MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); - })); - } - catch (System.Net.WebException e) - { - HttpWebResponse res = (HttpWebResponse)e.Response; - if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - d.BeginInvoke(DispatcherPriority.Normal, new Action(() => - { - MessageBox.Show("Error Joining Network: Cannot connect to ZeroTier service."); - })); - } - }); - } - - public void LeaveNetwork(Dispatcher d, string nwid) - { - Task.Factory.StartNew(() => - { - var request = WebRequest.Create(url + "/network/" + nwid + "?auth=" + authtoken) as HttpWebRequest; - if (request == null) - { - return; - } - - request.Method = "DELETE"; - request.Timeout = 30000; - - try - { - var httpResponse = (HttpWebResponse)request.GetResponse(); - - if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - else if (httpResponse.StatusCode != HttpStatusCode.OK) - { - Console.WriteLine("Error sending leave network message"); - } - } - catch (System.Net.Sockets.SocketException) - { - d.BeginInvoke(DispatcherPriority.Normal, new Action(() => - { - MessageBox.Show("Error Leaving Network: Cannot connect to ZeroTier service."); - })); - } - catch (System.Net.WebException e) - { - HttpWebResponse res = (HttpWebResponse)e.Response; - if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - d.BeginInvoke(DispatcherPriority.Normal, new Action(() => - { - MessageBox.Show("Error Leaving Network: Cannot connect to ZeroTier service."); - })); - } - catch - { - Console.WriteLine("Error leaving network: Unknown error"); - } - }); - } - - public delegate void PeersCallback(List peers); - - public void GetPeers(PeersCallback cb) - { - var request = WebRequest.Create(url + "/peer" + "?auth=" + authtoken) as HttpWebRequest; - if (request == null) - { - cb(null); - } - - request.Method = "GET"; - request.ContentType = "application/json"; - - try - { - var httpResponse = (HttpWebResponse)request.GetResponse(); - if (httpResponse.StatusCode == HttpStatusCode.OK) - { - using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) - { - var responseText = streamReader.ReadToEnd(); - //Console.WriteLine(responseText); - List peerList = null; - try - { - peerList = JsonConvert.DeserializeObject>(responseText); - } - catch (JsonReaderException e) - { - Console.WriteLine(e.ToString()); - } - cb(peerList); - } - } - else if (httpResponse.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - } - catch (System.Net.Sockets.SocketException) - { - cb(null); - } - catch (System.Net.WebException e) - { - HttpWebResponse res = (HttpWebResponse)e.Response; - if (res != null && res.StatusCode == HttpStatusCode.Unauthorized) - { - APIHandler.initHandler(true); - } - else - { - cb(null); - } - } - } - - public string NodeAddress() - { - return ZeroTierAddress; - } - } -} diff --git a/attic/WinUI/AboutView.xaml b/attic/WinUI/AboutView.xaml deleted file mode 100644 index 295d27bd5..000000000 --- a/attic/WinUI/AboutView.xaml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/attic/WinUI/AboutView.xaml.cs b/attic/WinUI/AboutView.xaml.cs deleted file mode 100644 index 9c48493d0..000000000 --- a/attic/WinUI/AboutView.xaml.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; - -namespace WinUI -{ - /// - /// Interaction logic for AboutView.xaml - /// - public partial class AboutView : Window - { - public AboutView() - { - InitializeComponent(); - } - - private void Hyperlink_MouseLeftButtonDown(object sender, RequestNavigateEventArgs e) - { - var hyperlink = (Hyperlink)sender; - Process.Start(hyperlink.NavigateUri.ToString()); - } - } -} diff --git a/attic/WinUI/App.config b/attic/WinUI/App.config deleted file mode 100644 index 8e1564635..000000000 --- a/attic/WinUI/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/attic/WinUI/App.xaml b/attic/WinUI/App.xaml deleted file mode 100644 index 12ed85f9a..000000000 --- a/attic/WinUI/App.xaml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/attic/WinUI/App.xaml.cs b/attic/WinUI/App.xaml.cs deleted file mode 100644 index 53ef2f678..000000000 --- a/attic/WinUI/App.xaml.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; -using Hardcodet.Wpf.TaskbarNotification; - -namespace WinUI -{ - /// - /// Interaction logic for App.xaml - /// - public partial class App : Application - { - private TaskbarIcon tb; - - private void InitApplication() - { - tb = (TaskbarIcon)FindResource("NotifyIcon"); - tb.Visibility = Visibility.Visible; - } - } -} diff --git a/attic/WinUI/CentralAPI.cs b/attic/WinUI/CentralAPI.cs deleted file mode 100644 index 22bdc697c..000000000 --- a/attic/WinUI/CentralAPI.cs +++ /dev/null @@ -1,256 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace WinUI -{ - class CentralAPI - { - private static volatile CentralAPI instance; - private static object syncRoot = new Object(); - - private CookieContainer cookieContainer; - private HttpClientHandler clientHandler; - private HttpClient client; - - private CentralServer server; - public CentralServer Central - { - get - { - return this.server; - } - set - { - this.server = value; - WriteCentralConfig(); - UpdateRequestHeaders(); - } - } - - public static CentralAPI Instance - { - get - { - if (instance == null) - { - lock (syncRoot) - { - if (instance == null) - { - instance = new CentralAPI(); - } - } - } - - return instance; - } - } - - - - private CentralAPI() - { -#if DEBUG - ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; -#endif - cookieContainer = new CookieContainer(); - clientHandler = new HttpClientHandler - { - AllowAutoRedirect = true, - UseCookies = true, - CookieContainer = cookieContainer - }; - - client = new HttpClient(clientHandler); - - string centralConfigPath = CentralConfigFile(); - if (File.Exists(centralConfigPath)) - { - byte[] tmp = File.ReadAllBytes(centralConfigPath); - string json = Encoding.UTF8.GetString(tmp).Trim(); - CentralServer ctmp = JsonConvert.DeserializeObject(json); - if (ctmp != null) - { - Central = ctmp; - } - else - { - Central = new CentralServer(); - } - } - else - { - Central = new CentralServer(); - } - } - - public bool HasAccessToken() - { - if (Central == null) - return false; - - return !string.IsNullOrEmpty(Central.APIKey); - } - - private string ZeroTierDir() - { - return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\ZeroTier\\One"; - } - - private string CentralConfigFile() - { - return ZeroTierDir() + "\\central.conf"; - } - - public void WriteCentralConfig() - { - string json = JsonConvert.SerializeObject(Central); - byte[] tmp = Encoding.UTF8.GetBytes(json); - if (tmp != null) - { - File.WriteAllBytes(CentralConfigFile(), tmp); - } - } - - private void UpdateRequestHeaders() - { - if (client.DefaultRequestHeaders.Contains("Authorization")) - { - client.DefaultRequestHeaders.Remove("Authorization"); - } - - if (!string.IsNullOrEmpty(Central.APIKey)) - { - client.DefaultRequestHeaders.Add("Authorization", "bearer " + Central.APIKey); - } - } - - public async Task Login(string email, string password, bool isNewUser) - { - string postURL = Central.ServerURL + "/api/_auth/local"; - CentralLogin login = new CentralLogin(email, password, isNewUser); - var content = new StringContent(JsonConvert.SerializeObject(login), Encoding.UTF8, "application/json"); - HttpResponseMessage response = await client.PostAsync(postURL, content); - - if (!response.IsSuccessStatusCode) - { - return false; - } - - string resContent = await response.Content.ReadAsStringAsync(); - - CentralUser user = JsonConvert.DeserializeObject(resContent); - - if (user.Tokens.Count == 0) - { - // create token - user = await CreateAuthToken(user); - } - - Central.APIKey = user.Tokens[0]; - - UpdateRequestHeaders(); - WriteCentralConfig(); - - return true; - } - - public async Task CreateAuthToken(CentralUser user) - { - string randomTokenURL = Central.ServerURL + "/api/randomToken"; - HttpResponseMessage response = await client.GetAsync(randomTokenURL); - - if (!response.IsSuccessStatusCode) - { - // TODO: throw an error - return null; - } - - string resContent = await response.Content.ReadAsStringAsync(); - - CentralToken t = JsonConvert.DeserializeObject(resContent); - - user.Tokens.Add(t.Token); - - string tokenObj = "{ \"tokens\": " + JsonConvert.SerializeObject(user.Tokens) + " } "; - - string postURL = Central.ServerURL + "/api/user/" + user.Id; - var postContent = new StringContent(tokenObj, Encoding.UTF8, "application/json"); - response = await client.PostAsync(postURL, postContent); - - if (!response.IsSuccessStatusCode) - { - // TODO: thrown an error - return null; - } - - resContent = await response.Content.ReadAsStringAsync(); - user = JsonConvert.DeserializeObject(resContent); - - return user; - } - - public async Task> GetNetworkList() - { - string networkURL = Central.ServerURL + "/api/network"; - - HttpResponseMessage response = await client.GetAsync(networkURL); - - if (!response.IsSuccessStatusCode) - { - // TODO: Throw Error - return new List(); - } - - string resContent = await response.Content.ReadAsStringAsync(); - - List networkList = JsonConvert.DeserializeObject>(resContent); - - return networkList; - } - - public async Task CreateNewNetwork() - { - string networkURL = Central.ServerURL + "/api/network?easy=1"; - CentralNetwork network = new CentralNetwork(); - network.Config = new CentralNetwork.CentralNetworkConfig(); - network.Config.Name = NetworkNameGenerator.GenerateName(); - string jsonNetwork = JsonConvert.SerializeObject(network); - var postContent = new StringContent(jsonNetwork, Encoding.UTF8, "application/json"); - HttpResponseMessage response = await client.PostAsync(networkURL, postContent); - - if (!response.IsSuccessStatusCode) - { - return null; - } - - string resContent = await response.Content.ReadAsStringAsync(); - - CentralNetwork newNetwork = JsonConvert.DeserializeObject(resContent); - - return newNetwork; - } - - public async Task AuthorizeNode(string nodeAddress, string networkId) - { - string json = "{ \"config\": { \"authorized\": true } }"; - string postURL = Central.ServerURL + "/api/network/" + networkId + "/member/" + nodeAddress; - var postContent = new StringContent(json, Encoding.UTF8, "application/json"); - HttpResponseMessage response = await client.PostAsync(postURL, postContent); - - if (response.IsSuccessStatusCode) - { - return true; - } - - return false; - } - } -} diff --git a/attic/WinUI/CentralLogin.cs b/attic/WinUI/CentralLogin.cs deleted file mode 100644 index 97265dcf8..000000000 --- a/attic/WinUI/CentralLogin.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace WinUI -{ - class CentralLogin - { - - - public CentralLogin(string email, string password, bool isNew) - { - Login = email; - Password = password; - IsNew = isNew; - } - - [JsonProperty("login")] - public string Login { get; set; } - - [JsonProperty("password")] - public string Password { get; set; } - - [JsonProperty("register")] - public bool IsNew { get; set; } - } -} diff --git a/attic/WinUI/CentralNetwork.cs b/attic/WinUI/CentralNetwork.cs deleted file mode 100644 index 26ad5234a..000000000 --- a/attic/WinUI/CentralNetwork.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace WinUI -{ - class CentralNetwork - { - [JsonProperty("id")] - public string Id { get; set; } - - [JsonProperty("type")] - public string Type { get; set; } - - [JsonProperty("clock")] - public UInt64 Clock { get; set; } - - [JsonProperty("rulesSource")] - public string RulesSource { get; set; } - - [JsonProperty("description")] - public string Description { get; set; } - - [JsonProperty("ownerId")] - public string OwnerID { get; set; } - - [JsonProperty("onlineMemberCount")] - public int OnlineMemberCount { get; set; } - - [JsonProperty("config")] - public CentralNetworkConfig Config { get; set; } - - public class CentralNetworkConfig - { - [JsonProperty("id")] - public string Id { get; set; } - - [JsonProperty("nwid")] - public string NetworkID { get; set; } - - [JsonProperty("name")] - public string Name { get; set; } - } - } -} diff --git a/attic/WinUI/CentralServer.cs b/attic/WinUI/CentralServer.cs deleted file mode 100644 index 8e2686534..000000000 --- a/attic/WinUI/CentralServer.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace WinUI -{ - class CentralServer - { - public CentralServer() - { - ServerURL = "https://my.zerotier.com"; - } - - [JsonProperty("server_url")] - public string ServerURL { get; set; } - - [JsonProperty("api_key")] - public string APIKey { get; set; } - } -} diff --git a/attic/WinUI/CentralToken.cs b/attic/WinUI/CentralToken.cs deleted file mode 100644 index 1db548aae..000000000 --- a/attic/WinUI/CentralToken.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace WinUI -{ - class CentralToken - { - [JsonProperty("token")] - public string Token { get; set; } - - [JsonProperty("clock")] - public UInt64 Clock { get; set; } - - [JsonProperty("raw")] - public string Raw { get; set; } - } -} diff --git a/attic/WinUI/CentralUser.cs b/attic/WinUI/CentralUser.cs deleted file mode 100644 index 8a8945a28..000000000 --- a/attic/WinUI/CentralUser.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Newtonsoft.Json; - -namespace WinUI -{ - class CentralUser - { - public class CentralGlobalPermissions - { - [JsonProperty("a")] - public bool Administrator { get; set; } - - [JsonProperty("d")] - public bool Delete { get; set; } - - [JsonProperty("m")] - public bool Modify { get; set; } - - [JsonProperty("r")] - public bool Read { get; set; } - } - - [JsonProperty("id")] - public string Id { get; set; } - - [JsonProperty("type")] - public string Type { get; set; } - - [JsonProperty("clock")] - public UInt64 Clock { get; set; } - - [JsonProperty("globalPermissions")] - public CentralGlobalPermissions GlobalPermissions { get; set; } - - [JsonProperty("displayName")] - public string DisplayName { get; set; } - - [JsonProperty("email")] - public string Email { get; set; } - - [JsonProperty("smsNumber")] - public string SmsNumber { get; set; } - - [JsonProperty("tokens")] - public List Tokens { get; set; } - } -} diff --git a/attic/WinUI/Fonts/segoeui.ttf b/attic/WinUI/Fonts/segoeui.ttf deleted file mode 100644 index fc18ebd0a..000000000 Binary files a/attic/WinUI/Fonts/segoeui.ttf and /dev/null differ diff --git a/attic/WinUI/Fonts/segoeuib.ttf b/attic/WinUI/Fonts/segoeuib.ttf deleted file mode 100644 index 5f31e0ca6..000000000 Binary files a/attic/WinUI/Fonts/segoeuib.ttf and /dev/null differ diff --git a/attic/WinUI/Fonts/segoeuii.ttf b/attic/WinUI/Fonts/segoeuii.ttf deleted file mode 100644 index 7efb70d60..000000000 Binary files a/attic/WinUI/Fonts/segoeuii.ttf and /dev/null differ diff --git a/attic/WinUI/Fonts/segoeuiz.ttf b/attic/WinUI/Fonts/segoeuiz.ttf deleted file mode 100644 index d7bb186b3..000000000 Binary files a/attic/WinUI/Fonts/segoeuiz.ttf and /dev/null differ diff --git a/attic/WinUI/ISwitchable.cs b/attic/WinUI/ISwitchable.cs deleted file mode 100644 index e485a14cb..000000000 --- a/attic/WinUI/ISwitchable.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace WinUI -{ - interface ISwitchable - { - void UtilizeState(object state); - } -} diff --git a/attic/WinUI/JoinNetworkView.xaml b/attic/WinUI/JoinNetworkView.xaml deleted file mode 100644 index 9898f020a..000000000 --- a/attic/WinUI/JoinNetworkView.xaml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/attic/macui/ZeroTier One/Network.h b/attic/macui/ZeroTier One/Network.h deleted file mode 100644 index c1cfbaf28..000000000 --- a/attic/macui/ZeroTier One/Network.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -enum NetworkStatus { - REQUESTING_CONFIGURATION, - OK, - ACCESS_DENIED, - NOT_FOUND, - PORT_ERROR, - CLIENT_TOO_OLD, -}; - -enum NetworkType { - PUBLIC, - PRIVATE, -}; - -@interface Network : NSObject - -@property (readonly) NSArray *assignedAddresses; -@property (readonly) BOOL bridge; -@property (readonly) BOOL broadcastEnabled; -@property (readonly) BOOL dhcp; -@property (readonly) NSString *mac; -@property (readonly) int mtu; -@property (readonly) int netconfRevision; -@property (readonly) NSString *name; -@property (readonly) UInt64 nwid; -@property (readonly) NSString *portDeviceName; -@property (readonly) int portError; -@property (readonly) enum NetworkStatus status; -@property (readonly) enum NetworkType type; -@property (readonly) BOOL allowManaged; -@property (readonly) BOOL allowGlobal; -@property (readonly) BOOL allowDefault; -@property (readonly) BOOL allowDNS; -@property (readonly) BOOL connected; // not persisted. set to YES if loaded via json - -- (id)initWithJsonData:(NSDictionary*)jsonData; -- (id)initWithCoder:(NSCoder *)aDecoder; -- (void)encodeWithCoder:(NSCoder *)aCoder; -+ (BOOL)defaultRouteExists:(NSArray*)netList; -- (NSString*)statusString; -- (NSString*)typeString; - -- (BOOL)hasSameNetworkId:(UInt64)networkId; - -- (BOOL)isEqualToNetwork:(Network*)network; -- (BOOL)isEqual:(id)object; -- (NSUInteger)hash; - -@end diff --git a/attic/macui/ZeroTier One/Network.m b/attic/macui/ZeroTier One/Network.m deleted file mode 100644 index 2379eb691..000000000 --- a/attic/macui/ZeroTier One/Network.m +++ /dev/null @@ -1,352 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "Network.h" - -NSString *NetworkAddressesKey = @"addresses"; -NSString *NetworkBridgeKey = @"bridge"; -NSString *NetworkBroadcastKey = @"broadcast"; -NSString *NetworkDhcpKey = @"dhcp"; -NSString *NetworkMacKey = @"mac"; -NSString *NetworkMtuKey = @"mtu"; -NSString *NetworkMulticastKey = @"multicast"; -NSString *NetworkNameKey = @"name"; -NSString *NetworkNetconfKey = @"netconf"; -NSString *NetworkNwidKey = @"nwid"; -NSString *NetworkPortNameKey = @"port"; -NSString *NetworkPortErrorKey = @"portError"; -NSString *NetworkStatusKey = @"status"; -NSString *NetworkTypeKey = @"type"; -NSString *NetworkAllowManagedKey = @"allowManaged"; -NSString *NetworkAllowGlobalKey = @"allowGlobal"; -NSString *NetworkAllowDefaultKey = @"allowDefault"; -NSString *NetworkAllowDNSKey = @"allowDNS"; - -@implementation Network - -- (id)initWithJsonData:(NSDictionary*)jsonData -{ - self = [super init]; - - if(self) { - if([jsonData objectForKey:@"assignedAddresses"]) { - _assignedAddresses = (NSArray*)[jsonData objectForKey:@"assignedAddresses"]; - } - - if([jsonData objectForKey:@"bridge"]) { - _bridge = [(NSNumber*)[jsonData objectForKey:@"bridge"] boolValue]; - } - - if([jsonData objectForKey:@"broadcastEnabled"]) { - _broadcastEnabled = [(NSNumber*)[jsonData objectForKey:@"broadcastEnabled"] boolValue]; - } - - if([jsonData objectForKey:@"dhcp"]) { - _dhcp = [(NSNumber*)[jsonData objectForKey:@"dhcp"] boolValue]; - } - - if([jsonData objectForKey:@"mac"]) { - _mac = (NSString*)[jsonData objectForKey:@"mac"]; - } - - if([jsonData objectForKey:@"mtu"]) { - _mtu = [(NSNumber*)[jsonData objectForKey:@"mtu"] intValue]; - } - - if([jsonData objectForKey:@"name"]) { - _name = (NSString*)[jsonData objectForKey:@"name"]; - } - - if([jsonData objectForKey:@"netconfRevision"]) { - _netconfRevision = [(NSNumber*)[jsonData objectForKey:@"netconfRevision"] intValue]; - } - - if([jsonData objectForKey:@"nwid"]) { - NSString *networkid = (NSString*)[jsonData objectForKey:@"nwid"]; - - NSScanner *scanner = [NSScanner scannerWithString:networkid]; - [scanner scanHexLongLong:&_nwid]; - } - - if([jsonData objectForKey:@"portDeviceName"]) { - _portDeviceName = (NSString*)[jsonData objectForKey:@"portDeviceName"]; - } - - if([jsonData objectForKey:@"portError"]) { - _portError = [(NSNumber*)[jsonData objectForKey:@"portError"] intValue]; - } - - if([jsonData objectForKey:@"allowManaged"]) { - _allowManaged = [(NSNumber*)[jsonData objectForKey:@"allowManaged"] boolValue]; - } - - if([jsonData objectForKey:@"allowGlobal"]) { - _allowGlobal = [(NSNumber*)[jsonData objectForKey:@"allowGlobal"] boolValue]; - } - - if([jsonData objectForKey:@"allowDefault"]) { - _allowDefault = [(NSNumber*)[jsonData objectForKey:@"allowDefault"] boolValue]; - } - if([jsonData objectForKey:@"allowDNS"]) { - _allowDNS = [(NSNumber*)[jsonData objectForKey:@"allowDNS"] boolValue]; - } else { - _allowDNS = false; - } - - if([jsonData objectForKey:@"status"]) { - NSString *statusStr = (NSString*)[jsonData objectForKey:@"status"]; - if([statusStr isEqualToString:@"REQUESTING_CONFIGURATION"]) { - _status = REQUESTING_CONFIGURATION; - } - else if([statusStr isEqualToString:@"OK"]) { - _status = OK; - } - else if([statusStr isEqualToString:@"ACCESS_DENIED"]) { - _status = ACCESS_DENIED; - } - else if([statusStr isEqualToString:@"NOT_FOUND"]) { - _status = NOT_FOUND; - } - else if([statusStr isEqualToString:@"PORT_ERROR"]) { - _status = PORT_ERROR; - } - else if([statusStr isEqualToString:@"CLIENT_TOO_OLD"]) { - _status = CLIENT_TOO_OLD; - } - } - - if([jsonData objectForKey:@"type"]) { - NSString *typeStr = (NSString*)[jsonData objectForKey:@"type"]; - if([typeStr isEqualToString:@"PRIVATE"]) { - _type = PRIVATE; - } - else if([typeStr isEqualToString:@"PUBLIC"]) { - _type = PUBLIC; - } - } - - _connected = YES; - } - - return self; -} -- (id)initWithCoder:(NSCoder *)aDecoder -{ - self = [super init]; - - if(self) { - if([aDecoder containsValueForKey:NetworkAddressesKey]) { - _assignedAddresses = (NSArray*)[aDecoder decodeObjectForKey:NetworkAddressesKey]; - } - - if([aDecoder containsValueForKey:NetworkBridgeKey]) { - _bridge = [aDecoder decodeBoolForKey:NetworkBridgeKey]; - } - - if([aDecoder containsValueForKey:NetworkBroadcastKey]) { - _broadcastEnabled = [aDecoder decodeBoolForKey:NetworkBroadcastKey]; - } - - if([aDecoder containsValueForKey:NetworkDhcpKey]) { - _dhcp = [aDecoder decodeBoolForKey:NetworkDhcpKey]; - } - - if([aDecoder containsValueForKey:NetworkMacKey]) { - _mac = (NSString*)[aDecoder decodeObjectForKey:NetworkMacKey]; - } - - if([aDecoder containsValueForKey:NetworkMtuKey]) { - _mtu = (int)[aDecoder decodeIntegerForKey:NetworkMtuKey]; - } - - if([aDecoder containsValueForKey:NetworkNameKey]) { - _name = (NSString*)[aDecoder decodeObjectForKey:NetworkNameKey]; - } - - if([aDecoder containsValueForKey:NetworkNetconfKey]) { - _netconfRevision = (int)[aDecoder decodeIntegerForKey:NetworkNetconfKey]; - } - - if([aDecoder containsValueForKey:NetworkNwidKey]) { - _nwid = [(NSNumber*)[aDecoder decodeObjectForKey:NetworkNwidKey] unsignedLongLongValue]; - } - - if([aDecoder containsValueForKey:NetworkPortNameKey]) { - _portDeviceName = (NSString*)[aDecoder decodeObjectForKey:NetworkPortNameKey]; - } - - if([aDecoder containsValueForKey:NetworkPortErrorKey]) { - _portError = (int)[aDecoder decodeIntegerForKey:NetworkPortErrorKey]; - } - - if([aDecoder containsValueForKey:NetworkStatusKey]) { - _status = (enum NetworkStatus)[aDecoder decodeIntegerForKey:NetworkStatusKey]; - } - - if([aDecoder containsValueForKey:NetworkTypeKey]) { - _type = (enum NetworkType)[aDecoder decodeIntegerForKey:NetworkTypeKey]; - } - - if([aDecoder containsValueForKey:NetworkAllowManagedKey]) { - _allowManaged = [aDecoder decodeBoolForKey:NetworkAllowManagedKey]; - } - - if([aDecoder containsValueForKey:NetworkAllowGlobalKey]) { - _allowGlobal = [aDecoder decodeBoolForKey:NetworkAllowGlobalKey]; - } - - if([aDecoder containsValueForKey:NetworkAllowDefaultKey]) { - _allowDefault = [aDecoder decodeBoolForKey:NetworkAllowDefaultKey]; - } - - if([aDecoder containsValueForKey:NetworkAllowDNSKey]) { - _allowDNS = [aDecoder decodeBoolForKey:NetworkAllowDNSKey]; - } else { - _allowDNS = false; - } - - _connected = NO; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder *)aCoder -{ - [aCoder encodeObject:_assignedAddresses forKey:NetworkAddressesKey]; - [aCoder encodeBool:_bridge forKey:NetworkBridgeKey]; - [aCoder encodeBool:_broadcastEnabled forKey:NetworkBroadcastKey]; - [aCoder encodeBool:_dhcp forKey:NetworkDhcpKey]; - [aCoder encodeObject:_mac forKey:NetworkMacKey]; - [aCoder encodeInteger:_mtu forKey:NetworkMtuKey]; - [aCoder encodeObject:_name forKey:NetworkNameKey]; - [aCoder encodeInteger:_netconfRevision forKey:NetworkNetconfKey]; - [aCoder encodeObject:[NSNumber numberWithUnsignedLongLong:_nwid] - forKey:NetworkNwidKey]; - [aCoder encodeObject:_portDeviceName forKey:NetworkPortNameKey]; - [aCoder encodeInteger:_portError forKey:NetworkPortErrorKey]; - [aCoder encodeInteger:_status forKey:NetworkStatusKey]; - [aCoder encodeInteger:_type forKey:NetworkTypeKey]; - [aCoder encodeBool:_allowManaged forKey:NetworkAllowManagedKey]; - [aCoder encodeBool:_allowGlobal forKey:NetworkAllowGlobalKey]; - [aCoder encodeBool:_allowDefault forKey:NetworkAllowDefaultKey]; - [aCoder encodeBool:_allowDNS forKey:NetworkAllowDNSKey]; -} - -+ (BOOL)defaultRouteExists:(NSArray*)netList -{ - for(Network *net in netList) { - if (net.allowDefault && net.connected) { - return YES; - } - } - return NO; -} - -- (NSString*)statusString { - switch(_status) { - case REQUESTING_CONFIGURATION: - return @"REQUESTING_CONFIGURATION"; - case OK: - return @"OK"; - case ACCESS_DENIED: - return @"ACCESS_DENIED"; - case NOT_FOUND: - return @"NOT_FOUND"; - case PORT_ERROR: - return @"PORT_ERROR"; - case CLIENT_TOO_OLD: - return @"CLIENT_TOO_OLD"; - default: - return @""; - } -} - -- (NSString*)typeString { - switch(_type) { - case PUBLIC: - return @"PUBLIC"; - case PRIVATE: - return @"PRIVATE"; - default: - return @""; - } -} - -- (BOOL)hasSameNetworkId:(UInt64)networkId -{ - return self.nwid == networkId; -} - -- (BOOL)isEqualToNetwork:(Network*)network -{ - return [self.assignedAddresses isEqualToArray:network.assignedAddresses] && - self.bridge == network.bridge && - self.broadcastEnabled == network.broadcastEnabled && - self.dhcp == network.dhcp && - [self.mac isEqualToString:network.mac] && - self.mtu == network.mtu && - self.netconfRevision == network.netconfRevision && - [self.name isEqualToString:network.name] && - self.nwid == network.nwid && - [self.portDeviceName isEqualToString:network.portDeviceName] && - self.status == network.status && - self.type == network.type && - self.allowManaged == network.allowManaged && - self.allowGlobal == network.allowGlobal && - self.allowDefault == network.allowDefault && - self.allowDNS == network.allowDNS && - self.connected == network.connected; -} - -- (BOOL)isEqual:(id)object -{ - if (self == object) { - return YES; - } - - if (![object isKindOfClass:[Network class]]) { - return NO; - } - - return [self isEqualToNetwork:object]; -} - -- (NSUInteger)hash -{ - return [self.assignedAddresses hash] ^ - self.bridge ^ - self.broadcastEnabled ^ - self.dhcp ^ - [self.mac hash] ^ - self.mtu ^ - self.netconfRevision ^ - [self.name hash] ^ - self.nwid ^ - [self.portDeviceName hash] ^ - self.portError ^ - self.status ^ - self.type ^ - self.allowManaged ^ - self.allowGlobal ^ - self.allowDefault ^ - self.allowDNS ^ - self.connected; -} - -@end diff --git a/attic/macui/ZeroTier One/NetworkInfoCell.h b/attic/macui/ZeroTier One/NetworkInfoCell.h deleted file mode 100644 index f764034ee..000000000 --- a/attic/macui/ZeroTier One/NetworkInfoCell.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -@class ShowNetworksViewController; - -@interface NetworkInfoCell : NSTableCellView - -@property (weak, nonatomic) ShowNetworksViewController *parent; - -@property (weak, nonatomic) IBOutlet NSTextField *networkIdField; -@property (weak, nonatomic) IBOutlet NSTextField *networkNameField; -@property (weak, nonatomic) IBOutlet NSTextField *statusField; -@property (weak, nonatomic) IBOutlet NSTextField *typeField; -@property (weak, nonatomic) IBOutlet NSTextField *macField; -@property (weak, nonatomic) IBOutlet NSTextField *mtuField; -@property (weak, nonatomic) IBOutlet NSTextField *broadcastField; -@property (weak, nonatomic) IBOutlet NSTextField *bridgingField; -@property (weak, nonatomic) IBOutlet NSTextField *deviceField; -@property (weak, nonatomic) IBOutlet NSTextField *addressesField; -@property (weak, nonatomic) IBOutlet NSButton *allowManaged; -@property (weak, nonatomic) IBOutlet NSButton *allowGlobal; -@property (weak, nonatomic) IBOutlet NSButton *allowDefault; -@property (weak, nonatomic) IBOutlet NSButton *allowDNS; -@property (weak, nonatomic) IBOutlet NSButton *connectedCheckbox; -@property (weak, nonatomic) IBOutlet NSButton *deleteButton; - -- (IBAction)onConnectCheckStateChanged:(NSButton*)sender; -- (IBAction)deleteNetwork:(NSButton*)sender; -- (IBAction)onAllowStatusChanged:(NSButton*)sender; - -- (void)joinNetwork:(NSString*)nwid; -- (void)leaveNetwork:(NSString*)nwid; - -@end diff --git a/attic/macui/ZeroTier One/NetworkInfoCell.m b/attic/macui/ZeroTier One/NetworkInfoCell.m deleted file mode 100644 index df1bbf67e..000000000 --- a/attic/macui/ZeroTier One/NetworkInfoCell.m +++ /dev/null @@ -1,86 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "NetworkInfoCell.h" -#import "ServiceCom.h" -#import "ShowNetworksViewController.h" -#import "Network.h" - -@implementation NetworkInfoCell - -- (void)drawRect:(NSRect)dirtyRect { - [super drawRect:dirtyRect]; - - // Drawing code here. -} - -- (IBAction)onConnectCheckStateChanged:(NSButton*)sender -{ - if(sender.state == NSOnState) { - [self joinNetwork:self.networkIdField.stringValue]; - } - else { - [self leaveNetwork:self.networkIdField.stringValue]; - } -} - -- (IBAction)deleteNetwork:(NSButton*)sender; -{ - [self leaveNetwork:self.networkIdField.stringValue]; - [self.parent deleteNetworkFromList:self.networkIdField.stringValue]; -} - -- (IBAction)onAllowStatusChanged:(NSButton*)sender -{ - [self joinNetwork:self.networkIdField.stringValue]; -} - -- (void)joinNetwork:(NSString*)nwid -{ - NSError *error = nil; - [[ServiceCom sharedInstance] joinNetwork:nwid - allowManaged:(self.allowManaged.state == NSOnState) - allowGlobal:(self.allowGlobal.state == NSOnState) - allowDefault:![Network defaultRouteExists:_parent.networkList] && (self.allowDefault.state == NSOnState) - allowDNS:(self.allowDNS.state == NSOnState) - error:&error]; - - if (error) { - NSAlert *alert = [NSAlert alertWithError:error]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Ok"]; - - [alert runModal]; - } -} - -- (void)leaveNetwork:(NSString*)nwid -{ - NSError *error = nil; - [[ServiceCom sharedInstance] leaveNetwork:nwid error:&error]; - - if (error) { - NSAlert *alert = [NSAlert alertWithError:error]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Ok"]; - - [alert runModal]; - } -} - -@end diff --git a/attic/macui/ZeroTier One/NetworkMonitor.h b/attic/macui/ZeroTier One/NetworkMonitor.h deleted file mode 100644 index 8cdec4ed6..000000000 --- a/attic/macui/ZeroTier One/NetworkMonitor.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -extern NSString * const NetworkUpdateKey; -extern NSString * const StatusUpdateKey; - -@class Network; - -@interface NetworkMonitor : NSObject -{ - NSMutableArray *_savedNetworks; - NSArray *_receivedNetworks; - NSMutableArray *_allNetworks; - - NSTimer *_timer; -} - -- (id)init; -- (void)dealloc; - -- (void)start; -- (void)stop; - -- (void)updateNetworkInfo; - -- (void)deleteSavedNetwork:(NSString*)networkId; - -@end diff --git a/attic/macui/ZeroTier One/NetworkMonitor.m b/attic/macui/ZeroTier One/NetworkMonitor.m deleted file mode 100644 index 7ed22c4a9..000000000 --- a/attic/macui/ZeroTier One/NetworkMonitor.m +++ /dev/null @@ -1,253 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "NetworkMonitor.h" -#import "Network.h" -#import "ServiceCom.h" -#import "NodeStatus.h" - -@import AppKit; - - -NSString * const NetworkUpdateKey = @"com.zerotier.one.network-list"; -NSString * const StatusUpdateKey = @"com.zerotier.one.status"; - -@interface NetworkMonitor (private) - -- (NSString*)dataFile; -- (void)internal_updateNetworkInfo; -- (NSInteger)findNetworkWithID:(UInt64)networkId; -- (NSInteger)findSavedNetworkWithID:(UInt64)networkId; -- (void)saveNetworks; - -@end - -@implementation NetworkMonitor - -- (id)init -{ - self = [super init]; - if(self) - { - _savedNetworks = [NSMutableArray array]; - _receivedNetworks = [NSArray array]; - _allNetworks = [NSMutableArray array]; - _timer = nil; - } - - return self; -} - -- (void)dealloc -{ - [_timer invalidate]; -} - -- (void)start -{ - NSLog(@"ZeroTier monitor started"); - _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f - target:self - selector:@selector(updateNetworkInfo) - userInfo:nil - repeats:YES]; -} - -- (void)stop -{ - NSLog(@"ZeroTier monitor stopped"); - [_timer invalidate]; - _timer = nil; -} - -- (void)updateNetworkInfo -{ - NSString *filePath = [self dataFile]; - - if([[NSFileManager defaultManager] fileExistsAtPath:filePath]) { - NSArray *networks = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; - - if(networks != nil) { - _savedNetworks = [networks mutableCopy]; - } - } - - NSError *error = nil; - - [[ServiceCom sharedInstance] getNetworklist:^(NSArray *networkList) { - _receivedNetworks = networkList; - - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - [self internal_updateNetworkInfo]; - } ]; - } error:&error]; - - if(error) { - [self stop]; - - NSAlert *alert = [NSAlert alertWithError:error]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Quit"]; - [alert addButtonWithTitle:@"Retry"]; - - NSModalResponse res = [alert runModal]; - - if(res == NSAlertFirstButtonReturn) { - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - } - else if(res == NSAlertSecondButtonReturn) { - [self start]; - return; - } - } - - [[ServiceCom sharedInstance] getNodeStatus:^(NodeStatus *status) { - NSDictionary *userInfo = [NSDictionary dictionaryWithObject:status forKey:@"status"]; - - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - [[NSNotificationCenter defaultCenter] postNotificationName:StatusUpdateKey - object:nil - userInfo:userInfo]; - }]; - } error:&error]; - - if (error) { - [self stop]; - - NSAlert *alert = [NSAlert alertWithError:error]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Quit"]; - [alert addButtonWithTitle:@"Retry"]; - - NSModalResponse res = [alert runModal]; - - if(res == NSAlertFirstButtonReturn) { - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - } - else if(res == NSAlertSecondButtonReturn) { - [self start]; - return; - } - } -} - -- (void)deleteSavedNetwork:(NSString*)networkId -{ - UInt64 nwid = 0; - NSScanner *scanner = [NSScanner scannerWithString:networkId]; - [scanner scanHexLongLong:&nwid]; - - NSInteger index = [self findNetworkWithID:nwid]; - - if(index != NSNotFound) { - [_allNetworks removeObjectAtIndex:index]; - } - - index = [self findSavedNetworkWithID:nwid]; - - if(index != NSNotFound) { - [_savedNetworks removeObjectAtIndex:index]; - } - - [self saveNetworks]; -} - -@end - -@implementation NetworkMonitor (private) -- (NSString*)dataFile -{ - NSURL *appSupport = [[[NSFileManager defaultManager] URLsForDirectory:NSApplicationSupportDirectory - inDomains:NSUserDomainMask] objectAtIndex:0]; - - appSupport = [[[appSupport URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"] URLByAppendingPathComponent:@"networkinfo.dat"]; - return appSupport.path; -} - -- (void)internal_updateNetworkInfo -{ - NSMutableArray *networks = [_savedNetworks mutableCopy]; - - for(Network *nw in _receivedNetworks) { - NSInteger index = [self findSavedNetworkWithID:nw.nwid]; - - if(index != NSNotFound) { - [networks setObject:nw atIndexedSubscript:index]; - } - else { - [networks addObject:nw]; - } - } - - [networks sortUsingComparator:^NSComparisonResult(Network *obj1, Network *obj2) { - if(obj1.nwid > obj2.nwid) { - return true; - } - return false; - }]; - - @synchronized(_allNetworks) { - _allNetworks = networks; - } - - [self saveNetworks]; - - NSDictionary *userInfo = [NSDictionary dictionaryWithObject:networks forKey:@"networks"]; - - [[NSNotificationCenter defaultCenter] postNotificationName:NetworkUpdateKey - object:nil - userInfo:userInfo]; -} - -- (NSInteger)findNetworkWithID:(UInt64)networkId -{ - for(int i = 0; i < [_allNetworks count]; ++i) { - Network *nw = [_allNetworks objectAtIndex:i]; - - if(nw.nwid == networkId) { - return i; - } - } - - return NSNotFound; -} - - -- (NSInteger)findSavedNetworkWithID:(UInt64)networkId -{ - for(int i = 0; i < [_savedNetworks count]; ++i) { - Network *nw = [_savedNetworks objectAtIndex:i]; - - if(nw.nwid == networkId) { - return i; - } - } - - return NSNotFound; -} - -- (void)saveNetworks -{ - NSString *filePath = [self dataFile]; - - @synchronized(_allNetworks) { - [NSKeyedArchiver archiveRootObject:_allNetworks toFile:filePath]; - } -} - -@end diff --git a/attic/macui/ZeroTier One/NodeStatus.h b/attic/macui/ZeroTier One/NodeStatus.h deleted file mode 100644 index eab5bfe44..000000000 --- a/attic/macui/ZeroTier One/NodeStatus.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -@interface NodeStatus : NSObject - -@property (readonly) NSString *address; -@property (readonly) NSString *publicIdentity; -@property (readonly) BOOL online; -@property (readonly) BOOL tcpFallbackActive; -@property (readonly) int versionMajor; -@property (readonly) int versionMinor; -@property (readonly) int versionRev; -@property (readonly) NSString *version; -@property (readonly) UInt64 clock; - -- (id)initWithJsonData:(NSDictionary*)jsonData; - -@end diff --git a/attic/macui/ZeroTier One/NodeStatus.m b/attic/macui/ZeroTier One/NodeStatus.m deleted file mode 100644 index 3bae3c7da..000000000 --- a/attic/macui/ZeroTier One/NodeStatus.m +++ /dev/null @@ -1,40 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#import "NodeStatus.h" - -@implementation NodeStatus - -- (id)initWithJsonData:(NSDictionary*)jsonData -{ - self = [super init]; - - if(self) { - _address = (NSString*)[jsonData objectForKey:@"address"]; - _publicIdentity = (NSString*)[jsonData objectForKey:@"publicIdentity"]; - _online = [(NSNumber*)[jsonData objectForKey:@"online"] boolValue]; - _tcpFallbackActive = [(NSNumber*)[jsonData objectForKey:@"tcpFallbackActive"] boolValue]; - _versionMajor = [(NSNumber*)[jsonData objectForKey:@"versionMajor"] intValue]; - _versionMinor = [(NSNumber*)[jsonData objectForKey:@"versionMinor"] intValue]; - _versionRev = [(NSNumber*)[jsonData objectForKey:@"versionRev"] intValue]; - _version = (NSString*)[jsonData objectForKey:@"version"]; - _clock = [(NSNumber*)[jsonData objectForKey:@"clock"] unsignedLongLongValue]; - } - - return self; -} -@end diff --git a/attic/macui/ZeroTier One/PreferencesViewController.h b/attic/macui/ZeroTier One/PreferencesViewController.h deleted file mode 100644 index 56d0fdb82..000000000 --- a/attic/macui/ZeroTier One/PreferencesViewController.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -@interface PreferencesViewController : NSViewController - -@property (nonatomic, weak) IBOutlet NSButton *startupCheckBox; - -- (IBAction)onStartupCheckBoxChanged:(NSButton*)sender; - -- (BOOL)isLaunchAtStartup; -- (LSSharedFileListItemRef)itemRefInLoginItems; -- (void)setLaunchAtLoginEnabled:(BOOL)enabled; - -@end diff --git a/attic/macui/ZeroTier One/PreferencesViewController.m b/attic/macui/ZeroTier One/PreferencesViewController.m deleted file mode 100644 index 13927fbaf..000000000 --- a/attic/macui/ZeroTier One/PreferencesViewController.m +++ /dev/null @@ -1,112 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "PreferencesViewController.h" - -@interface PreferencesViewController () - -@end - -@implementation PreferencesViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - if([self isLaunchAtStartup]) { - self.startupCheckBox.state = NSOnState; - } - else { - self.startupCheckBox.state = NSOffState; - } -} - -- (IBAction)onStartupCheckBoxChanged:(NSButton *)sender -{ - if(sender.state == NSOnState) { - [self setLaunchAtLoginEnabled:YES]; - } - else { - [self setLaunchAtLoginEnabled:NO]; - } - -} - -- (void)setLaunchAtLoginEnabled:(BOOL)enabled -{ - LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); - - if (enabled) { - // Add the app to the LoginItems list. - CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; - LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL); - if (itemRef) CFRelease(itemRef); - } - else { - // Remove the app from the LoginItems list. - LSSharedFileListItemRef itemRef = [self itemRefInLoginItems]; - LSSharedFileListItemRemove(loginItemsRef,itemRef); - if (itemRef != nil) CFRelease(itemRef); - } -} - - -- (BOOL)isLaunchAtStartup { - // See if the app is currently in LoginItems. - LSSharedFileListItemRef itemRef = [self itemRefInLoginItems]; - // Store away that boolean. - BOOL isInList = itemRef != nil; - // Release the reference if it exists. - if (itemRef != nil) CFRelease(itemRef); - - return isInList; -} - -- (LSSharedFileListItemRef)itemRefInLoginItems { - LSSharedFileListItemRef itemRef = nil; - - NSString * appPath = [[NSBundle mainBundle] bundlePath]; - - // This will retrieve the path for the application - // For example, /Applications/test.app - CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:appPath]; - - // Create a reference to the shared file list. - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL); - - if (loginItems) { - UInt32 seedValue; - //Retrieve the list of Login Items and cast them to - // a NSArray so that it will be easier to iterate. - NSArray *loginItemsArray = (__bridge NSArray *)LSSharedFileListCopySnapshot(loginItems, &seedValue); - for(int i = 0; i< [loginItemsArray count]; i++){ - LSSharedFileListItemRef currentItemRef = (__bridge LSSharedFileListItemRef)[loginItemsArray - objectAtIndex:i]; - //Resolve the item with URL - if (LSSharedFileListItemResolve(currentItemRef, 0, (CFURLRef*) &url, NULL) == noErr) { - NSString * urlPath = [(__bridge NSURL*)url path]; - if ([urlPath compare:appPath] == NSOrderedSame){ - itemRef = currentItemRef; - } - } - } - } - CFRelease(loginItems); - return itemRef; -} - -@end diff --git a/attic/macui/ZeroTier One/PreferencesViewController.xib b/attic/macui/ZeroTier One/PreferencesViewController.xib deleted file mode 100644 index 62aef4c03..000000000 --- a/attic/macui/ZeroTier One/PreferencesViewController.xib +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/attic/macui/ZeroTier One/ServiceCom.h b/attic/macui/ZeroTier One/ServiceCom.h deleted file mode 100644 index 17b738e4d..000000000 --- a/attic/macui/ZeroTier One/ServiceCom.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -@class NodeStatus; -@class Network; - -@interface ServiceCom : NSObject -{ - NSString *baseURL; - NSURLSession *session; - BOOL _isQuitting; - BOOL _resetKey; -} -+ (ServiceCom*)sharedInstance; - -- (id)init; - -- (void)getNetworklist:(void (^)(NSArray*))completionHandler error:(NSError* __autoreleasing *)error; -- (void)getNodeStatus:(void (^)(NodeStatus*))completionHandler error:(NSError*__autoreleasing*)error; -- (void)joinNetwork:(NSString*)networkId allowManaged:(BOOL)allowManaged allowGlobal:(BOOL)allowGlobal allowDefault:(BOOL)allowDefault allowDNS:(BOOL)allowDNS error:(NSError*__autoreleasing*)error; -- (void)leaveNetwork:(NSString*)networkId error:(NSError*__autoreleasing*)error; - -@end diff --git a/attic/macui/ZeroTier One/ServiceCom.m b/attic/macui/ZeroTier One/ServiceCom.m deleted file mode 100644 index 55d67741a..000000000 --- a/attic/macui/ZeroTier One/ServiceCom.m +++ /dev/null @@ -1,522 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "ServiceCom.h" -#import "AuthtokenCopy.h" -#import "Network.h" -#import "NodeStatus.h" -@import AppKit; - -@interface ServiceCom (Private) - -- (NSString*)key; - -@end - -@implementation ServiceCom - -+ (ServiceCom*)sharedInstance { - static ServiceCom *sc = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sc = [[ServiceCom alloc] init]; - }); - return sc; -} - -- (id)init -{ - self = [super init]; - if(self) { - baseURL = @"http://127.0.0.1:9993"; - session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]]; - _isQuitting = NO; - _resetKey = NO; - } - - return self; -} - -- (NSString*)key:(NSError* __autoreleasing *)err -{ - static NSString *k = nil; - static NSUInteger resetCount = 0; - - @synchronized (self) { - if (_isQuitting) { - return @""; - } - - if (_resetKey && k != nil) { - k = nil; - ++resetCount; - NSLog(@"ResetCount: %lu", (unsigned long)resetCount); - if (resetCount > 10) { - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - NSAlert *alert = [NSAlert alertWithMessageText:@"Error obtaining Auth Token" - defaultButton:@"Quit" - alternateButton:@"Retry" - otherButton:nil - informativeTextWithFormat:@"Please ensure ZeroTier is installed correctly"]; - alert.alertStyle = NSCriticalAlertStyle; - - NSModalResponse res; - if (!_isQuitting) { - res = [alert runModal]; - } - else { - return; - } - - if(res == 1) { - _isQuitting = YES; - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - } - }]; - return @""; - } - } - - if (k == nil) { - NSError *error = nil; - NSURL *appSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:false error:&error]; - - if (error) { - NSLog(@"Error: %@", error); - return @""; - } - - appSupportDir = [[appSupportDir URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"]; - NSURL *authtokenURL = [appSupportDir URLByAppendingPathComponent:@"authtoken.secret"]; - - if (!_resetKey && [[NSFileManager defaultManager] fileExistsAtPath:[authtokenURL path]]) { - k = [NSString stringWithContentsOfURL:authtokenURL - encoding:NSUTF8StringEncoding - error:&error]; - - k = [k stringByReplacingOccurrencesOfString:@"\n" withString:@""]; - - if (error) { - NSLog(@"Error: %@", error); - k = nil; - *err = error; - return @""; - } - } - else { - _resetKey = NO; - NSURL *sysAppSupportDir = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory inDomain:NSSystemDomainMask appropriateForURL:nil create:false error:nil]; - - sysAppSupportDir = [[sysAppSupportDir URLByAppendingPathComponent:@"ZeroTier"] URLByAppendingPathComponent:@"One"]; - NSURL *sysAuthtokenURL = [sysAppSupportDir URLByAppendingPathComponent:@"authtoken.secret"]; - - if(![[NSFileManager defaultManager] fileExistsAtPath:[sysAuthtokenURL path]]) { - - } - - [[NSFileManager defaultManager] createDirectoryAtURL:appSupportDir - withIntermediateDirectories:YES - attributes:nil - error:&error]; - - if (error) { - NSLog(@"Error: %@", error); - *err = error; - k = nil; - return @""; - } - - AuthorizationRef authRef; - OSStatus status = AuthorizationCreate(nil, nil, kAuthorizationFlagDefaults, &authRef); - - if (status != errAuthorizationSuccess) { - NSLog(@"Authorization Failed! %d", status); - - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't create AuthorizationRef", nil), - }; - *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo]; - - return @""; - } - - AuthorizationItem authItem; - authItem.name = kAuthorizationRightExecute; - authItem.valueLength = 0; - authItem.flags = 0; - - AuthorizationRights authRights; - authRights.count = 1; - authRights.items = &authItem; - - AuthorizationFlags authFlags = kAuthorizationFlagDefaults | - kAuthorizationFlagInteractionAllowed | - kAuthorizationFlagPreAuthorize | - kAuthorizationFlagExtendRights; - - status = AuthorizationCopyRights(authRef, &authRights, nil, authFlags, nil); - - if (status != errAuthorizationSuccess) { - NSLog(@"Authorization Failed! %d", status); - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: NSLocalizedString(@"Couldn't copy authorization rights", nil), - }; - *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo]; - return @""; - } - - NSString *localKey = getAdminAuthToken(authRef); - AuthorizationFree(authRef, kAuthorizationFlagDestroyRights); - - if (localKey != nil && [localKey lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > 0) { - k = localKey; - - [localKey writeToURL:authtokenURL - atomically:YES - encoding:NSUTF8StringEncoding - error:&error]; - - if (error) { - NSLog(@"Error writing token to disk: %@", error); - *err = error; - } - } - } - } - - if (k == nil) { - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: NSLocalizedString(@"Unknown error finding authorization key", nil), - }; - *err = [NSError errorWithDomain:@"com.zerotier.one" code:-1 userInfo:userInfo]; - - return @""; - } - } - return k; -} - -- (void)getNetworklist:(void (^)(NSArray *))completionHandler error:(NSError *__autoreleasing*)error -{ - NSString* key = [self key:error]; - if(*error) { - return; - } - - NSString *urlString = [[baseURL stringByAppendingString:@"/network?auth="] stringByAppendingString:key]; - - NSURL *url = [NSURL URLWithString:urlString]; - NSURLSessionDataTask *task = - [session dataTaskWithURL:url - completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable err) { - - if (err) { - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - NSAlert *alert = [NSAlert alertWithError:err]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Quit"]; - [alert addButtonWithTitle:@"Retry"]; - - NSModalResponse res; - if (!_isQuitting) { - res = [alert runModal]; - } - else { - return; - } - - if(res == NSAlertFirstButtonReturn) { - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - _isQuitting = YES; - } - }]; - return; - } - - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; - NSInteger status = [httpResponse statusCode]; - - NSError *err2; - - if (status == 200) { - NSArray *json = [NSJSONSerialization JSONObjectWithData:data - options:0 - error:&err2]; - if (err) { - NSLog(@"Error fetching network list: %@", err2); - - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - NSAlert *alert = [NSAlert alertWithError:err2]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Quit"]; - [alert addButtonWithTitle:@"Retry"]; - - NSModalResponse res; - if (!_isQuitting) { - res = [alert runModal]; - } - else { - return; - } - - if(res == NSAlertFirstButtonReturn) { - _isQuitting = YES; - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - } - }]; - return; - } - - NSMutableArray *networks = [[NSMutableArray alloc] init]; - for(NSDictionary *dict in json) { - [networks addObject:[[Network alloc] initWithJsonData:dict]]; - } - - completionHandler(networks); - } - else if (status == 401) { - self->_resetKey = YES; - } - }]; - [task resume]; -} - -- (void)getNodeStatus:(void (^)(NodeStatus*))completionHandler error:(NSError*__autoreleasing*)error -{ - NSString *key = [self key:error]; - if(*error) { - return; - } - - NSString *urlString = [[baseURL stringByAppendingString:@"/status?auth="] stringByAppendingString:key]; - - NSURL *url = [NSURL URLWithString:urlString]; - NSURLSessionDataTask *task = - [session dataTaskWithURL:url - completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable err) { - - if(err) { - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - NSAlert *alert = [NSAlert alertWithError:err]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Quit"]; - [alert addButtonWithTitle:@"Retry"]; - - NSModalResponse res; - if (!_isQuitting) { - res = [alert runModal]; - } - else { - return; - } - - if(res == NSAlertFirstButtonReturn) { - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - _isQuitting = YES; - } - }]; - return; - } - - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; - NSInteger status = [httpResponse statusCode]; - - NSError *err2; - if(status == 200) { - NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data - options:0 - error:&err2]; - - if(err2) { - NSLog(@"Error fetching node status: %@", err2); - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - NSAlert *alert = [NSAlert alertWithError:err2]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Quit"]; - [alert addButtonWithTitle:@"Retry"]; - - NSModalResponse res; - if (!_isQuitting) { - res = [alert runModal]; - } - else { - return; - } - - if(res == NSAlertFirstButtonReturn) { - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - _isQuitting = YES; - } - }]; - return; - } - - NodeStatus *status = [[NodeStatus alloc] initWithJsonData:json]; - - completionHandler(status); - } - else if (status == 401) { - self->_resetKey = YES; - } - }]; - [task resume]; -} - -- (void)joinNetwork:(NSString*)networkId - allowManaged:(BOOL)allowManaged - allowGlobal:(BOOL)allowGlobal - allowDefault:(BOOL)allowDefault - allowDNS:(BOOL)allowDNS - error:(NSError *__autoreleasing*)error -{ - NSString *key = [self key:error]; - if(*error) { - return; - } - - NSString *urlString = [[[[baseURL stringByAppendingString:@"/network/"] - stringByAppendingString:networkId] - stringByAppendingString:@"?auth="] - stringByAppendingString:key]; - - NSURL *url = [NSURL URLWithString:urlString]; - - NSMutableDictionary *jsonDict = [NSMutableDictionary dictionary]; - [jsonDict setObject:[NSNumber numberWithBool:allowManaged] forKey:@"allowManaged"]; - [jsonDict setObject:[NSNumber numberWithBool:allowGlobal] forKey:@"allowGlobal"]; - [jsonDict setObject:[NSNumber numberWithBool:allowDefault] forKey:@"allowDefault"]; - [jsonDict setObject:[NSNumber numberWithBool:allowDNS] forKey:@"allowDNS"]; - - NSError *err = nil; - - NSData *json = [NSJSONSerialization dataWithJSONObject:jsonDict - options:0 - error:&err]; - - if(err) { - NSLog(@"Error creating json data: %@", err); - *error = err; - return; - } - - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; - request.HTTPMethod = @"POST"; - request.HTTPBody = json; - [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; - - NSURLSessionDataTask *task = - [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable err) { - if(err) { - NSLog(@"Error posting join request: %@", err); - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - NSAlert *alert = [NSAlert alertWithError:err]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Quit"]; - [alert addButtonWithTitle:@"Retry"]; - - NSModalResponse res; - if (!_isQuitting) { - res = [alert runModal]; - } - else { - return; - } - - if(res == NSAlertFirstButtonReturn) { - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - _isQuitting = YES; - } - }]; - } - - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; - NSInteger status = [httpResponse statusCode]; - - if(status == 200) { - NSLog(@"join ok"); - } - else if (status == 401) { - self->_resetKey = YES; - } - else { - NSLog(@"join error: %ld", (long)status); - } - }]; - [task resume]; -} - -- (void)leaveNetwork:(NSString*)networkId error:(NSError*__autoreleasing*)error -{ - NSString *key = [self key:error]; - if(*error) { - return; - } - - NSString *urlString = [[[[baseURL stringByAppendingString:@"/network/"] - stringByAppendingString:networkId] - stringByAppendingString:@"?auth="] - stringByAppendingString:key]; - - NSURL *url = [NSURL URLWithString:urlString]; - - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; - request.HTTPMethod = @"DELETE"; - - NSURLSessionDataTask *task = - [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable err) { - if(err) { - NSLog(@"Error posting delete request: %@", err); - [[NSOperationQueue mainQueue] addOperationWithBlock:^{ - NSAlert *alert = [NSAlert alertWithError:err]; - alert.alertStyle = NSCriticalAlertStyle; - [alert addButtonWithTitle:@"Quit"]; - [alert addButtonWithTitle:@"Retry"]; - - NSModalResponse res; - if (!_isQuitting) { - res = [alert runModal]; - } - else { - return; - } - - if(res == NSAlertFirstButtonReturn) { - [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; - _isQuitting = YES; - } - }]; - return; - } - - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; - NSInteger status = httpResponse.statusCode; - - if(status == 200) { - NSLog(@"leave ok"); - } - else if (status == 401) { - self->_resetKey = YES; - } - else { - NSLog(@"leave error: %ld", status); - } - }]; - [task resume]; -} - -@end diff --git a/attic/macui/ZeroTier One/ShowNetworksViewController.h b/attic/macui/ZeroTier One/ShowNetworksViewController.h deleted file mode 100644 index 6138958d3..000000000 --- a/attic/macui/ZeroTier One/ShowNetworksViewController.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -@class NetworkMonitor; -@class Network; - -@interface ShowNetworksViewController : NSViewController - -@property (nonatomic) NSMutableArray *networkList; -@property (nonatomic) NetworkMonitor *netMonitor; -@property (nonatomic) BOOL visible; - -@property (weak, nonatomic) IBOutlet NSTableView *tableView; - -- (void)deleteNetworkFromList:(NSString*)nwid; -- (void)setNetworks:(NSArray*)list; - - -@end diff --git a/attic/macui/ZeroTier One/ShowNetworksViewController.m b/attic/macui/ZeroTier One/ShowNetworksViewController.m deleted file mode 100644 index acd29479a..000000000 --- a/attic/macui/ZeroTier One/ShowNetworksViewController.m +++ /dev/null @@ -1,184 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import "ShowNetworksViewController.h" -#import "NetworkMonitor.h" -#import "NetworkInfoCell.h" -#import "Network.h" - -BOOL hasNetworkWithID(NSArray *list, UInt64 nwid) -{ - for(Network *n in list) { - if(n.nwid == nwid) { - return YES; - } - } - - return NO; -} - -@interface ShowNetworksViewController () - -@end - -@implementation ShowNetworksViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.networkList = [NSMutableArray array]; - - [self.tableView setDelegate:self]; - [self.tableView setDataSource:self]; - [self.tableView setBackgroundColor:[NSColor clearColor]]; -} - -- (void)viewWillAppear { - [super viewWillAppear]; - self.visible = YES; -} - -- (void)viewWillDisappear { - [super viewWillDisappear]; - self.visible = NO; -} - -- (NSInteger)findNetworkWithID:(UInt64)networkId -{ - for(int i = 0; i < [_networkList count]; ++i) { - Network *nw = [_networkList objectAtIndex:i]; - - if(nw.nwid == networkId) { - return i; - } - } - - return NSNotFound; -} - - -- (void)deleteNetworkFromList:(NSString *)nwid { - [self.netMonitor deleteSavedNetwork:nwid]; - - UInt64 netid = 0; - NSScanner *scanner = [NSScanner scannerWithString:nwid]; - [scanner scanHexLongLong:&netid]; - for (Network *n in _networkList) { - if (n.nwid == netid) { - NSInteger index = [self findNetworkWithID:netid]; - - if (index != NSNotFound) { - [_networkList removeObjectAtIndex:index]; - [_tableView reloadData]; - } - } - } -} - -- (void)setNetworks:(NSArray *)list { - for (Network *n in list) { - if ([_networkList containsObject:n]) { - // don't need to do anything here. Already an identical object in the list - continue; - } - else { - // network not in the list based on equality. Did an object change? or is it a new item? - if (hasNetworkWithID(_networkList, n.nwid)) { - - for (int i = 0; i < [_networkList count]; ++i) { - Network *n2 = [_networkList objectAtIndex:i]; - if (n.nwid == n2.nwid) - { - [_networkList replaceObjectAtIndex:i withObject:n]; - [_tableView reloadDataForRowIndexes:[NSIndexSet indexSetWithIndex:i] - columnIndexes:[NSIndexSet indexSetWithIndex:0]]; - } - } - } - else { - [_networkList addObject:n]; - [_tableView reloadData]; - } - } - } -} - -- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { - return [_networkList count]; -} - -- (NSView*)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row -{ - NetworkInfoCell *cell = (NetworkInfoCell*)[tableView makeViewWithIdentifier:@"NetworkInfoCell" - owner:nil]; - Network *network = [_networkList objectAtIndex:row]; - cell.parent = self; - cell.networkIdField.stringValue = [NSString stringWithFormat:@"%10llx", network.nwid]; - cell.networkNameField.stringValue = network.name; - cell.statusField.stringValue = [network statusString]; - cell.typeField.stringValue = [network typeString]; - cell.mtuField.stringValue = [NSString stringWithFormat:@"%d", network.mtu]; - cell.macField.stringValue = network.mac; - cell.broadcastField.stringValue = network.broadcastEnabled ? @"ENABLED" : @"DISABLED"; - cell.bridgingField.stringValue = network.bridge ? @"ENABLED" : @"DISABLED"; - cell.deviceField.stringValue = network.portDeviceName; - - if(network.connected) { - cell.connectedCheckbox.state = NSOnState; - - if(network.allowDefault) { - cell.allowDefault.enabled = YES; - cell.allowDefault.state = NSOnState; - } - else { - cell.allowDefault.state = NSOffState; - - if([Network defaultRouteExists:_networkList]) { - cell.allowDefault.enabled = NO; - } - else { - cell.allowDefault.enabled = YES; - } - } - - cell.allowGlobal.enabled = YES; - cell.allowManaged.enabled = YES; - cell.allowDNS.enabled = YES; - } - else { - cell.connectedCheckbox.state = NSOffState; - cell.allowDefault.enabled = NO; - cell.allowGlobal.enabled = NO; - cell.allowManaged.enabled = NO; - cell.allowDNS.enabled = NO; - } - - cell.allowGlobal.state = network.allowGlobal ? NSOnState : NSOffState; - cell.allowManaged.state = network.allowManaged ? NSOnState : NSOffState; - cell.allowDNS.state = network.allowDNS ? NSOnState : NSOffState; - - cell.addressesField.stringValue = @""; - - for(NSString *addr in network.assignedAddresses) { - cell.addressesField.stringValue = [[cell.addressesField.stringValue stringByAppendingString:addr] stringByAppendingString:@"\n"]; - } - - return cell; -} - -@end diff --git a/attic/macui/ZeroTier One/ShowNetworksViewController.xib b/attic/macui/ZeroTier One/ShowNetworksViewController.xib deleted file mode 100644 index 485adb0c0..000000000 --- a/attic/macui/ZeroTier One/ShowNetworksViewController.xib +++ /dev/null @@ -1,394 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/attic/macui/ZeroTier One/ZeroTier One.entitlements b/attic/macui/ZeroTier One/ZeroTier One.entitlements deleted file mode 100644 index 0c67376eb..000000000 --- a/attic/macui/ZeroTier One/ZeroTier One.entitlements +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/attic/macui/ZeroTier One/ZeroTierIcon.icns b/attic/macui/ZeroTier One/ZeroTierIcon.icns deleted file mode 100644 index 17e60d587..000000000 Binary files a/attic/macui/ZeroTier One/ZeroTierIcon.icns and /dev/null differ diff --git a/attic/macui/ZeroTier One/about.html b/attic/macui/ZeroTier One/about.html deleted file mode 100644 index 09f6eb36a..000000000 --- a/attic/macui/ZeroTier One/about.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -
-
-

Welcome to ZeroTier

-

Getting Started

-

Networks are identified by 16-digit network IDs. If someone invited you to join theirs you probably received one. If not you can create your own at my.zerotier.com or by running running your own network controller. -

Your computer is identified by a 10-digit ZeroTier address. You can find it at the top of the ZeroTier app's pull-down menu or by typing "sudo zerotier-cli info" in a terminal window. This number is unique to your system and is how network administrators can recognize you. If someone invited you to a network, give them this ID so they can authorize you to join.

-

Starting, Stopping, and Uninstalling

-

The ZeroTier service is separate from the UI app and starts on system boot. The app can be started on login or only when needed. To stop the ZeroTier service use:

-      sudo launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist

- Replace "unload" with "load" to start it again.

-

ZeroTier can be uninstalled with:

-      sudo '/Library/Application Support/ZeroTier/One/uninstall.sh' -

-

For more information, visit zerotier.com.

-
- - \ No newline at end of file diff --git a/attic/macui/ZeroTier One/main.m b/attic/macui/ZeroTier One/main.m deleted file mode 100644 index 108a6bd18..000000000 --- a/attic/macui/ZeroTier One/main.m +++ /dev/null @@ -1,23 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -int main(int argc, const char * argv[]) { - return NSApplicationMain(argc, argv); -} diff --git a/attic/world/mkworld.cpp b/attic/world/mkworld.cpp index 6b9bbe8d0..ed2c499a0 100644 --- a/attic/world/mkworld.cpp +++ b/attic/world/mkworld.cpp @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include #include @@ -54,7 +54,7 @@ int main(int argc,char **argv) { std::string previous,current; if ((!OSUtils::readFile("previous.c25519",previous))||(!OSUtils::readFile("current.c25519",current))) { - C25519::Pair np(C25519::generate()); + ECC::Pair np(ECC::generate()); previous = std::string(); previous.append((const char *)np.pub.data,ZT_C25519_PUBLIC_KEY_LEN); previous.append((const char *)np.priv.data,ZT_C25519_PRIVATE_KEY_LEN); @@ -68,10 +68,10 @@ int main(int argc,char **argv) fprintf(stderr,"FATAL: previous.c25519 or current.c25519 empty or invalid" ZT_EOL_S); return 1; } - C25519::Pair previousKP; + ECC::Pair previousKP; memcpy(previousKP.pub.data,previous.data(),ZT_C25519_PUBLIC_KEY_LEN); memcpy(previousKP.priv.data,previous.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); - C25519::Pair currentKP; + ECC::Pair currentKP; memcpy(currentKP.pub.data,current.data(),ZT_C25519_PUBLIC_KEY_LEN); memcpy(currentKP.priv.data,current.data() + ZT_C25519_PUBLIC_KEY_LEN,ZT_C25519_PRIVATE_KEY_LEN); diff --git a/ext/ed25519-amd64-asm/sign.c b/ext/ed25519-amd64-asm/sign.c index 882ae76f3..715feb5b7 100644 --- a/ext/ed25519-amd64-asm/sign.c +++ b/ext/ed25519-amd64-asm/sign.c @@ -61,7 +61,7 @@ int crypto_sign( #endif #if 0 -void C25519::sign(const C25519::Private &myPrivate,const C25519::Public &myPublic,const void *msg,unsigned int len,void *signature) +void ECC::sign(const ECC::Private &myPrivate,const ECC::Public &myPublic,const void *msg,unsigned int len,void *signature) { sc25519 sck, scs, scsk; ge25519 ger; diff --git a/include/ZeroTierDebug.h b/include/ZeroTierDebug.h index 3d1942fd1..2e9cc2c5a 100644 --- a/include/ZeroTierDebug.h +++ b/include/ZeroTierDebug.h @@ -21,84 +21,81 @@ #define ZT_DEBUG_H #if defined(__linux__) || defined(__APPLE__) -#include #include +#include #include #endif #include -#define ZT_MSG_INFO true -#define ZT_COLOR true +#define ZT_MSG_INFO true +#define ZT_COLOR true // Debug output colors #if defined(__APPLE__) - #include "TargetConditionals.h" +#include "TargetConditionals.h" #endif -#if defined(ZT_COLOR) && !defined(_WIN32) && !defined(__ANDROID__) && !defined(TARGET_OS_IPHONE) && !defined(TARGET_IPHONE_SIMULATOR) && !defined(__APP_FRAMEWORK__) - #define ZT_RED "\x1B[31m" - #define ZT_GRN "\x1B[32m" - #define ZT_YEL "\x1B[33m" - #define ZT_BLU "\x1B[34m" - #define ZT_MAG "\x1B[35m" - #define ZT_CYN "\x1B[36m" - #define ZT_WHT "\x1B[37m" - #define ZT_RESET "\x1B[0m" +#if defined(ZT_COLOR) && ! defined(_WIN32) && ! defined(__ANDROID__) && ! defined(TARGET_OS_IPHONE) && ! defined(TARGET_IPHONE_SIMULATOR) && ! defined(__APP_FRAMEWORK__) +#define ZT_RED "\x1B[31m" +#define ZT_GRN "\x1B[32m" +#define ZT_YEL "\x1B[33m" +#define ZT_BLU "\x1B[34m" +#define ZT_MAG "\x1B[35m" +#define ZT_CYN "\x1B[36m" +#define ZT_WHT "\x1B[37m" +#define ZT_RESET "\x1B[0m" #else - #define ZT_RED - #define ZT_GRN - #define ZT_YEL - #define ZT_BLU - #define ZT_MAG - #define ZT_CYN - #define ZT_WHT - #define ZT_RESET +#define ZT_RED +#define ZT_GRN +#define ZT_YEL +#define ZT_BLU +#define ZT_MAG +#define ZT_CYN +#define ZT_WHT +#define ZT_RESET #endif -#define ZT_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) // short +#define ZT_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) // short #ifdef __linux__ - #define ZT_THREAD_ID (long)0 // syscall(SYS_gettid) +#define ZT_THREAD_ID (long)0 // syscall(SYS_gettid) #endif #ifdef __APPLE__ - #define ZT_THREAD_ID (long)0 // (long)gettid() +#define ZT_THREAD_ID (long)0 // (long)gettid() #endif #ifdef __FreeBSD__ - #define ZT_THREAD_ID (long)0 // (long)gettid() +#define ZT_THREAD_ID (long)0 // (long)gettid() #endif #ifdef _WIN32 - #define ZT_THREAD_ID (long)0 // +#define ZT_THREAD_ID (long)0 // #endif #if defined(__JNI_LIB__) - #include +#include #endif #if defined(__ANDROID__) - #include - #define ZT_LOG_TAG "ZTSDK" +#include +#define ZT_LOG_TAG "ZTSDK" #endif #if defined(ZT_DEBUG_TRACE) - #if ZT_MSG_INFO == true - #if defined(__ANDROID__) - #define DEBUG_INFO(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, \ - "INFO : %17s:%5d:%20s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args)) - #endif - #if defined(_WIN32) - #define DEBUG_INFO(fmt, ...) fprintf(stderr, ZT_GRN "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" \ - ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__) - #endif - #if defined(__linux__) or defined(__APPLE__) or defined(__FreeBSD__) - #define DEBUG_INFO(fmt, args ...) fprintf(stderr, ZT_GRN "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" \ - ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args) - #endif - #else - #define DEBUG_INFO(fmt, args...) - #endif -#else // blank - #if defined(_WIN32) - #define DEBUG_INFO(...) - #else - #define DEBUG_INFO(fmt, args...) - #endif +#if ZT_MSG_INFO == true +#if defined(__ANDROID__) +#define DEBUG_INFO(fmt, args...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, ZT_LOG_TAG, "INFO : %17s:%5d:%20s: " fmt "\n", ZT_FILENAME, __LINE__, __FUNCTION__, ##args)) +#endif +#if defined(_WIN32) +#define DEBUG_INFO(fmt, ...) fprintf(stderr, ZT_GRN "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, __VA_ARGS__) +#endif +#if defined(__linux__) or defined(__APPLE__) or defined(__FreeBSD__) +#define DEBUG_INFO(fmt, args...) fprintf(stderr, ZT_GRN "INFO [%ld]: %17s:%5d:%25s: " fmt "\n" ZT_RESET, ZT_THREAD_ID, ZT_FILENAME, __LINE__, __FUNCTION__, ##args) +#endif +#else +#define DEBUG_INFO(fmt, args...) +#endif +#else // blank +#if defined(_WIN32) +#define DEBUG_INFO(...) +#else +#define DEBUG_INFO(fmt, args...) +#endif #endif -#endif // _H +#endif // _H diff --git a/include/ZeroTierOne.h b/include/ZeroTierOne.h index fd475959d..8aa701a8f 100644 --- a/include/ZeroTierOne.h +++ b/include/ZeroTierOne.h @@ -23,22 +23,24 @@ // For the struct sockaddr_storage structure #if defined(_WIN32) || defined(_WIN64) +// clang-format off #include #include #include +// clang-format on #else /* not Windows */ #include #include -#include #include +#include #endif /* Windows or not */ -#if defined (_MSC_VER) -#ifdef ZT_EXPORT +#if defined(_MSC_VER) +#ifdef ZT_EXPORT #define ZT_SDK_API __declspec(dllexport) #else #define ZT_SDK_API __declspec(dllimport) -#if !defined(ZT_SDK) +#if ! defined(ZT_SDK) #ifdef _DEBUG #ifdef _WIN64 #pragma comment(lib, "ZeroTierOne_x64d.lib") @@ -291,74 +293,74 @@ extern "C" { #define ZT_RULE_PACKET_CHARACTERISTICS_TCP_FIN 0x0000000000000001ULL // Fields in remote trace dictionaries -#define ZT_REMOTE_TRACE_FIELD__EVENT "event" -#define ZT_REMOTE_TRACE_FIELD__NODE_ID "nodeId" -#define ZT_REMOTE_TRACE_FIELD__PACKET_ID "packetId" -#define ZT_REMOTE_TRACE_FIELD__PACKET_VERB "packetVerb" -#define ZT_REMOTE_TRACE_FIELD__PACKET_TRUSTED_PATH_ID "packetTrustedPathId" +#define ZT_REMOTE_TRACE_FIELD__EVENT "event" +#define ZT_REMOTE_TRACE_FIELD__NODE_ID "nodeId" +#define ZT_REMOTE_TRACE_FIELD__PACKET_ID "packetId" +#define ZT_REMOTE_TRACE_FIELD__PACKET_VERB "packetVerb" +#define ZT_REMOTE_TRACE_FIELD__PACKET_TRUSTED_PATH_ID "packetTrustedPathId" #define ZT_REMOTE_TRACE_FIELD__PACKET_TRUSTED_PATH_APPROVED "packetTrustedPathApproved" -#define ZT_REMOTE_TRACE_FIELD__PACKET_HOPS "packetHops" -#define ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR "remoteZtAddr" -#define ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR "remotePhyAddr" -#define ZT_REMOTE_TRACE_FIELD__LOCAL_ZTADDR "localZtAddr" -#define ZT_REMOTE_TRACE_FIELD__LOCAL_PHYADDR "localPhyAddr" -#define ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET "localSocket" -#define ZT_REMOTE_TRACE_FIELD__IP_SCOPE "phyAddrIpScope" -#define ZT_REMOTE_TRACE_FIELD__NETWORK_ID "networkId" -#define ZT_REMOTE_TRACE_FIELD__SOURCE_ZTADDR "sourceZtAddr" -#define ZT_REMOTE_TRACE_FIELD__DEST_ZTADDR "destZtAddr" -#define ZT_REMOTE_TRACE_FIELD__SOURCE_MAC "sourceMac" -#define ZT_REMOTE_TRACE_FIELD__DEST_MAC "destMac" -#define ZT_REMOTE_TRACE_FIELD__ETHERTYPE "etherType" -#define ZT_REMOTE_TRACE_FIELD__VLAN_ID "vlanId" -#define ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH "frameLength" -#define ZT_REMOTE_TRACE_FIELD__FRAME_DATA "frameData" -#define ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_NOTEE "filterNoTee" -#define ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_INBOUND "filterInbound" -#define ZT_REMOTE_TRACE_FIELD__FILTER_RESULT "filterResult" -#define ZT_REMOTE_TRACE_FIELD__FILTER_BASE_RULE_LOG "filterBaseRuleLog" -#define ZT_REMOTE_TRACE_FIELD__FILTER_CAP_RULE_LOG "filterCapRuleLog" -#define ZT_REMOTE_TRACE_FIELD__FILTER_CAP_ID "filterMatchingCapId" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE "credType" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID "credId" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP "credTs" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_INFO "credInfo" -#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO "credIssuedTo" +#define ZT_REMOTE_TRACE_FIELD__PACKET_HOPS "packetHops" +#define ZT_REMOTE_TRACE_FIELD__REMOTE_ZTADDR "remoteZtAddr" +#define ZT_REMOTE_TRACE_FIELD__REMOTE_PHYADDR "remotePhyAddr" +#define ZT_REMOTE_TRACE_FIELD__LOCAL_ZTADDR "localZtAddr" +#define ZT_REMOTE_TRACE_FIELD__LOCAL_PHYADDR "localPhyAddr" +#define ZT_REMOTE_TRACE_FIELD__LOCAL_SOCKET "localSocket" +#define ZT_REMOTE_TRACE_FIELD__IP_SCOPE "phyAddrIpScope" +#define ZT_REMOTE_TRACE_FIELD__NETWORK_ID "networkId" +#define ZT_REMOTE_TRACE_FIELD__SOURCE_ZTADDR "sourceZtAddr" +#define ZT_REMOTE_TRACE_FIELD__DEST_ZTADDR "destZtAddr" +#define ZT_REMOTE_TRACE_FIELD__SOURCE_MAC "sourceMac" +#define ZT_REMOTE_TRACE_FIELD__DEST_MAC "destMac" +#define ZT_REMOTE_TRACE_FIELD__ETHERTYPE "etherType" +#define ZT_REMOTE_TRACE_FIELD__VLAN_ID "vlanId" +#define ZT_REMOTE_TRACE_FIELD__FRAME_LENGTH "frameLength" +#define ZT_REMOTE_TRACE_FIELD__FRAME_DATA "frameData" +#define ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_NOTEE "filterNoTee" +#define ZT_REMOTE_TRACE_FIELD__FILTER_FLAG_INBOUND "filterInbound" +#define ZT_REMOTE_TRACE_FIELD__FILTER_RESULT "filterResult" +#define ZT_REMOTE_TRACE_FIELD__FILTER_BASE_RULE_LOG "filterBaseRuleLog" +#define ZT_REMOTE_TRACE_FIELD__FILTER_CAP_RULE_LOG "filterCapRuleLog" +#define ZT_REMOTE_TRACE_FIELD__FILTER_CAP_ID "filterMatchingCapId" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TYPE "credType" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ID "credId" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_TIMESTAMP "credTs" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_INFO "credInfo" +#define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_ISSUED_TO "credIssuedTo" #define ZT_REMOTE_TRACE_FIELD__CREDENTIAL_REVOCATION_TARGET "credRevocationTarget" -#define ZT_REMOTE_TRACE_FIELD__REASON "reason" -#define ZT_REMOTE_TRACE_FIELD__NETWORK_CONTROLLER_ID "networkControllerId" +#define ZT_REMOTE_TRACE_FIELD__REASON "reason" +#define ZT_REMOTE_TRACE_FIELD__NETWORK_CONTROLLER_ID "networkControllerId" // Event types in remote traces -#define ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE 0x1000 -#define ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH 0x1001 -#define ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH 0x1002 -#define ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED 0x1003 -#define ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE 0x1004 -#define ZT_REMOTE_TRACE_EVENT__PACKET_INVALID 0x1005 -#define ZT_REMOTE_TRACE_EVENT__DROPPED_HELLO 0x1006 +#define ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE 0x1000 +#define ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH 0x1001 +#define ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH 0x1002 +#define ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED 0x1003 +#define ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE 0x1004 +#define ZT_REMOTE_TRACE_EVENT__PACKET_INVALID 0x1005 +#define ZT_REMOTE_TRACE_EVENT__DROPPED_HELLO 0x1006 #define ZT_REMOTE_TRACE_EVENT__OUTGOING_NETWORK_FRAME_DROPPED 0x2000 #define ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_ACCESS_DENIED 0x2001 #define ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_FRAME_DROPPED 0x2002 -#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED 0x2003 -#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED 0x2004 -#define ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT 0x2005 -#define ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE 0x2006 +#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED 0x2003 +#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED 0x2004 +#define ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT 0x2005 +#define ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE 0x2006 // Event types in remote traces in hex string form -#define ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE_S "1000" -#define ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH_S "1001" -#define ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH_S "1002" -#define ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED_S "1003" -#define ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE_S "1004" -#define ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S "1005" -#define ZT_REMOTE_TRACE_EVENT__DROPPED_HELLO_S "1006" +#define ZT_REMOTE_TRACE_EVENT__RESETTING_PATHS_IN_SCOPE_S "1000" +#define ZT_REMOTE_TRACE_EVENT__PEER_CONFIRMING_UNKNOWN_PATH_S "1001" +#define ZT_REMOTE_TRACE_EVENT__PEER_LEARNED_NEW_PATH_S "1002" +#define ZT_REMOTE_TRACE_EVENT__PEER_REDIRECTED_S "1003" +#define ZT_REMOTE_TRACE_EVENT__PACKET_MAC_FAILURE_S "1004" +#define ZT_REMOTE_TRACE_EVENT__PACKET_INVALID_S "1005" +#define ZT_REMOTE_TRACE_EVENT__DROPPED_HELLO_S "1006" #define ZT_REMOTE_TRACE_EVENT__OUTGOING_NETWORK_FRAME_DROPPED_S "2000" #define ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_ACCESS_DENIED_S "2001" #define ZT_REMOTE_TRACE_EVENT__INCOMING_NETWORK_FRAME_DROPPED_S "2002" -#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S "2003" -#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S "2004" -#define ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT_S "2005" -#define ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE_S "2006" +#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_REJECTED_S "2003" +#define ZT_REMOTE_TRACE_EVENT__CREDENTIAL_ACCEPTED_S "2004" +#define ZT_REMOTE_TRACE_EVENT__NETWORK_CONFIG_REQUEST_SENT_S "2005" +#define ZT_REMOTE_TRACE_EVENT__NETWORK_FILTER_TRACE_S "2006" /****************************************************************************/ /* Structures and other types */ @@ -372,192 +374,189 @@ extern "C" { * indicate serious problems like an inaccessible data store or a compile * problem. */ -enum ZT_ResultCode -{ - /** - * Operation completed normally - */ - ZT_RESULT_OK = 0, +enum ZT_ResultCode { + /** + * Operation completed normally + */ + ZT_RESULT_OK = 0, - /** - * Call produced no error but no action was taken - */ - ZT_RESULT_OK_IGNORED = 1, + /** + * Call produced no error but no action was taken + */ + ZT_RESULT_OK_IGNORED = 1, - // Fatal errors (>=100, <1000) + // Fatal errors (>=100, <1000) - /** - * Ran out of memory - */ - ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY = 100, + /** + * Ran out of memory + */ + ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY = 100, - /** - * Data store is not writable or has failed - */ - ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED = 101, + /** + * Data store is not writable or has failed + */ + ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED = 101, - /** - * Internal error (e.g. unexpected exception indicating bug or build problem) - */ - ZT_RESULT_FATAL_ERROR_INTERNAL = 102, + /** + * Internal error (e.g. unexpected exception indicating bug or build problem) + */ + ZT_RESULT_FATAL_ERROR_INTERNAL = 102, - // Non-fatal errors (>1000) + // Non-fatal errors (>1000) - /** - * Network ID not valid - */ - ZT_RESULT_ERROR_NETWORK_NOT_FOUND = 1000, + /** + * Network ID not valid + */ + ZT_RESULT_ERROR_NETWORK_NOT_FOUND = 1000, - /** - * The requested operation is not supported on this version or build - */ - ZT_RESULT_ERROR_UNSUPPORTED_OPERATION = 1001, + /** + * The requested operation is not supported on this version or build + */ + ZT_RESULT_ERROR_UNSUPPORTED_OPERATION = 1001, - /** - * The requested operation was given a bad parameter or was called in an invalid state - */ - ZT_RESULT_ERROR_BAD_PARAMETER = 1002 + /** + * The requested operation was given a bad parameter or was called in an invalid state + */ + ZT_RESULT_ERROR_BAD_PARAMETER = 1002 }; /** * @param x Result code * @return True if result code indicates a fatal error */ -#define ZT_ResultCode_isFatal(x) ((((int)(x)) >= 100)&&(((int)(x)) < 1000)) +#define ZT_ResultCode_isFatal(x) ((((int)(x)) >= 100) && (((int)(x)) < 1000)) /** * Status codes sent to status update callback when things happen */ -enum ZT_Event -{ - /** - * Node has been initialized - * - * This is the first event generated, and is always sent. It may occur - * before Node's constructor returns. - * - * Meta-data: none - */ - ZT_EVENT_UP = 0, +enum ZT_Event { + /** + * Node has been initialized + * + * This is the first event generated, and is always sent. It may occur + * before Node's constructor returns. + * + * Meta-data: none + */ + ZT_EVENT_UP = 0, - /** - * Node is offline -- network does not seem to be reachable by any available strategy - * - * Meta-data: none - */ - ZT_EVENT_OFFLINE = 1, + /** + * Node is offline -- network does not seem to be reachable by any available strategy + * + * Meta-data: none + */ + ZT_EVENT_OFFLINE = 1, - /** - * Node is online -- at least one upstream node appears reachable - * - * Meta-data: none - */ - ZT_EVENT_ONLINE = 2, + /** + * Node is online -- at least one upstream node appears reachable + * + * Meta-data: none + */ + ZT_EVENT_ONLINE = 2, - /** - * Node is shutting down - * - * This is generated within Node's destructor when it is being shut down. - * It's done for convenience, since cleaning up other state in the event - * handler may appear more idiomatic. - * - * Meta-data: none - */ - ZT_EVENT_DOWN = 3, + /** + * Node is shutting down + * + * This is generated within Node's destructor when it is being shut down. + * It's done for convenience, since cleaning up other state in the event + * handler may appear more idiomatic. + * + * Meta-data: none + */ + ZT_EVENT_DOWN = 3, - /** - * Your identity has collided with another node's ZeroTier address - * - * This happens if two different public keys both hash (via the algorithm - * in Identity::generate()) to the same 40-bit ZeroTier address. - * - * This is something you should "never" see, where "never" is defined as - * once per 2^39 new node initializations / identity creations. If you do - * see it, you're going to see it very soon after a node is first - * initialized. - * - * This is reported as an event rather than a return code since it's - * detected asynchronously via error messages from authoritative nodes. - * - * If this occurs, you must shut down and delete the node, delete the - * identity.secret record/file from the data store, and restart to generate - * a new identity. If you don't do this, you will not be able to communicate - * with other nodes. - * - * We'd automate this process, but we don't think silently deleting - * private keys or changing our address without telling the calling code - * is good form. It violates the principle of least surprise. - * - * You can technically get away with not handling this, but we recommend - * doing so in a mature reliable application. Besides, handling this - * condition is a good way to make sure it never arises. It's like how - * umbrellas prevent rain and smoke detectors prevent fires. They do, right? - * - * Meta-data: none - */ - ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION = 4, + /** + * Your identity has collided with another node's ZeroTier address + * + * This happens if two different public keys both hash (via the algorithm + * in Identity::generate()) to the same 40-bit ZeroTier address. + * + * This is something you should "never" see, where "never" is defined as + * once per 2^39 new node initializations / identity creations. If you do + * see it, you're going to see it very soon after a node is first + * initialized. + * + * This is reported as an event rather than a return code since it's + * detected asynchronously via error messages from authoritative nodes. + * + * If this occurs, you must shut down and delete the node, delete the + * identity.secret record/file from the data store, and restart to generate + * a new identity. If you don't do this, you will not be able to communicate + * with other nodes. + * + * We'd automate this process, but we don't think silently deleting + * private keys or changing our address without telling the calling code + * is good form. It violates the principle of least surprise. + * + * You can technically get away with not handling this, but we recommend + * doing so in a mature reliable application. Besides, handling this + * condition is a good way to make sure it never arises. It's like how + * umbrellas prevent rain and smoke detectors prevent fires. They do, right? + * + * Meta-data: none + */ + ZT_EVENT_FATAL_ERROR_IDENTITY_COLLISION = 4, - /** - * Trace (debugging) message - * - * These events are only generated if this is a TRACE-enabled build. - * - * Meta-data: C string, TRACE message - */ - ZT_EVENT_TRACE = 5, + /** + * Trace (debugging) message + * + * These events are only generated if this is a TRACE-enabled build. + * + * Meta-data: C string, TRACE message + */ + ZT_EVENT_TRACE = 5, - /** - * VERB_USER_MESSAGE received - * - * These are generated when a VERB_USER_MESSAGE packet is received via - * ZeroTier VL1. - * - * Meta-data: ZT_UserMessage structure - */ - ZT_EVENT_USER_MESSAGE = 6, + /** + * VERB_USER_MESSAGE received + * + * These are generated when a VERB_USER_MESSAGE packet is received via + * ZeroTier VL1. + * + * Meta-data: ZT_UserMessage structure + */ + ZT_EVENT_USER_MESSAGE = 6, - /** - * Remote trace received - * - * These are generated when a VERB_REMOTE_TRACE is received. Note - * that any node can fling one of these at us. It is your responsibility - * to filter and determine if it's worth paying attention to. If it's - * not just drop it. Most nodes that are not active controllers ignore - * these, and controllers only save them if they pertain to networks - * with remote tracing enabled. - * - * Meta-data: ZT_RemoteTrace structure - */ - ZT_EVENT_REMOTE_TRACE = 7 + /** + * Remote trace received + * + * These are generated when a VERB_REMOTE_TRACE is received. Note + * that any node can fling one of these at us. It is your responsibility + * to filter and determine if it's worth paying attention to. If it's + * not just drop it. Most nodes that are not active controllers ignore + * these, and controllers only save them if they pertain to networks + * with remote tracing enabled. + * + * Meta-data: ZT_RemoteTrace structure + */ + ZT_EVENT_REMOTE_TRACE = 7 }; /** * Payload of REMOTE_TRACE event */ -typedef struct -{ - /** - * ZeroTier address of sender - */ - uint64_t origin; +typedef struct { + /** + * ZeroTier address of sender + */ + uint64_t origin; - /** - * Null-terminated Dictionary containing key/value pairs sent by origin - * - * This *should* be a dictionary, but the implementation only checks - * that it is a valid non-empty C-style null-terminated string. Be very - * careful to use a well-tested parser to parse this as it represents - * data received from a potentially un-trusted peer on the network. - * Invalid payloads should be dropped. - * - * The contents of data[] may be modified. - */ - char *data; + /** + * Null-terminated Dictionary containing key/value pairs sent by origin + * + * This *should* be a dictionary, but the implementation only checks + * that it is a valid non-empty C-style null-terminated string. Be very + * careful to use a well-tested parser to parse this as it represents + * data received from a potentially un-trusted peer on the network. + * Invalid payloads should be dropped. + * + * The contents of data[] may be modified. + */ + char* data; - /** - * Length of dict[] in bytes, including terminating null - */ - unsigned int len; + /** + * Length of dict[] in bytes, including terminating null + */ + unsigned int len; } ZT_RemoteTrace; /** @@ -570,57 +569,55 @@ typedef struct * in the world can send you a user message! (Unless your network is air * gapped.) */ -typedef struct -{ - /** - * ZeroTier address of sender (least significant 40 bits) - */ - uint64_t origin; +typedef struct { + /** + * ZeroTier address of sender (least significant 40 bits) + */ + uint64_t origin; - /** - * User message type ID - */ - uint64_t typeId; + /** + * User message type ID + */ + uint64_t typeId; - /** - * User message data (not including type ID) - */ - const void *data; + /** + * User message data (not including type ID) + */ + const void* data; - /** - * Length of data in bytes - */ - unsigned int length; + /** + * Length of data in bytes + */ + unsigned int length; } ZT_UserMessage; /** * Current node status */ -typedef struct -{ - /** - * 40-bit ZeroTier address of this node - */ - uint64_t address; +typedef struct { + /** + * 40-bit ZeroTier address of this node + */ + uint64_t address; - /** - * Public identity in string-serialized form (safe to send to others) - * - * This pointer will remain valid as long as the node exists. - */ - const char *publicIdentity; + /** + * Public identity in string-serialized form (safe to send to others) + * + * This pointer will remain valid as long as the node exists. + */ + const char* publicIdentity; - /** - * Full identity including secret key in string-serialized form - * - * This pointer will remain valid as long as the node exists. - */ - const char *secretIdentity; + /** + * Full identity including secret key in string-serialized form + * + * This pointer will remain valid as long as the node exists. + */ + const char* secretIdentity; - /** - * True if some kind of connectivity appears available - */ - int online; + /** + * True if some kind of connectivity appears available + */ + int online; } ZT_NodeStatus; /** @@ -628,74 +625,71 @@ typedef struct * * This structure is subject to change between versions. */ -typedef struct -{ - /** - * Number of each protocol verb (possible verbs 0..31) received - */ - uint64_t inVerbCounts[32]; +typedef struct { + /** + * Number of each protocol verb (possible verbs 0..31) received + */ + uint64_t inVerbCounts[32]; - /** - * Number of bytes for each protocol verb received - */ - uint64_t inVerbBytes[32]; + /** + * Number of bytes for each protocol verb received + */ + uint64_t inVerbBytes[32]; } ZT_NodeStatistics; /** * Virtual network status codes */ -enum ZT_VirtualNetworkStatus -{ - /** - * Waiting for network configuration (also means revision == 0) - */ - ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION = 0, +enum ZT_VirtualNetworkStatus { + /** + * Waiting for network configuration (also means revision == 0) + */ + ZT_NETWORK_STATUS_REQUESTING_CONFIGURATION = 0, - /** - * Configuration received and we are authorized - */ - ZT_NETWORK_STATUS_OK = 1, + /** + * Configuration received and we are authorized + */ + ZT_NETWORK_STATUS_OK = 1, - /** - * Netconf master told us 'nope' - */ - ZT_NETWORK_STATUS_ACCESS_DENIED = 2, + /** + * Netconf master told us 'nope' + */ + ZT_NETWORK_STATUS_ACCESS_DENIED = 2, - /** - * Netconf master exists, but this virtual network does not - */ - ZT_NETWORK_STATUS_NOT_FOUND = 3, + /** + * Netconf master exists, but this virtual network does not + */ + ZT_NETWORK_STATUS_NOT_FOUND = 3, - /** - * Initialization of network failed or other internal error - */ - ZT_NETWORK_STATUS_PORT_ERROR = 4, + /** + * Initialization of network failed or other internal error + */ + ZT_NETWORK_STATUS_PORT_ERROR = 4, - /** - * ZeroTier core version too old - */ - ZT_NETWORK_STATUS_CLIENT_TOO_OLD = 5, + /** + * ZeroTier core version too old + */ + ZT_NETWORK_STATUS_CLIENT_TOO_OLD = 5, - /** - * External authentication is required (e.g. SSO) - */ - ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED = 6 + /** + * External authentication is required (e.g. SSO) + */ + ZT_NETWORK_STATUS_AUTHENTICATION_REQUIRED = 6 }; /** * Virtual network type codes */ -enum ZT_VirtualNetworkType -{ - /** - * Private networks are authorized via certificates of membership - */ - ZT_NETWORK_TYPE_PRIVATE = 0, +enum ZT_VirtualNetworkType { + /** + * Private networks are authorized via certificates of membership + */ + ZT_NETWORK_TYPE_PRIVATE = 0, - /** - * Public networks have no access control -- they'll always be AUTHORIZED - */ - ZT_NETWORK_TYPE_PUBLIC = 1 + /** + * Public networks have no access control -- they'll always be AUTHORIZED + */ + ZT_NETWORK_TYPE_PUBLIC = 1 }; /** @@ -707,85 +701,84 @@ enum ZT_VirtualNetworkType * Each rule is composed of zero or more MATCHes followed by an ACTION. * An ACTION with no MATCHes is always taken. */ -enum ZT_VirtualNetworkRuleType -{ - // 0 to 15 reserved for actions +enum ZT_VirtualNetworkRuleType { + // 0 to 15 reserved for actions - /** - * Drop frame - */ - ZT_NETWORK_RULE_ACTION_DROP = 0, + /** + * Drop frame + */ + ZT_NETWORK_RULE_ACTION_DROP = 0, - /** - * Accept and pass frame - */ - ZT_NETWORK_RULE_ACTION_ACCEPT = 1, + /** + * Accept and pass frame + */ + ZT_NETWORK_RULE_ACTION_ACCEPT = 1, - /** - * Forward a copy of this frame to an observer (by ZT address) - */ - ZT_NETWORK_RULE_ACTION_TEE = 2, + /** + * Forward a copy of this frame to an observer (by ZT address) + */ + ZT_NETWORK_RULE_ACTION_TEE = 2, - /** - * Exactly like TEE but mandates ACKs from observer - */ - ZT_NETWORK_RULE_ACTION_WATCH = 3, + /** + * Exactly like TEE but mandates ACKs from observer + */ + ZT_NETWORK_RULE_ACTION_WATCH = 3, - /** - * Drop and redirect this frame to another node (by ZT address) - */ - ZT_NETWORK_RULE_ACTION_REDIRECT = 4, + /** + * Drop and redirect this frame to another node (by ZT address) + */ + ZT_NETWORK_RULE_ACTION_REDIRECT = 4, - /** - * Stop evaluating rule set (drops unless there are capabilities, etc.) - */ - ZT_NETWORK_RULE_ACTION_BREAK = 5, + /** + * Stop evaluating rule set (drops unless there are capabilities, etc.) + */ + ZT_NETWORK_RULE_ACTION_BREAK = 5, - /** - * Place a matching frame in the specified QoS bucket - */ - ZT_NETWORK_RULE_ACTION_PRIORITY = 6, + /** + * Place a matching frame in the specified QoS bucket + */ + ZT_NETWORK_RULE_ACTION_PRIORITY = 6, - /** - * Maximum ID for an ACTION, anything higher is a MATCH - */ - ZT_NETWORK_RULE_ACTION__MAX_ID = 15, + /** + * Maximum ID for an ACTION, anything higher is a MATCH + */ + ZT_NETWORK_RULE_ACTION__MAX_ID = 15, - // 16 to 63 reserved for match criteria + // 16 to 63 reserved for match criteria - ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS = 24, - ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS = 25, - ZT_NETWORK_RULE_MATCH_VLAN_ID = 26, - ZT_NETWORK_RULE_MATCH_VLAN_PCP = 27, - ZT_NETWORK_RULE_MATCH_VLAN_DEI = 28, - ZT_NETWORK_RULE_MATCH_MAC_SOURCE = 29, - ZT_NETWORK_RULE_MATCH_MAC_DEST = 30, - ZT_NETWORK_RULE_MATCH_IPV4_SOURCE = 31, - ZT_NETWORK_RULE_MATCH_IPV4_DEST = 32, - ZT_NETWORK_RULE_MATCH_IPV6_SOURCE = 33, - ZT_NETWORK_RULE_MATCH_IPV6_DEST = 34, - ZT_NETWORK_RULE_MATCH_IP_TOS = 35, - ZT_NETWORK_RULE_MATCH_IP_PROTOCOL = 36, - ZT_NETWORK_RULE_MATCH_ETHERTYPE = 37, - ZT_NETWORK_RULE_MATCH_ICMP = 38, - ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE = 39, - ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE = 40, - ZT_NETWORK_RULE_MATCH_CHARACTERISTICS = 41, - ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE = 42, - ZT_NETWORK_RULE_MATCH_RANDOM = 43, - ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE = 44, - ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND = 45, - ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR = 46, - ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR = 47, - ZT_NETWORK_RULE_MATCH_TAGS_EQUAL = 48, - ZT_NETWORK_RULE_MATCH_TAG_SENDER = 49, - ZT_NETWORK_RULE_MATCH_TAG_RECEIVER = 50, - ZT_NETWORK_RULE_MATCH_INTEGER_RANGE = 51, + ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS = 24, + ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS = 25, + ZT_NETWORK_RULE_MATCH_VLAN_ID = 26, + ZT_NETWORK_RULE_MATCH_VLAN_PCP = 27, + ZT_NETWORK_RULE_MATCH_VLAN_DEI = 28, + ZT_NETWORK_RULE_MATCH_MAC_SOURCE = 29, + ZT_NETWORK_RULE_MATCH_MAC_DEST = 30, + ZT_NETWORK_RULE_MATCH_IPV4_SOURCE = 31, + ZT_NETWORK_RULE_MATCH_IPV4_DEST = 32, + ZT_NETWORK_RULE_MATCH_IPV6_SOURCE = 33, + ZT_NETWORK_RULE_MATCH_IPV6_DEST = 34, + ZT_NETWORK_RULE_MATCH_IP_TOS = 35, + ZT_NETWORK_RULE_MATCH_IP_PROTOCOL = 36, + ZT_NETWORK_RULE_MATCH_ETHERTYPE = 37, + ZT_NETWORK_RULE_MATCH_ICMP = 38, + ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE = 39, + ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE = 40, + ZT_NETWORK_RULE_MATCH_CHARACTERISTICS = 41, + ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE = 42, + ZT_NETWORK_RULE_MATCH_RANDOM = 43, + ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE = 44, + ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND = 45, + ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR = 46, + ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR = 47, + ZT_NETWORK_RULE_MATCH_TAGS_EQUAL = 48, + ZT_NETWORK_RULE_MATCH_TAG_SENDER = 49, + ZT_NETWORK_RULE_MATCH_TAG_RECEIVER = 50, + ZT_NETWORK_RULE_MATCH_INTEGER_RANGE = 51, - /** - * Maximum ID allowed for a MATCH entry in the rules table - */ - ZT_NETWORK_RULE_MATCH__MAX_ID = 63 + /** + * Maximum ID allowed for a MATCH entry in the rules table + */ + ZT_NETWORK_RULE_MATCH__MAX_ID = 63 }; /** @@ -799,733 +792,713 @@ enum ZT_VirtualNetworkRuleType * This is designed to be a more memory-efficient way of storing rules than * a wide table, yet still fast and simple to access in code. */ -typedef struct -{ - /** - * Type and flags - * - * Bits are: NOTTTTTT - * - * N - If true, sense of match is inverted (no effect on actions) - * O - If true, result is ORed with previous instead of ANDed (no effect on actions) - * T - Rule or action type - * - * AND with 0x3f to get type, 0x80 to get NOT bit, and 0x40 to get OR bit. - */ - uint8_t t; +typedef struct { + /** + * Type and flags + * + * Bits are: NOTTTTTT + * + * N - If true, sense of match is inverted (no effect on actions) + * O - If true, result is ORed with previous instead of ANDed (no effect on actions) + * T - Rule or action type + * + * AND with 0x3f to get type, 0x80 to get NOT bit, and 0x40 to get OR bit. + */ + uint8_t t; - /** - * Union containing the value of this rule -- which field is used depends on 't' - */ - union { - /** - * IPv6 address in big-endian / network byte order and netmask bits - */ - struct { - uint8_t ip[16]; - uint8_t mask; - } ipv6; + /** + * Union containing the value of this rule -- which field is used depends on 't' + */ + union { + /** + * IPv6 address in big-endian / network byte order and netmask bits + */ + struct { + uint8_t ip[16]; + uint8_t mask; + } ipv6; - /** - * IPv4 address in big-endian / network byte order - */ - struct { - uint32_t ip; - uint8_t mask; - } ipv4; + /** + * IPv4 address in big-endian / network byte order + */ + struct { + uint32_t ip; + uint8_t mask; + } ipv4; - /** - * Integer range match in packet payload - * - * This allows matching of ranges of integers up to 64 bits wide where - * the range is +/- INT32_MAX. It's packed this way so it fits in 16 - * bytes and doesn't enlarge the overall size of this union. - */ - struct { - uint64_t start; // integer range start - uint32_t end; // end of integer range (relative to start, inclusive, 0 for equality w/start) - uint16_t idx; // index in packet of integer - uint8_t format; // bits in integer (range 1-64, ((format&63)+1)) and endianness (MSB 1 for little, 0 for big) - } intRange; + /** + * Integer range match in packet payload + * + * This allows matching of ranges of integers up to 64 bits wide where + * the range is +/- INT32_MAX. It's packed this way so it fits in 16 + * bytes and doesn't enlarge the overall size of this union. + */ + struct { + uint64_t start; // integer range start + uint32_t end; // end of integer range (relative to start, inclusive, 0 for equality w/start) + uint16_t idx; // index in packet of integer + uint8_t format; // bits in integer (range 1-64, ((format&63)+1)) and endianness (MSB 1 for little, 0 for big) + } intRange; - /** - * Packet characteristic flags being matched - */ - uint64_t characteristics; + /** + * Packet characteristic flags being matched + */ + uint64_t characteristics; - /** - * IP port range -- start-end inclusive -- host byte order - */ - uint16_t port[2]; + /** + * IP port range -- start-end inclusive -- host byte order + */ + uint16_t port[2]; - /** - * 40-bit ZeroTier address (in least significant bits, host byte order) - */ - uint64_t zt; + /** + * 40-bit ZeroTier address (in least significant bits, host byte order) + */ + uint64_t zt; - /** - * 0 = never, UINT32_MAX = always - */ - uint32_t randomProbability; + /** + * 0 = never, UINT32_MAX = always + */ + uint32_t randomProbability; - /** - * 48-bit Ethernet MAC address in big-endian order - */ - uint8_t mac[6]; + /** + * 48-bit Ethernet MAC address in big-endian order + */ + uint8_t mac[6]; - /** - * VLAN ID in host byte order - */ - uint16_t vlanId; + /** + * VLAN ID in host byte order + */ + uint16_t vlanId; - /** - * VLAN PCP (least significant 3 bits) - */ - uint8_t vlanPcp; + /** + * VLAN PCP (least significant 3 bits) + */ + uint8_t vlanPcp; - /** - * VLAN DEI (single bit / boolean) - */ - uint8_t vlanDei; + /** + * VLAN DEI (single bit / boolean) + */ + uint8_t vlanDei; - /** - * Ethernet type in host byte order - */ - uint16_t etherType; + /** + * Ethernet type in host byte order + */ + uint16_t etherType; - /** - * IP protocol - */ - uint8_t ipProtocol; + /** + * IP protocol + */ + uint8_t ipProtocol; - /** - * IP type of service a.k.a. DSCP field - */ - struct { - uint8_t mask; - uint8_t value[2]; - } ipTos; + /** + * IP type of service a.k.a. DSCP field + */ + struct { + uint8_t mask; + uint8_t value[2]; + } ipTos; - /** - * Ethernet packet size in host byte order (start-end, inclusive) - */ - uint16_t frameSize[2]; + /** + * Ethernet packet size in host byte order (start-end, inclusive) + */ + uint16_t frameSize[2]; - /** - * ICMP type and code - */ - struct { - uint8_t type; // ICMP type, always matched - uint8_t code; // ICMP code if matched - uint8_t flags; // flag 0x01 means also match code, otherwise only match type - } icmp; + /** + * ICMP type and code + */ + struct { + uint8_t type; // ICMP type, always matched + uint8_t code; // ICMP code if matched + uint8_t flags; // flag 0x01 means also match code, otherwise only match type + } icmp; - /** - * For tag-related rules - */ - struct { - uint32_t id; - uint32_t value; - } tag; + /** + * For tag-related rules + */ + struct { + uint32_t id; + uint32_t value; + } tag; - /** - * Destinations for TEE and REDIRECT - */ - struct { - uint64_t address; - uint32_t flags; - uint16_t length; - } fwd; + /** + * Destinations for TEE and REDIRECT + */ + struct { + uint64_t address; + uint32_t flags; + uint16_t length; + } fwd; - /** - * Quality of Service (QoS) bucket we want a frame to be placed in - */ - uint8_t qosBucket; - } v; + /** + * Quality of Service (QoS) bucket we want a frame to be placed in + */ + uint8_t qosBucket; + } v; } ZT_VirtualNetworkRule; /** * A route to be pushed on a virtual network */ -typedef struct -{ - /** - * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default - */ - struct sockaddr_storage target; +typedef struct { + /** + * Target network / netmask bits (in port field) or NULL or 0.0.0.0/0 for default + */ + struct sockaddr_storage target; - /** - * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) - */ - struct sockaddr_storage via; + /** + * Gateway IP address (port ignored) or NULL (family == 0) for LAN-local (no gateway) + */ + struct sockaddr_storage via; - /** - * Route flags - */ - uint16_t flags; + /** + * Route flags + */ + uint16_t flags; - /** - * Route metric (not currently used) - */ - uint16_t metric; + /** + * Route metric (not currently used) + */ + uint16_t metric; } ZT_VirtualNetworkRoute; /** * DNS configuration to be pushed on a virtual network */ -typedef struct -{ - char domain[128]; - struct sockaddr_storage server_addr[ZT_MAX_DNS_SERVERS]; +typedef struct { + char domain[128]; + struct sockaddr_storage server_addr[ZT_MAX_DNS_SERVERS]; } ZT_VirtualNetworkDNS; /** * An Ethernet multicast group */ -typedef struct -{ - /** - * MAC address (least significant 48 bits) - */ - uint64_t mac; +typedef struct { + /** + * MAC address (least significant 48 bits) + */ + uint64_t mac; - /** - * Additional distinguishing information (usually zero) - */ - unsigned long adi; + /** + * Additional distinguishing information (usually zero) + */ + unsigned long adi; } ZT_MulticastGroup; /** * Virtual network configuration update type */ -enum ZT_VirtualNetworkConfigOperation -{ - /** - * Network is coming up (either for the first time or after service restart) - */ - ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP = 1, +enum ZT_VirtualNetworkConfigOperation { + /** + * Network is coming up (either for the first time or after service restart) + */ + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_UP = 1, - /** - * Network configuration has been updated - */ - ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE = 2, + /** + * Network configuration has been updated + */ + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE = 2, - /** - * Network is going down (not permanently) - */ - ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN = 3, + /** + * Network is going down (not permanently) + */ + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN = 3, - /** - * Network is going down permanently (leave/delete) - */ - ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4 + /** + * Network is going down permanently (leave/delete) + */ + ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY = 4 }; /** * What trust hierarchy role does this peer have? */ -enum ZT_PeerRole -{ - ZT_PEER_ROLE_LEAF = 0, // ordinary node - ZT_PEER_ROLE_MOON = 1, // moon root - ZT_PEER_ROLE_PLANET = 2 // planetary root +enum ZT_PeerRole { + ZT_PEER_ROLE_LEAF = 0, // ordinary node + ZT_PEER_ROLE_MOON = 1, // moon root + ZT_PEER_ROLE_PLANET = 2 // planetary root }; /** * Vendor ID */ -enum ZT_Vendor -{ - ZT_VENDOR_UNSPECIFIED = 0, - ZT_VENDOR_ZEROTIER = 1 -}; +enum ZT_Vendor { ZT_VENDOR_UNSPECIFIED = 0, ZT_VENDOR_ZEROTIER = 1 }; /** * Platform type */ -enum ZT_Platform -{ - ZT_PLATFORM_UNSPECIFIED = 0, - ZT_PLATFORM_LINUX = 1, - ZT_PLATFORM_WINDOWS = 2, - ZT_PLATFORM_MACOS = 3, - ZT_PLATFORM_ANDROID = 4, - ZT_PLATFORM_IOS = 5, - ZT_PLATFORM_SOLARIS_SMARTOS = 6, - ZT_PLATFORM_FREEBSD = 7, - ZT_PLATFORM_NETBSD = 8, - ZT_PLATFORM_OPENBSD = 9, - ZT_PLATFORM_RISCOS = 10, - ZT_PLATFORM_VXWORKS = 11, - ZT_PLATFORM_FREERTOS = 12, - ZT_PLATFORM_SYSBIOS = 13, - ZT_PLATFORM_HURD = 14, - ZT_PLATFORM_WEB = 15 +enum ZT_Platform { + ZT_PLATFORM_UNSPECIFIED = 0, + ZT_PLATFORM_LINUX = 1, + ZT_PLATFORM_WINDOWS = 2, + ZT_PLATFORM_MACOS = 3, + ZT_PLATFORM_ANDROID = 4, + ZT_PLATFORM_IOS = 5, + ZT_PLATFORM_SOLARIS_SMARTOS = 6, + ZT_PLATFORM_FREEBSD = 7, + ZT_PLATFORM_NETBSD = 8, + ZT_PLATFORM_OPENBSD = 9, + ZT_PLATFORM_RISCOS = 10, + ZT_PLATFORM_VXWORKS = 11, + ZT_PLATFORM_FREERTOS = 12, + ZT_PLATFORM_SYSBIOS = 13, + ZT_PLATFORM_HURD = 14, + ZT_PLATFORM_WEB = 15 }; /** * Architecture type */ -enum ZT_Architecture -{ - ZT_ARCHITECTURE_UNSPECIFIED = 0, - ZT_ARCHITECTURE_X86 = 1, - ZT_ARCHITECTURE_X64 = 2, - ZT_ARCHITECTURE_ARM32 = 3, - ZT_ARCHITECTURE_ARM64 = 4, - ZT_ARCHITECTURE_MIPS32 = 5, - ZT_ARCHITECTURE_MIPS64 = 6, - ZT_ARCHITECTURE_POWER32 = 7, - ZT_ARCHITECTURE_POWER64 = 8, - ZT_ARCHITECTURE_OPENRISC32 = 9, - ZT_ARCHITECTURE_OPENRISC64 = 10, - ZT_ARCHITECTURE_SPARC32 = 11, - ZT_ARCHITECTURE_SPARC64 = 12, - ZT_ARCHITECTURE_DOTNET_CLR = 13, - ZT_ARCHITECTURE_JAVA_JVM = 14, - ZT_ARCHITECTURE_WEB = 15, - ZT_ARCHITECTURE_S390X = 16, - ZT_ARCHITECTURE_LOONGARCH64 = 17 +enum ZT_Architecture { + ZT_ARCHITECTURE_UNSPECIFIED = 0, + ZT_ARCHITECTURE_X86 = 1, + ZT_ARCHITECTURE_X64 = 2, + ZT_ARCHITECTURE_ARM32 = 3, + ZT_ARCHITECTURE_ARM64 = 4, + ZT_ARCHITECTURE_MIPS32 = 5, + ZT_ARCHITECTURE_MIPS64 = 6, + ZT_ARCHITECTURE_POWER32 = 7, + ZT_ARCHITECTURE_POWER64 = 8, + ZT_ARCHITECTURE_OPENRISC32 = 9, + ZT_ARCHITECTURE_OPENRISC64 = 10, + ZT_ARCHITECTURE_SPARC32 = 11, + ZT_ARCHITECTURE_SPARC64 = 12, + ZT_ARCHITECTURE_DOTNET_CLR = 13, + ZT_ARCHITECTURE_JAVA_JVM = 14, + ZT_ARCHITECTURE_WEB = 15, + ZT_ARCHITECTURE_S390X = 16, + ZT_ARCHITECTURE_LOONGARCH64 = 17 }; /** * Virtual network configuration */ -typedef struct -{ - /** - * 64-bit ZeroTier network ID - */ - uint64_t nwid; +typedef struct { + /** + * 64-bit ZeroTier network ID + */ + uint64_t nwid; - /** - * Ethernet MAC (48 bits) that should be assigned to port - */ - uint64_t mac; + /** + * Ethernet MAC (48 bits) that should be assigned to port + */ + uint64_t mac; - /** - * Network name (from network configuration master) - */ - char name[ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1]; + /** + * Network name (from network configuration master) + */ + char name[ZT_MAX_NETWORK_SHORT_NAME_LENGTH + 1]; - /** - * Network configuration request status - */ - enum ZT_VirtualNetworkStatus status; + /** + * Network configuration request status + */ + enum ZT_VirtualNetworkStatus status; - /** - * Network type - */ - enum ZT_VirtualNetworkType type; + /** + * Network type + */ + enum ZT_VirtualNetworkType type; - /** - * Maximum interface MTU - */ - unsigned int mtu; + /** + * Maximum interface MTU + */ + unsigned int mtu; - /** - * If nonzero, the network this port belongs to indicates DHCP availability - * - * This is a suggestion. The underlying implementation is free to ignore it - * for security or other reasons. This is simply a netconf parameter that - * means 'DHCP is available on this network.' - */ - int dhcp; + /** + * If nonzero, the network this port belongs to indicates DHCP availability + * + * This is a suggestion. The underlying implementation is free to ignore it + * for security or other reasons. This is simply a netconf parameter that + * means 'DHCP is available on this network.' + */ + int dhcp; - /** - * If nonzero, this port is allowed to bridge to other networks - * - * This is informational. If this is false (0), bridged packets will simply - * be dropped and bridging won't work. - */ - int bridge; + /** + * If nonzero, this port is allowed to bridge to other networks + * + * This is informational. If this is false (0), bridged packets will simply + * be dropped and bridging won't work. + */ + int bridge; - /** - * If nonzero, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic - */ - int broadcastEnabled; + /** + * If nonzero, this network supports and allows broadcast (ff:ff:ff:ff:ff:ff) traffic + */ + int broadcastEnabled; - /** - * If the network is in PORT_ERROR state, this is the (negative) error code most recently reported - */ - int portError; + /** + * If the network is in PORT_ERROR state, this is the (negative) error code most recently reported + */ + int portError; - /** - * Revision number as reported by controller or 0 if still waiting for config - */ - unsigned long netconfRevision; + /** + * Revision number as reported by controller or 0 if still waiting for config + */ + unsigned long netconfRevision; - /** - * Number of assigned addresses - */ - unsigned int assignedAddressCount; + /** + * Number of assigned addresses + */ + unsigned int assignedAddressCount; - /** - * ZeroTier-assigned addresses (in sockaddr_storage structures) - * - * For IP, the port number of the sockaddr_XX structure contains the number - * of bits in the address netmask. Only the IP address and port are used. - * Other fields like interface number can be ignored. - * - * This is only used for ZeroTier-managed address assignments sent by the - * virtual network's configuration master. - */ - struct sockaddr_storage assignedAddresses[ZT_MAX_ZT_ASSIGNED_ADDRESSES]; + /** + * ZeroTier-assigned addresses (in sockaddr_storage structures) + * + * For IP, the port number of the sockaddr_XX structure contains the number + * of bits in the address netmask. Only the IP address and port are used. + * Other fields like interface number can be ignored. + * + * This is only used for ZeroTier-managed address assignments sent by the + * virtual network's configuration master. + */ + struct sockaddr_storage assignedAddresses[ZT_MAX_ZT_ASSIGNED_ADDRESSES]; - /** - * Number of ZT-pushed routes - */ - unsigned int routeCount; + /** + * Number of ZT-pushed routes + */ + unsigned int routeCount; - /** - * Routes (excluding those implied by assigned addresses and their masks) - */ - ZT_VirtualNetworkRoute routes[ZT_MAX_NETWORK_ROUTES]; + /** + * Routes (excluding those implied by assigned addresses and their masks) + */ + ZT_VirtualNetworkRoute routes[ZT_MAX_NETWORK_ROUTES]; - /** - * Number of multicast groups subscribed - */ - unsigned int multicastSubscriptionCount; + /** + * Number of multicast groups subscribed + */ + unsigned int multicastSubscriptionCount; - /** - * Multicast groups to which this network's device is subscribed - */ - struct { - uint64_t mac; /* MAC in lower 48 bits */ - uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */ - } multicastSubscriptions[ZT_MAX_MULTICAST_SUBSCRIPTIONS]; + /** + * Multicast groups to which this network's device is subscribed + */ + struct { + uint64_t mac; /* MAC in lower 48 bits */ + uint32_t adi; /* Additional distinguishing information, usually zero except for IPv4 ARP groups */ + } multicastSubscriptions[ZT_MAX_MULTICAST_SUBSCRIPTIONS]; - /** - * Network specific DNS configuration - */ - ZT_VirtualNetworkDNS dns; + /** + * Network specific DNS configuration + */ + ZT_VirtualNetworkDNS dns; + /** + * sso enabled + */ + bool ssoEnabled; + /** + * SSO version + */ + uint64_t ssoVersion; - /** - * sso enabled - */ - bool ssoEnabled; + /** + * If the status us AUTHENTICATION_REQUIRED, this may contain a URL for authentication. + */ + char authenticationURL[2048]; - /** - * SSO version - */ - uint64_t ssoVersion; + /** + * Time that current authentication expires. only valid if ssoEnabled is true + */ + uint64_t authenticationExpiryTime; - /** - * If the status us AUTHENTICATION_REQUIRED, this may contain a URL for authentication. - */ - char authenticationURL[2048]; + /** + * OIDC issuer URL. + */ + char issuerURL[2048]; - /** - * Time that current authentication expires. only valid if ssoEnabled is true - */ - uint64_t authenticationExpiryTime; + /** + * central base URL. + */ + char centralAuthURL[2048]; - /** - * OIDC issuer URL. - */ - char issuerURL[2048]; + /** + * sso nonce + */ + char ssoNonce[128]; - /** - * central base URL. - */ - char centralAuthURL[2048]; + /** + * sso state + */ + char ssoState[256]; - /** - * sso nonce - */ - char ssoNonce[128]; + /** + * oidc client id + */ + char ssoClientID[256]; - /** - * sso state - */ - char ssoState[256]; - - /** - * oidc client id - */ - char ssoClientID[256]; - - /** - * sso provider - **/ - char ssoProvider[64]; + /** + * sso provider + **/ + char ssoProvider[64]; } ZT_VirtualNetworkConfig; /** * A list of networks */ -typedef struct -{ - ZT_VirtualNetworkConfig *networks; - unsigned long networkCount; +typedef struct { + ZT_VirtualNetworkConfig* networks; + unsigned long networkCount; } ZT_VirtualNetworkList; /** * Physical path configuration */ typedef struct { - /** - * If non-zero set this physical network path to be trusted to disable encryption and authentication - */ - uint64_t trustedPathId; + /** + * If non-zero set this physical network path to be trusted to disable encryption and authentication + */ + uint64_t trustedPathId; - /** - * Physical path MTU from ZT_MIN_PHYSMTU and ZT_MAX_PHYSMTU or <= 0 to use default - */ - int mtu; + /** + * Physical path MTU from ZT_MIN_PHYSMTU and ZT_MAX_PHYSMTU or <= 0 to use default + */ + int mtu; } ZT_PhysicalPathConfiguration; /** * Physical network path to a peer */ -typedef struct -{ - /** - * Address of endpoint - */ - struct sockaddr_storage address; +typedef struct { + /** + * Address of endpoint + */ + struct sockaddr_storage address; - /** - * Time of last send in milliseconds or 0 for never - */ - uint64_t lastSend; + /** + * Time of last send in milliseconds or 0 for never + */ + uint64_t lastSend; - /** - * Time of last receive in milliseconds or 0 for never - */ - uint64_t lastReceive; + /** + * Time of last receive in milliseconds or 0 for never + */ + uint64_t lastReceive; - /** - * Is this a trusted path? If so this will be its nonzero ID. - */ - uint64_t trustedPathId; + /** + * Is this a trusted path? If so this will be its nonzero ID. + */ + uint64_t trustedPathId; - /** - * Mean latency - */ - float latencyMean; + /** + * Mean latency + */ + float latencyMean; - /** - * Maximum observed latency - */ - float latencyMax; + /** + * Maximum observed latency + */ + float latencyMax; - /** - * Variance of latency - */ - float latencyVariance; + /** + * Variance of latency + */ + float latencyVariance; - /** - * Packet loss ratio - */ - float packetLossRatio; + /** + * Packet loss ratio + */ + float packetLossRatio; - /** - * Packet error ratio - */ - float packetErrorRatio; + /** + * Packet error ratio + */ + float packetErrorRatio; - /** - * Number of flows assigned to this path - */ - uint16_t assignedFlowCount; + /** + * Number of flows assigned to this path + */ + uint16_t assignedFlowCount; - /** - * Address scope - */ - uint8_t scope; + /** + * Address scope + */ + uint8_t scope; - /** - * Relative quality value - */ - float relativeQuality; + /** + * Relative quality value + */ + float relativeQuality; - /** - * Name of physical interface this path resides on - */ - char ifname[ZT_MAX_PHYSIFNAME]; + /** + * Name of physical interface this path resides on + */ + char ifname[ZT_MAX_PHYSIFNAME]; - /** - * Pointer to PhySocket object for this path - */ - uint64_t localSocket; + /** + * Pointer to PhySocket object for this path + */ + uint64_t localSocket; - /** - * Local port corresponding to this path's localSocket - */ - uint16_t localPort; + /** + * Local port corresponding to this path's localSocket + */ + uint16_t localPort; - /** - * Is path expired? - */ - int expired; + /** + * Is path expired? + */ + int expired; - /** - * Whether this path is currently included in the bond - */ - uint8_t bonded; + /** + * Whether this path is currently included in the bond + */ + uint8_t bonded; - /** - * Whether this path is currently eligible to be used in a bond - */ - uint8_t eligible; + /** + * Whether this path is currently eligible to be used in a bond + */ + uint8_t eligible; - /** - * The capacity of this link (as given to bonding layer) - */ - uint32_t linkSpeed; + /** + * The capacity of this link (as given to bonding layer) + */ + uint32_t linkSpeed; - /** - * Is path preferred? - */ - int preferred; + /** + * Is path preferred? + */ + int preferred; } ZT_PeerPhysicalPath; /** * Peer status result buffer */ -typedef struct -{ - /** - * ZeroTier address (40 bits) - */ - uint64_t address; +typedef struct { + /** + * ZeroTier address (40 bits) + */ + uint64_t address; - /** - * Remote major version or -1 if not known - */ - int versionMajor; + /** + * Remote major version or -1 if not known + */ + int versionMajor; - /** - * Remote minor version or -1 if not known - */ - int versionMinor; + /** + * Remote minor version or -1 if not known + */ + int versionMinor; - /** - * Remote revision or -1 if not known - */ - int versionRev; + /** + * Remote revision or -1 if not known + */ + int versionRev; - /** - * Last measured latency in milliseconds or -1 if unknown - */ - int latency; + /** + * Last measured latency in milliseconds or -1 if unknown + */ + int latency; - /** - * What trust hierarchy role does this device have? - */ - enum ZT_PeerRole role; + /** + * What trust hierarchy role does this device have? + */ + enum ZT_PeerRole role; - /** - * Whether a multi-link bond has formed - */ - bool isBonded; + /** + * Whether a multi-link bond has formed + */ + bool isBonded; - /** - * The bonding policy used to bond to this peer - */ - int bondingPolicy; + /** + * The bonding policy used to bond to this peer + */ + int bondingPolicy; - /** - * The number of links that comprise the bond to this peer that are considered alive - */ - int numAliveLinks; + /** + * The number of links that comprise the bond to this peer that are considered alive + */ + int numAliveLinks; - /** - * The number of links that comprise the bond to this peer - */ - int numTotalLinks; + /** + * The number of links that comprise the bond to this peer + */ + int numTotalLinks; - /** - * The user-specified bond template name - */ - char customBondName[32]; + /** + * The user-specified bond template name + */ + char customBondName[32]; - /** - * Number of paths (size of paths[]) - */ - unsigned int pathCount; + /** + * Number of paths (size of paths[]) + */ + unsigned int pathCount; - /** - * Known network paths to peer - */ - ZT_PeerPhysicalPath paths[ZT_MAX_PEER_NETWORK_PATHS]; + /** + * Known network paths to peer + */ + ZT_PeerPhysicalPath paths[ZT_MAX_PEER_NETWORK_PATHS]; } ZT_Peer; /** * List of peers */ -typedef struct -{ - ZT_Peer *peers; - unsigned long peerCount; +typedef struct { + ZT_Peer* peers; + unsigned long peerCount; } ZT_PeerList; /** * ZeroTier core state objects */ -enum ZT_StateObjectType -{ - /** - * Null object -- ignored - */ - ZT_STATE_OBJECT_NULL = 0, +enum ZT_StateObjectType { + /** + * Null object -- ignored + */ + ZT_STATE_OBJECT_NULL = 0, - /** - * Public address and public key - * - * Object ID: this node's address if known, or 0 if unknown (first query) - * Canonical path: /identity.public - * Persistence: required - */ - ZT_STATE_OBJECT_IDENTITY_PUBLIC = 1, + /** + * Public address and public key + * + * Object ID: this node's address if known, or 0 if unknown (first query) + * Canonical path: /identity.public + * Persistence: required + */ + ZT_STATE_OBJECT_IDENTITY_PUBLIC = 1, - /** - * Full identity with secret key - * - * Object ID: this node's address if known, or 0 if unknown (first query) - * Canonical path: /identity.secret - * Persistence: required, should be stored with restricted permissions e.g. mode 0600 on *nix - */ - ZT_STATE_OBJECT_IDENTITY_SECRET = 2, + /** + * Full identity with secret key + * + * Object ID: this node's address if known, or 0 if unknown (first query) + * Canonical path: /identity.secret + * Persistence: required, should be stored with restricted permissions e.g. mode 0600 on *nix + */ + ZT_STATE_OBJECT_IDENTITY_SECRET = 2, - /** - * The planet (there is only one per... well... planet!) - * - * Object ID: world ID of planet, or 0 if unknown (first query) - * Canonical path: /planet - * Persistence: recommended - */ - ZT_STATE_OBJECT_PLANET = 3, + /** + * The planet (there is only one per... well... planet!) + * + * Object ID: world ID of planet, or 0 if unknown (first query) + * Canonical path: /planet + * Persistence: recommended + */ + ZT_STATE_OBJECT_PLANET = 3, - /** - * A moon (federated root set) - * - * Object ID: world ID of moon - * Canonical path: /moons.d/.moon (16-digit hex ID) - * Persistence: required if moon memberships should persist - */ - ZT_STATE_OBJECT_MOON = 4, + /** + * A moon (federated root set) + * + * Object ID: world ID of moon + * Canonical path: /moons.d/.moon (16-digit hex ID) + * Persistence: required if moon memberships should persist + */ + ZT_STATE_OBJECT_MOON = 4, - /** - * Peer and related state - * - * Object ID: peer address - * Canonical path: /peers.d/ (10-digit address - * Persistence: optional, can be cleared at any time - */ - ZT_STATE_OBJECT_PEER = 5, + /** + * Peer and related state + * + * Object ID: peer address + * Canonical path: /peers.d/ (10-digit address + * Persistence: optional, can be cleared at any time + */ + ZT_STATE_OBJECT_PEER = 5, - /** - * Network configuration - * - * Object ID: peer address - * Canonical path: /networks.d/.conf (16-digit hex ID) - * Persistence: required if network memberships should persist - */ - ZT_STATE_OBJECT_NETWORK_CONFIG = 6 + /** + * Network configuration + * + * Object ID: peer address + * Canonical path: /networks.d/.conf (16-digit hex ID) + * Persistence: required if network memberships should persist + */ + ZT_STATE_OBJECT_NETWORK_CONFIG = 6 }; /** @@ -1559,13 +1532,13 @@ typedef void ZT_Node; * PORT_ERROR state. */ typedef int (*ZT_VirtualNetworkConfigFunction)( - ZT_Node *, /* Node */ - void *, /* User ptr */ - void *, /* Thread ptr */ - uint64_t, /* Network ID */ - void **, /* Modifiable network user PTR */ - enum ZT_VirtualNetworkConfigOperation, /* Config operation */ - const ZT_VirtualNetworkConfig *); /* Network configuration */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + uint64_t, /* Network ID */ + void**, /* Modifiable network user PTR */ + enum ZT_VirtualNetworkConfigOperation, /* Config operation */ + const ZT_VirtualNetworkConfig*); /* Network configuration */ /** * Function to send a frame out to a virtual network port @@ -1575,17 +1548,17 @@ typedef int (*ZT_VirtualNetworkConfigFunction)( * (9) frame length. */ typedef void (*ZT_VirtualNetworkFrameFunction)( - ZT_Node *, /* Node */ - void *, /* User ptr */ - void *, /* Thread ptr */ - uint64_t, /* Network ID */ - void **, /* Modifiable network user PTR */ - uint64_t, /* Source MAC */ - uint64_t, /* Destination MAC */ - unsigned int, /* Ethernet type */ - unsigned int, /* VLAN ID (0 for none) */ - const void *, /* Frame data */ - unsigned int); /* Frame length */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + uint64_t, /* Network ID */ + void**, /* Modifiable network user PTR */ + uint64_t, /* Source MAC */ + uint64_t, /* Destination MAC */ + unsigned int, /* Ethernet type */ + unsigned int, /* VLAN ID (0 for none) */ + const void*, /* Frame data */ + unsigned int); /* Frame length */ /** * Callback for events @@ -1597,11 +1570,11 @@ typedef void (*ZT_VirtualNetworkFrameFunction)( * in the definition of ZT_Event. */ typedef void (*ZT_EventCallback)( - ZT_Node *, /* Node */ - void *, /* User ptr */ - void *, /* Thread ptr */ - enum ZT_Event, /* Event type */ - const void *); /* Event payload (if applicable) */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + enum ZT_Event, /* Event type */ + const void*); /* Event payload (if applicable) */ /** * Callback for storing and/or publishing state information @@ -1613,13 +1586,13 @@ typedef void (*ZT_EventCallback)( * deleted. */ typedef void (*ZT_StatePutFunction)( - ZT_Node *, /* Node */ - void *, /* User ptr */ - void *, /* Thread ptr */ - enum ZT_StateObjectType, /* State object type */ - const uint64_t [2], /* State object ID (if applicable) */ - const void *, /* State object data */ - int); /* Length of data or -1 to delete */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + enum ZT_StateObjectType, /* State object type */ + const uint64_t[2], /* State object ID (if applicable) */ + const void*, /* State object data */ + int); /* Length of data or -1 to delete */ /** * Callback for retrieving stored state information @@ -1629,13 +1602,13 @@ typedef void (*ZT_StatePutFunction)( * small to store it. */ typedef int (*ZT_StateGetFunction)( - ZT_Node *, /* Node */ - void *, /* User ptr */ - void *, /* Thread ptr */ - enum ZT_StateObjectType, /* State object type */ - const uint64_t [2], /* State object ID (if applicable) */ - void *, /* Buffer to store state object data */ - unsigned int); /* Length of data buffer in bytes */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + enum ZT_StateObjectType, /* State object type */ + const uint64_t[2], /* State object ID (if applicable) */ + void*, /* Buffer to store state object data */ + unsigned int); /* Length of data buffer in bytes */ /** * Function to send a ZeroTier packet out over the physical wire (L2/L3) @@ -1662,14 +1635,14 @@ typedef int (*ZT_StateGetFunction)( * delivery. It only means that the packet appears to have been sent. */ typedef int (*ZT_WirePacketSendFunction)( - ZT_Node *, /* Node */ - void *, /* User ptr */ - void *, /* Thread ptr */ - int64_t, /* Local socket */ - const struct sockaddr_storage *, /* Remote address */ - const void *, /* Packet data */ - unsigned int, /* Packet length */ - unsigned int); /* TTL or 0 to use default */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + int64_t, /* Local socket */ + const struct sockaddr_storage*, /* Remote address */ + const void*, /* Packet data */ + unsigned int, /* Packet length */ + unsigned int); /* TTL or 0 to use default */ /** * Function to check whether a path should be used for ZeroTier traffic @@ -1693,12 +1666,12 @@ typedef int (*ZT_WirePacketSendFunction)( * interface (recursion). */ typedef int (*ZT_PathCheckFunction)( - ZT_Node *, /* Node */ - void *, /* User ptr */ - void *, /* Thread ptr */ - uint64_t, /* ZeroTier address */ - int64_t, /* Local socket or -1 if unknown */ - const struct sockaddr_storage *); /* Remote address */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + uint64_t, /* ZeroTier address */ + int64_t, /* Local socket or -1 if unknown */ + const struct sockaddr_storage*); /* Remote address */ /** * Function to get physical addresses for ZeroTier peers @@ -1716,12 +1689,12 @@ typedef int (*ZT_PathCheckFunction)( * with an address. */ typedef int (*ZT_PathLookupFunction)( - ZT_Node *, /* Node */ - void *, /* User ptr */ - void *, /* Thread ptr */ - uint64_t, /* ZeroTier address (40 bits) */ - int, /* Desired ss_family or -1 for any */ - struct sockaddr_storage *); /* Result buffer */ + ZT_Node*, /* Node */ + void*, /* User ptr */ + void*, /* Thread ptr */ + uint64_t, /* ZeroTier address (40 bits) */ + int, /* Desired ss_family or -1 for any */ + struct sockaddr_storage*); /* Result buffer */ /****************************************************************************/ /* C Node API */ @@ -1730,52 +1703,51 @@ typedef int (*ZT_PathLookupFunction)( /** * Structure for configuring ZeroTier core callback functions */ -struct ZT_Node_Callbacks -{ - /** - * Struct version -- must currently be 0 - */ - long version; +struct ZT_Node_Callbacks { + /** + * Struct version -- must currently be 0 + */ + long version; - /** - * REQUIRED: Function to store and/or replicate state objects - */ - ZT_StatePutFunction statePutFunction; + /** + * REQUIRED: Function to store and/or replicate state objects + */ + ZT_StatePutFunction statePutFunction; - /** - * REQUIRED: Function to retrieve state objects from an object store - */ - ZT_StateGetFunction stateGetFunction; + /** + * REQUIRED: Function to retrieve state objects from an object store + */ + ZT_StateGetFunction stateGetFunction; - /** - * REQUIRED: Function to send packets over the physical wire - */ - ZT_WirePacketSendFunction wirePacketSendFunction; + /** + * REQUIRED: Function to send packets over the physical wire + */ + ZT_WirePacketSendFunction wirePacketSendFunction; - /** - * REQUIRED: Function to inject frames into a virtual network's TAP - */ - ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction; + /** + * REQUIRED: Function to inject frames into a virtual network's TAP + */ + ZT_VirtualNetworkFrameFunction virtualNetworkFrameFunction; - /** - * REQUIRED: Function to be called when virtual networks are configured or changed - */ - ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction; + /** + * REQUIRED: Function to be called when virtual networks are configured or changed + */ + ZT_VirtualNetworkConfigFunction virtualNetworkConfigFunction; - /** - * REQUIRED: Function to be called to notify external code of important events - */ - ZT_EventCallback eventCallback; + /** + * REQUIRED: Function to be called to notify external code of important events + */ + ZT_EventCallback eventCallback; - /** - * OPTIONAL: Function to check whether a given physical path should be used - */ - ZT_PathCheckFunction pathCheckFunction; + /** + * OPTIONAL: Function to check whether a given physical path should be used + */ + ZT_PathCheckFunction pathCheckFunction; - /** - * OPTIONAL: Function to get hints to physical paths to ZeroTier addresses - */ - ZT_PathLookupFunction pathLookupFunction; + /** + * OPTIONAL: Function to get hints to physical paths to ZeroTier addresses + */ + ZT_PathLookupFunction pathLookupFunction; }; /** @@ -1793,7 +1765,7 @@ struct ZT_Node_Callbacks * @param now Current clock in milliseconds * @return OK (0) or error code if a fatal error condition has occurred */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,void *tptr,const struct ZT_Node_Callbacks *callbacks,int64_t now); +ZT_SDK_API enum ZT_ResultCode ZT_Node_new(ZT_Node** node, void* uptr, void* tptr, const struct ZT_Node_Callbacks* callbacks, int64_t now); /** * Delete a node and free all resources it consumes @@ -1803,7 +1775,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_new(ZT_Node **node,void *uptr,void *tptr,c * * @param node Node to delete */ -ZT_SDK_API void ZT_Node_delete(ZT_Node *node); +ZT_SDK_API void ZT_Node_delete(ZT_Node* node); /** * Process a packet received from the physical wire @@ -1818,15 +1790,8 @@ ZT_SDK_API void ZT_Node_delete(ZT_Node *node); * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks() * @return OK (0) or error code if a fatal error condition has occurred */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_processWirePacket( - ZT_Node *node, - void *tptr, - int64_t now, - int64_t localSocket, - const struct sockaddr_storage *remoteAddress, - const void *packetData, - unsigned int packetLength, - volatile int64_t *nextBackgroundTaskDeadline); +ZT_SDK_API enum ZT_ResultCode +ZT_Node_processWirePacket(ZT_Node* node, void* tptr, int64_t now, int64_t localSocket, const struct sockaddr_storage* remoteAddress, const void* packetData, unsigned int packetLength, volatile int64_t* nextBackgroundTaskDeadline); /** * Process a frame from a virtual network port (tap) @@ -1845,17 +1810,17 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processWirePacket( * @return OK (0) or error code if a fatal error condition has occurred */ ZT_SDK_API enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame( - ZT_Node *node, - void *tptr, - int64_t now, - uint64_t nwid, - uint64_t sourceMac, - uint64_t destMac, - unsigned int etherType, - unsigned int vlanId, - const void *frameData, - unsigned int frameLength, - volatile int64_t *nextBackgroundTaskDeadline); + ZT_Node* node, + void* tptr, + int64_t now, + uint64_t nwid, + uint64_t sourceMac, + uint64_t destMac, + unsigned int etherType, + unsigned int vlanId, + const void* frameData, + unsigned int frameLength, + volatile int64_t* nextBackgroundTaskDeadline); /** * Perform periodic background operations @@ -1866,7 +1831,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame( * @param nextBackgroundTaskDeadline Value/result: set to deadline for next call to processBackgroundTasks() * @return OK (0) or error code if a fatal error condition has occurred */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,void *tptr,int64_t now,volatile int64_t *nextBackgroundTaskDeadline); +ZT_SDK_API enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node* node, void* tptr, int64_t now, volatile int64_t* nextBackgroundTaskDeadline); /** * Join a network @@ -1882,7 +1847,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node,void * @param uptr An arbitrary pointer to associate with this network (default: NULL) * @return OK (0) or error code if a fatal error condition has occurred */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *uptr,void *tptr); +ZT_SDK_API enum ZT_ResultCode ZT_Node_join(ZT_Node* node, uint64_t nwid, void* uptr, void* tptr); /** * Leave a network @@ -1899,7 +1864,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_join(ZT_Node *node,uint64_t nwid,void *upt * @param uptr Target pointer is set to uptr (if not NULL) * @return OK (0) or error code if a fatal error condition has occurred */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **uptr,void *tptr); +ZT_SDK_API enum ZT_ResultCode ZT_Node_leave(ZT_Node* node, uint64_t nwid, void** uptr, void* tptr); /** * Subscribe to an Ethernet multicast group @@ -1927,7 +1892,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_leave(ZT_Node *node,uint64_t nwid,void **u * @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed) * @return OK (0) or error code if a fatal error condition has occurred */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,void *tptr,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); +ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node* node, void* tptr, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi); /** * Unsubscribe from an Ethernet multicast group (or all groups) @@ -1943,7 +1908,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node,void *tpt * @param multicastAdi Multicast ADI (least significant 32 bits only, use 0 if not needed) * @return OK (0) or error code if a fatal error condition has occurred */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi); +ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node* node, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi); /** * Add or update a moon @@ -1959,7 +1924,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node,uint64_ * @param len Length of moonWorld in bytes * @return Error if moon was invalid or failed to be added */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,void *tptr,uint64_t moonWorldId,uint64_t moonSeed); +ZT_SDK_API enum ZT_ResultCode ZT_Node_orbit(ZT_Node* node, void* tptr, uint64_t moonWorldId, uint64_t moonSeed); /** * Remove a moon (does nothing if not present) @@ -1969,7 +1934,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_orbit(ZT_Node *node,void *tptr,uint64_t mo * @param moonWorldId World ID of moon to remove * @return Error if anything bad happened */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t moonWorldId); +ZT_SDK_API enum ZT_ResultCode ZT_Node_deorbit(ZT_Node* node, void* tptr, uint64_t moonWorldId); /** * Get this node's 40-bit ZeroTier address @@ -1977,7 +1942,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_deorbit(ZT_Node *node,void *tptr,uint64_t * @param node Node instance * @return ZeroTier address (least significant 40 bits of 64-bit int) */ -ZT_SDK_API uint64_t ZT_Node_address(ZT_Node *node); +ZT_SDK_API uint64_t ZT_Node_address(ZT_Node* node); /** * Get the status of this node @@ -1985,7 +1950,7 @@ ZT_SDK_API uint64_t ZT_Node_address(ZT_Node *node); * @param node Node instance * @param status Buffer to fill with current node status */ -ZT_SDK_API void ZT_Node_status(ZT_Node *node,ZT_NodeStatus *status); +ZT_SDK_API void ZT_Node_status(ZT_Node* node, ZT_NodeStatus* status); /** * Get a list of known peer nodes @@ -1996,7 +1961,7 @@ ZT_SDK_API void ZT_Node_status(ZT_Node *node,ZT_NodeStatus *status); * @param node Node instance * @return List of known peers or NULL on failure */ -ZT_SDK_API ZT_PeerList *ZT_Node_peers(ZT_Node *node); +ZT_SDK_API ZT_PeerList* ZT_Node_peers(ZT_Node* node); /** * Get the status of a virtual network @@ -2008,7 +1973,7 @@ ZT_SDK_API ZT_PeerList *ZT_Node_peers(ZT_Node *node); * @param nwid 64-bit network ID * @return Network configuration or NULL if we are not a member of this network */ -ZT_SDK_API ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node,uint64_t nwid); +ZT_SDK_API ZT_VirtualNetworkConfig* ZT_Node_networkConfig(ZT_Node* node, uint64_t nwid); /** * Enumerate and get status of all networks @@ -2016,7 +1981,7 @@ ZT_SDK_API ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node,uint64_t * @param node Node instance * @return List of networks or NULL on failure */ -ZT_SDK_API ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node); +ZT_SDK_API ZT_VirtualNetworkList* ZT_Node_networks(ZT_Node* node); /** * Free a query result buffer @@ -2026,7 +1991,7 @@ ZT_SDK_API ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node); * @param node Node instance * @param qr Query result buffer */ -ZT_SDK_API void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); +ZT_SDK_API void ZT_Node_freeQueryResult(ZT_Node* node, void* qr); /** * Add a local interface address @@ -2050,12 +2015,12 @@ ZT_SDK_API void ZT_Node_freeQueryResult(ZT_Node *node,void *qr); * @param addr Local interface address * @return Boolean: non-zero if address was accepted and added */ -ZT_SDK_API int ZT_Node_addLocalInterfaceAddress(ZT_Node *node,const struct sockaddr_storage *addr); +ZT_SDK_API int ZT_Node_addLocalInterfaceAddress(ZT_Node* node, const struct sockaddr_storage* addr); /** * Clear local interface addresses */ -ZT_SDK_API void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node); +ZT_SDK_API void ZT_Node_clearLocalInterfaceAddresses(ZT_Node* node); /** * Send a VERB_USER_MESSAGE to another ZeroTier node @@ -2071,7 +2036,7 @@ ZT_SDK_API void ZT_Node_clearLocalInterfaceAddresses(ZT_Node *node); * @param len Length of data in bytes * @return Boolean: non-zero on success, zero on failure */ -ZT_SDK_API int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,uint64_t typeId,const void *data,unsigned int len); +ZT_SDK_API int ZT_Node_sendUserMessage(ZT_Node* node, void* tptr, uint64_t dest, uint64_t typeId, const void* data, unsigned int len); /** * Set a network configuration master instance for this node @@ -2088,7 +2053,7 @@ ZT_SDK_API int ZT_Node_sendUserMessage(ZT_Node *node,void *tptr,uint64_t dest,ui * @param networkConfigMasterInstance Instance of NetworkConfigMaster C++ class or NULL to disable * @return OK (0) or error code if a fatal error condition has occurred */ -ZT_SDK_API void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkConfigMasterInstance); +ZT_SDK_API void ZT_Node_setNetconfMaster(ZT_Node* node, void* networkConfigMasterInstance); /** * Set configuration for a given physical path @@ -2098,7 +2063,7 @@ ZT_SDK_API void ZT_Node_setNetconfMaster(ZT_Node *node,void *networkConfigMaster * @param pathConfig Path configuration or NULL to erase this entry and therefore reset it to NULL * @return OK or error code */ -ZT_SDK_API enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node *node,const struct sockaddr_storage *pathNetwork,const ZT_PhysicalPathConfiguration *pathConfig); +ZT_SDK_API enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node* node, const struct sockaddr_storage* pathNetwork, const ZT_PhysicalPathConfiguration* pathConfig); /** * Get ZeroTier One version @@ -2107,7 +2072,7 @@ ZT_SDK_API enum ZT_ResultCode ZT_Node_setPhysicalPathConfiguration(ZT_Node *node * @param minor Result: minor version * @param revision Result: revision */ -ZT_SDK_API void ZT_version(int *major,int *minor,int *revision); +ZT_SDK_API void ZT_version(int* major, int* minor, int* revision); #ifdef __cplusplus } diff --git a/make-mac.mk b/make-mac.mk index bc1940723..b8a9d6db9 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -83,7 +83,7 @@ ifeq ($(ZT_DEBUG),1) # C25519 in particular is almost UNUSABLE in heavy testing without it. node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -O2 -g $(INCLUDES) $(DEFS) else - CFLAGS?=-Ofast -fstack-protector-strong + CFLAGS?=-O3 -fstack-protector-strong CFLAGS+=$(ARCH_FLAGS) -Wall -flto -fPIE -mmacosx-version-min=$(MACOS_VERSION_MIN) -DNDEBUG -Wno-unused-private-field $(INCLUDES) $(DEFS) STRIP=strip EXTRA_CARGO_FLAGS=--release @@ -109,7 +109,7 @@ ext/x64-salsa2012-asm/salsa2012.o: as -arch x86_64 -mmacosx-version-min=$(MACOS_VERSION_MIN) -o ext/x64-salsa2012-asm/salsa2012.o ext/x64-salsa2012-asm/salsa2012.s mac-agent: FORCE - $(CC) -Ofast $(ARCH_FLAGS) -mmacosx-version-min=$(MACOS_VERSION_MIN) -o MacEthernetTapAgent osdep/MacEthernetTapAgent.c + $(CC) -O3 $(ARCH_FLAGS) -mmacosx-version-min=$(MACOS_VERSION_MIN) -o MacEthernetTapAgent osdep/MacEthernetTapAgent.c $(CODESIGN) -f --options=runtime -s $(CODESIGN_APP_CERT) MacEthernetTapAgent osdep/MacDNSHelper.o: osdep/MacDNSHelper.mm diff --git a/node/Bond.cpp b/node/Bond.cpp index 171fc165f..647633342 100644 --- a/node/Bond.cpp +++ b/node/Bond.cpp @@ -854,7 +854,7 @@ void Bond::sendPATH_NEGOTIATION_REQUEST(void* tPtr, int pathIdx) outp.append(_localUtility); if (_paths[pathIdx].p->address()) { Metrics::pkt_path_negotiation_request_out++; - outp.armor(_peer->key(), false, _peer->aesKeysIfSupported()); + outp.armor(_peer->key(), true, false, _peer->aesKeysIfSupported(), _peer->identity()); RR->node->putPacket(tPtr, _paths[pathIdx].p->localSocket(), _paths[pathIdx].p->address(), outp.data(), outp.size()); _overheadBytes += outp.size(); } @@ -895,7 +895,7 @@ void Bond::sendQOS_MEASUREMENT(void* tPtr, int pathIdx, int64_t localSocket, con // debug("sending QOS via link %s (len=%d)", pathToStr(_paths[pathIdx].p).c_str(), len); outp.append(qosData, len); if (atAddress) { - outp.armor(_peer->key(), false, _peer->aesKeysIfSupported()); + outp.armor(_peer->key(), true, false, _peer->aesKeysIfSupported(), _peer->identity()); RR->node->putPacket(tPtr, localSocket, atAddress, outp.data(), outp.size()); } else { @@ -933,7 +933,7 @@ void Bond::processBackgroundBondTasks(void* tPtr, int64_t now) if ((_monitorInterval > 0) && (((now - _paths[i].p->_lastIn) >= (_paths[i].alive ? _monitorInterval : _failoverInterval)))) { if ((_peer->remoteVersionProtocol() >= 5) && (! ((_peer->remoteVersionMajor() == 1) && (_peer->remoteVersionMinor() == 1) && (_peer->remoteVersionRevision() == 0)))) { Packet outp(_peer->address(), RR->identity.address(), Packet::VERB_ECHO); // ECHO (this is our bond's heartbeat) - outp.armor(_peer->key(), true, _peer->aesKeysIfSupported()); + outp.armor(_peer->key(), true, false, _peer->aesKeysIfSupported(), _peer->identity()); RR->node->expectReplyTo(outp.packetId()); RR->node->putPacket(tPtr, _paths[i].p->localSocket(), _paths[i].p->address(), outp.data(), outp.size()); _paths[i].p->_lastOut = now; @@ -1751,11 +1751,10 @@ void Bond::processActiveBackupTasks(void* tPtr, int64_t now) } } // Sort queue based on performance - std::sort(_abFailoverQueue.begin(), _abFailoverQueue.end(), - [this](const int a, const int b) { - // Sort by failover score in descending order (highest score first) - return _paths[a].failoverScore > _paths[b].failoverScore; - }); + std::sort(_abFailoverQueue.begin(), _abFailoverQueue.end(), [this](const int a, const int b) { + // Sort by failover score in descending order (highest score first) + return _paths[a].failoverScore > _paths[b].failoverScore; + }); /** * Short-circuit if we have no queued paths diff --git a/node/Capability.hpp b/node/Capability.hpp index 798f09e48..b22380c5d 100644 --- a/node/Capability.hpp +++ b/node/Capability.hpp @@ -17,9 +17,9 @@ #include "../include/ZeroTierOne.h" #include "Address.hpp" #include "Buffer.hpp" -#include "C25519.hpp" #include "Constants.hpp" #include "Credential.hpp" +#include "ECC.hpp" #include "Identity.hpp" #include "Utils.hpp" @@ -413,9 +413,9 @@ class Capability : public Credential { if ((i < _maxCustodyChainLength) && (i < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) && (_custody[i].to)) { _custody[i].to.appendTo(b); _custody[i].from.appendTo(b); - b.append((uint8_t)1); // 1 == Ed25519 signature - b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); // length of signature - b.append(_custody[i].signature.data, ZT_C25519_SIGNATURE_LEN); + b.append((uint8_t)1); // 1 == Ed25519 signature + b.append((uint16_t)ZT_ECC_SIGNATURE_LEN); // length of signature + b.append(_custody[i].signature.data, ZT_ECC_SIGNATURE_LEN); } else { b.append((unsigned char)0, ZT_ADDRESS_LENGTH); // zero 'to' terminates chain @@ -470,12 +470,12 @@ class Capability : public Credential { _custody[i].from.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; if (b[p++] == 1) { - if (b.template at(p) != ZT_C25519_SIGNATURE_LEN) { + if (b.template at(p) != ZT_ECC_SIGNATURE_LEN) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } p += 2; - memcpy(_custody[i].signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); - p += ZT_C25519_SIGNATURE_LEN; + memcpy(_custody[i].signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN); + p += ZT_ECC_SIGNATURE_LEN; } else { p += 2 + b.template at(p); @@ -518,7 +518,7 @@ class Capability : public Credential { struct { Address to; Address from; - C25519::Signature signature; + ECC::Signature signature; } _custody[ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH]; }; diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp index b1dcafcfd..5a00c8eab 100644 --- a/node/CertificateOfMembership.cpp +++ b/node/CertificateOfMembership.cpp @@ -13,6 +13,7 @@ #include "CertificateOfMembership.hpp" +#include "ECC.hpp" #include "Network.hpp" #include "Node.hpp" #include "RuntimeEnvironment.hpp" @@ -44,7 +45,7 @@ CertificateOfMembership::CertificateOfMembership(uint64_t timestamp, uint64_t ti } _qualifierCount = 7; - memset(_signature.data, 0, ZT_C25519_SIGNATURE_LEN); + memset(_signature.data, 0, ZT_ECC_SIGNATURE_LEN); } bool CertificateOfMembership::agreesWith(const CertificateOfMembership& other, const Identity& otherIdentity) const diff --git a/node/CertificateOfMembership.hpp b/node/CertificateOfMembership.hpp index 70c9570ff..c5a3c6a7a 100644 --- a/node/CertificateOfMembership.hpp +++ b/node/CertificateOfMembership.hpp @@ -16,9 +16,9 @@ #include "Address.hpp" #include "Buffer.hpp" -#include "C25519.hpp" #include "Constants.hpp" #include "Credential.hpp" +#include "ECC.hpp" #include "Identity.hpp" #include "Utils.hpp" @@ -241,7 +241,7 @@ class CertificateOfMembership : public Credential { } _signedBy.appendTo(b); if (_signedBy) { - b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); + b.append(_signature.data, ZT_ECC_SIGNATURE_LEN); } } @@ -283,8 +283,8 @@ class CertificateOfMembership : public Credential { p += ZT_ADDRESS_LENGTH; if (_signedBy) { - memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); - p += ZT_C25519_SIGNATURE_LEN; + memcpy(_signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN); + p += ZT_ECC_SIGNATURE_LEN; } return (p - startAt); @@ -305,7 +305,7 @@ class CertificateOfMembership : public Credential { return false; } } - return (memcmp(_signature.data, c._signature.data, ZT_C25519_SIGNATURE_LEN) == 0); + return (memcmp(_signature.data, c._signature.data, ZT_ECC_SIGNATURE_LEN) == 0); } inline bool operator!=(const CertificateOfMembership& c) const { @@ -329,7 +329,7 @@ class CertificateOfMembership : public Credential { Address _signedBy; _Qualifier _qualifiers[ZT_NETWORK_COM_MAX_QUALIFIERS]; unsigned int _qualifierCount; - C25519::Signature _signature; + ECC::Signature _signature; }; } // namespace ZeroTier diff --git a/node/CertificateOfOwnership.hpp b/node/CertificateOfOwnership.hpp index aa18e188d..3e2f5b926 100644 --- a/node/CertificateOfOwnership.hpp +++ b/node/CertificateOfOwnership.hpp @@ -16,9 +16,9 @@ #include "Address.hpp" #include "Buffer.hpp" -#include "C25519.hpp" #include "Constants.hpp" #include "Credential.hpp" +#include "ECC.hpp" #include "Identity.hpp" #include "InetAddress.hpp" #include "MAC.hpp" @@ -182,9 +182,9 @@ class CertificateOfOwnership : public Credential { _issuedTo.appendTo(b); _signedBy.appendTo(b); if (! forSign) { - b.append((uint8_t)1); // 1 == Ed25519 - b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); // length of signature - b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); + b.append((uint8_t)1); // 1 == Ed25519 + b.append((uint16_t)ZT_ECC_SIGNATURE_LEN); // length of signature + b.append(_signature.data, ZT_ECC_SIGNATURE_LEN); } b.append((uint16_t)0); // length of additional fields, currently 0 @@ -223,12 +223,12 @@ class CertificateOfOwnership : public Credential { _signedBy.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; if (b[p++] == 1) { - if (b.template at(p) != ZT_C25519_SIGNATURE_LEN) { + if (b.template at(p) != ZT_ECC_SIGNATURE_LEN) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } p += 2; - memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); - p += ZT_C25519_SIGNATURE_LEN; + memcpy(_signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN); + p += ZT_ECC_SIGNATURE_LEN; } else { p += 2 + b.template at(p); @@ -269,7 +269,7 @@ class CertificateOfOwnership : public Credential { uint8_t _thingValues[ZT_CERTIFICATEOFOWNERSHIP_MAX_THINGS][ZT_CERTIFICATEOFOWNERSHIP_MAX_THING_VALUE_SIZE]; Address _issuedTo; Address _signedBy; - C25519::Signature _signature; + ECC::Signature _signature; }; } // namespace ZeroTier diff --git a/node/Credential.hpp b/node/Credential.hpp index d1300a78b..3f290cadf 100644 --- a/node/Credential.hpp +++ b/node/Credential.hpp @@ -14,16 +14,6 @@ #ifndef ZT_CREDENTIAL_HPP #define ZT_CREDENTIAL_HPP -#include "Constants.hpp" - -#include -#include -#include -#include -#include -#include -#include - namespace ZeroTier { /** diff --git a/node/C25519.cpp b/node/ECC.cpp similarity index 99% rename from node/C25519.cpp rename to node/ECC.cpp index 77ff9dc5a..ad5a2537a 100644 --- a/node/C25519.cpp +++ b/node/ECC.cpp @@ -7,16 +7,11 @@ Derived from public domain code by D. J. Bernstein. // Modified very slightly for ZeroTier One by Adam Ierymenko // This code remains in the public domain. -#include "C25519.hpp" +#include "ECC.hpp" -#include "Buffer.hpp" -#include "Constants.hpp" -#include "Hashtable.hpp" -#include "Mutex.hpp" #include "SHA512.hpp" #include -#include #include #ifdef __WINDOWS__ @@ -2452,7 +2447,7 @@ extern "C" void ed25519_amd64_asm_sign(const unsigned char* sk, const unsigned c namespace ZeroTier { -void C25519::agree(const C25519::Private& mine, const C25519::Public& their, void* keybuf, unsigned int keylen) +void ECC::agree(const ECC::Private& mine, const ECC::Public& their, void* keybuf, unsigned int keylen) { unsigned char rawkey[32]; unsigned char digest[64]; @@ -2468,7 +2463,7 @@ void C25519::agree(const C25519::Private& mine, const C25519::Public& their, voi } } -void C25519::sign(const C25519::Private& myPrivate, const C25519::Public& myPublic, const void* msg, unsigned int len, void* signature) +void ECC::sign(const ECC::Private& myPrivate, const ECC::Public& myPublic, const void* msg, unsigned int len, void* signature) { unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg) SHA512(digest, msg, len); @@ -2524,7 +2519,7 @@ void C25519::sign(const C25519::Private& myPrivate, const C25519::Public& myPubl #endif } -bool C25519::verify(const C25519::Public& their, const void* msg, unsigned int len, const void* signature) +bool ECC::verify(const ECC::Public& their, const void* msg, unsigned int len, const void* signature) { const unsigned char* const sig = (const unsigned char*)signature; unsigned char digest[64]; // we sign the first 32 bytes of SHA-512(msg) @@ -2555,14 +2550,14 @@ bool C25519::verify(const C25519::Public& their, const void* msg, unsigned int l return Utils::secureEq(sig, t2, 32); } -void C25519::_calcPubDH(C25519::Pair& kp) +void ECC::_calcPubDH(ECC::Pair& kp) { // First 32 bytes of pub and priv are the keys for ECDH key // agreement. This generates the public portion from the private. crypto_scalarmult_base(kp.pub.data, kp.priv.data); } -void C25519::_calcPubED(C25519::Pair& kp) +void ECC::_calcPubED(ECC::Pair& kp) { unsigned char extsk[64]; sc25519 scsk; diff --git a/node/C25519.hpp b/node/ECC.hpp similarity index 72% rename from node/C25519.hpp rename to node/ECC.hpp index aaccb07ee..68f6d5ea8 100644 --- a/node/C25519.hpp +++ b/node/ECC.hpp @@ -11,30 +11,71 @@ */ /****/ -#ifndef ZT_C25519_HPP -#define ZT_C25519_HPP +/* + * This file defines the elliptic curve crypto used for ZeroTier V1. The normal + * public version uses C25519 and Ed25519, while the FIPS version uses NIST. + * FIPS builds are completely incompatible with regular ZeroTier, but that's + * fine since FIPS users typically want a fully isolated private network. If you + * are not such a user you probably don't want this. + */ + +#ifndef ZT_ECC_HPP +#define ZT_ECC_HPP #include "Utils.hpp" -namespace ZeroTier { +#ifdef ZT_FIPS -#define ZT_C25519_PUBLIC_KEY_LEN 64 -#define ZT_C25519_PRIVATE_KEY_LEN 64 -#define ZT_C25519_SIGNATURE_LEN 96 +/* FIPS140/NIST ECC cryptography */ +/* Note that to be FIPS we also need to link against a FIPS-certified library. */ -/** - * A combined Curve25519 ECDH and Ed25519 signature engine - */ -class C25519 { +#include +#include +#include +#include +#include + +#define ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN 97 /* Single ECC P-384 key */ +#define ZT_ECC_PUBLIC_KEY_SET_LEN (97 * 2) /* Two ECC P-384 keys */ +#define ZT_ECC_PRIVATE_KEY_SET_LEN (48 * 2) /* Two ECC P-384 secret keys */ +#define ZT_ECC_SIGNATURE_LEN 96 /* NIST P-384 ECDSA signature */ + +class ECC { public: struct Public { - uint8_t data[ZT_C25519_PUBLIC_KEY_LEN]; + uint8_t data[ZT_ECC_PUBLIC_KEY_SET_LEN]; }; struct Private { - uint8_t data[ZT_C25519_PRIVATE_KEY_LEN]; + uint8_t data[ZT_ECC_PRIVATE_KEY_SET_LEN]; }; struct Signature { - uint8_t data[ZT_C25519_SIGNATURE_LEN]; + uint8_t data[ZT_ECC_SIGNATURE_LEN]; + }; + struct Pair { + Public pub; + Private priv; + }; +}; + +#else // Curve25519 / Ed25519 + +namespace ZeroTier { + +#define ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN 32 /* Single C25519 ECDH key */ +#define ZT_ECC_PUBLIC_KEY_SET_LEN 64 /* C25519 and Ed25519 keys */ +#define ZT_ECC_PRIVATE_KEY_SET_LEN 64 /* C25519 and Ed25519 secret keys */ +#define ZT_ECC_SIGNATURE_LEN 96 /* Ed25519 signature plus (not necessary) hash */ + +class ECC { + public: + struct Public { + uint8_t data[ZT_ECC_PUBLIC_KEY_SET_LEN]; + }; + struct Private { + uint8_t data[ZT_ECC_PRIVATE_KEY_SET_LEN]; + }; + struct Signature { + uint8_t data[ZT_ECC_SIGNATURE_LEN]; }; struct Pair { Public pub; @@ -42,12 +83,12 @@ class C25519 { }; /** - * Generate a C25519 elliptic curve key pair + * Generate an elliptic curve key pair */ static inline Pair generate() { Pair kp; - Utils::getSecureRandom(kp.priv.data, ZT_C25519_PRIVATE_KEY_LEN); + Utils::getSecureRandom(kp.priv.data, ZT_ECC_PRIVATE_KEY_SET_LEN); _calcPubDH(kp); _calcPubED(kp); return kp; @@ -70,7 +111,7 @@ class C25519 { { Pair kp; void* const priv = (void*)kp.priv.data; - Utils::getSecureRandom(priv, ZT_C25519_PRIVATE_KEY_LEN); + Utils::getSecureRandom(priv, ZT_ECC_PRIVATE_KEY_SET_LEN); _calcPubED(kp); // do Ed25519 key -- bytes 32-63 of pub and priv do { ++(((uint64_t*)priv)[1]); @@ -182,3 +223,5 @@ class C25519 { } // namespace ZeroTier #endif + +#endif diff --git a/node/Identity.cpp b/node/Identity.cpp index 8105d2a58..1e6d4212d 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -14,6 +14,7 @@ #include "Identity.hpp" #include "Constants.hpp" +#include "ECC.hpp" #include "SHA512.hpp" #include "Salsa20.hpp" #include "Utils.hpp" @@ -76,9 +77,9 @@ struct _Identity_generate_cond { _Identity_generate_cond(unsigned char* sb, char* gm) : digest(sb), genmem(gm) { } - inline bool operator()(const C25519::Pair& kp) const + inline bool operator()(const ECC::Pair& kp) const { - _computeMemoryHardHash(kp.pub.data, ZT_C25519_PUBLIC_KEY_LEN, digest, genmem); + _computeMemoryHardHash(kp.pub.data, ZT_ECC_PUBLIC_KEY_SET_LEN, digest, genmem); return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN); } unsigned char* digest; @@ -90,15 +91,15 @@ void Identity::generate() unsigned char digest[64]; char* genmem = new char[ZT_IDENTITY_GEN_MEMORY]; - C25519::Pair kp; + ECC::Pair kp; do { - kp = C25519::generateSatisfying(_Identity_generate_cond(digest, genmem)); + kp = ECC::generateSatisfying(_Identity_generate_cond(digest, genmem)); _address.setTo(digest + 59, ZT_ADDRESS_LENGTH); // last 5 bytes are address } while (_address.isReserved()); _publicKey = kp.pub; if (! _privateKey) { - _privateKey = new C25519::Private(); + _privateKey = new ECC::Private(); } *_privateKey = kp.priv; @@ -113,7 +114,7 @@ bool Identity::locallyValidate() const unsigned char digest[64]; char* genmem = new char[ZT_IDENTITY_GEN_MEMORY]; - _computeMemoryHardHash(_publicKey.data, ZT_C25519_PUBLIC_KEY_LEN, digest, genmem); + _computeMemoryHardHash(_publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN, digest, genmem); delete[] genmem; unsigned char addrb[5]; @@ -130,12 +131,12 @@ char* Identity::toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER *(p++) = ':'; *(p++) = '0'; *(p++) = ':'; - Utils::hex(_publicKey.data, ZT_C25519_PUBLIC_KEY_LEN, p); - p += ZT_C25519_PUBLIC_KEY_LEN * 2; + Utils::hex(_publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN, p); + p += ZT_ECC_PUBLIC_KEY_SET_LEN * 2; if ((_privateKey) && (includePrivate)) { *(p++) = ':'; - Utils::hex(_privateKey->data, ZT_C25519_PRIVATE_KEY_LEN, p); - p += ZT_C25519_PRIVATE_KEY_LEN * 2; + Utils::hex(_privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN, p); + p += ZT_ECC_PRIVATE_KEY_SET_LEN * 2; } *p = (char)0; return buf; @@ -154,7 +155,7 @@ bool Identity::fromString(const char* str) } delete _privateKey; - _privateKey = (C25519::Private*)0; + _privateKey = (ECC::Private*)0; int fno = 0; char* saveptr = (char*)0; @@ -174,14 +175,14 @@ bool Identity::fromString(const char* str) } break; case 2: - if (Utils::unhex(f, _publicKey.data, ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) { + if (Utils::unhex(f, _publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN) != ZT_ECC_PUBLIC_KEY_SET_LEN) { _address.zero(); return false; } break; case 3: - _privateKey = new C25519::Private(); - if (Utils::unhex(f, _privateKey->data, ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) { + _privateKey = new ECC::Private(); + if (Utils::unhex(f, _privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN) != ZT_ECC_PRIVATE_KEY_SET_LEN) { _address.zero(); return false; } diff --git a/node/Identity.hpp b/node/Identity.hpp index 9a7f0cc5b..0f82d4916 100644 --- a/node/Identity.hpp +++ b/node/Identity.hpp @@ -16,8 +16,8 @@ #include "Address.hpp" #include "Buffer.hpp" -#include "C25519.hpp" #include "Constants.hpp" +#include "ECC.hpp" #include "SHA512.hpp" #include "Utils.hpp" @@ -40,22 +40,22 @@ namespace ZeroTier { */ class Identity { public: - Identity() : _privateKey((C25519::Private*)0) + Identity() : _privateKey((ECC::Private*)0) { } - Identity(const Identity& id) : _address(id._address), _publicKey(id._publicKey), _privateKey((id._privateKey) ? new C25519::Private(*(id._privateKey)) : (C25519::Private*)0) + Identity(const Identity& id) : _address(id._address), _publicKey(id._publicKey), _privateKey((id._privateKey) ? new ECC::Private(*(id._privateKey)) : (ECC::Private*)0) { } - Identity(const char* str) : _privateKey((C25519::Private*)0) + Identity(const char* str) : _privateKey((ECC::Private*)0) { if (! fromString(str)) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE; } } - template Identity(const Buffer& b, unsigned int startAt = 0) : _privateKey((C25519::Private*)0) + template Identity(const Buffer& b, unsigned int startAt = 0) : _privateKey((ECC::Private*)0) { deserialize(b, startAt); } @@ -63,7 +63,7 @@ class Identity { ~Identity() { if (_privateKey) { - Utils::burn(_privateKey, sizeof(C25519::Private)); + Utils::burn(_privateKey, sizeof(ECC::Private)); delete _privateKey; } } @@ -74,13 +74,13 @@ class Identity { _publicKey = id._publicKey; if (id._privateKey) { if (! _privateKey) { - _privateKey = new C25519::Private(); + _privateKey = new ECC::Private(); } *_privateKey = *(id._privateKey); } else { delete _privateKey; - _privateKey = (C25519::Private*)0; + _privateKey = (ECC::Private*)0; } return *this; } @@ -104,7 +104,7 @@ class Identity { */ inline bool hasPrivate() const { - return (_privateKey != (C25519::Private*)0); + return (_privateKey != (ECC::Private*)0); } /** @@ -116,7 +116,7 @@ class Identity { { uint8_t address[ZT_ADDRESS_LENGTH]; _address.copyTo(address, ZT_ADDRESS_LENGTH); - SHA384(sha384buf, address, ZT_ADDRESS_LENGTH, _publicKey.data, ZT_C25519_PUBLIC_KEY_LEN); + SHA384(sha384buf, address, ZT_ADDRESS_LENGTH, _publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN); } /** @@ -128,7 +128,7 @@ class Identity { inline bool sha512PrivateKey(void* sha) const { if (_privateKey) { - SHA512(sha, _privateKey->data, ZT_C25519_PRIVATE_KEY_LEN); + SHA512(sha, _privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN); return true; } return false; @@ -140,10 +140,10 @@ class Identity { * @param data Data to sign * @param len Length of data */ - inline C25519::Signature sign(const void* data, unsigned int len) const + inline ECC::Signature sign(const void* data, unsigned int len) const { if (_privateKey) { - return C25519::sign(*_privateKey, _publicKey, data, len); + return ECC::sign(*_privateKey, _publicKey, data, len); } throw ZT_EXCEPTION_PRIVATE_KEY_REQUIRED; } @@ -159,10 +159,10 @@ class Identity { */ inline bool verify(const void* data, unsigned int len, const void* signature, unsigned int siglen) const { - if (siglen != ZT_C25519_SIGNATURE_LEN) { + if (siglen != ZT_ECC_SIGNATURE_LEN) { return false; } - return C25519::verify(_publicKey, data, len, signature); + return ECC::verify(_publicKey, data, len, signature); } /** @@ -173,9 +173,9 @@ class Identity { * @param signature Signature * @return True if signature validates and data integrity checks */ - inline bool verify(const void* data, unsigned int len, const C25519::Signature& signature) const + inline bool verify(const void* data, unsigned int len, const ECC::Signature& signature) const { - return C25519::verify(_publicKey, data, len, signature); + return ECC::verify(_publicKey, data, len, signature); } /** @@ -190,7 +190,7 @@ class Identity { inline bool agree(const Identity& id, void* const key) const { if (_privateKey) { - C25519::agree(*_privateKey, id._publicKey, key, ZT_SYMMETRIC_KEY_SIZE); + ECC::agree(*_privateKey, id._publicKey, key, ZT_SYMMETRIC_KEY_SIZE); return true; } return false; @@ -215,10 +215,10 @@ class Identity { { _address.appendTo(b); b.append((uint8_t)0); // C25519/Ed25519 identity type - b.append(_publicKey.data, ZT_C25519_PUBLIC_KEY_LEN); + b.append(_publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN); if ((_privateKey) && (includePrivate)) { - b.append((unsigned char)ZT_C25519_PRIVATE_KEY_LEN); - b.append(_privateKey->data, ZT_C25519_PRIVATE_KEY_LEN); + b.append((unsigned char)ZT_ECC_PRIVATE_KEY_SET_LEN); + b.append(_privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN); } else { b.append((unsigned char)0); @@ -240,7 +240,7 @@ class Identity { template inline unsigned int deserialize(const Buffer& b, unsigned int startAt = 0) { delete _privateKey; - _privateKey = (C25519::Private*)0; + _privateKey = (ECC::Private*)0; unsigned int p = startAt; @@ -251,17 +251,17 @@ class Identity { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE; } - memcpy(_publicKey.data, b.field(p, ZT_C25519_PUBLIC_KEY_LEN), ZT_C25519_PUBLIC_KEY_LEN); - p += ZT_C25519_PUBLIC_KEY_LEN; + memcpy(_publicKey.data, b.field(p, ZT_ECC_PUBLIC_KEY_SET_LEN), ZT_ECC_PUBLIC_KEY_SET_LEN); + p += ZT_ECC_PUBLIC_KEY_SET_LEN; unsigned int privateKeyLength = (unsigned int)b[p++]; if (privateKeyLength) { - if (privateKeyLength != ZT_C25519_PRIVATE_KEY_LEN) { + if (privateKeyLength != ZT_ECC_PRIVATE_KEY_SET_LEN) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } - _privateKey = new C25519::Private(); - memcpy(_privateKey->data, b.field(p, ZT_C25519_PRIVATE_KEY_LEN), ZT_C25519_PRIVATE_KEY_LEN); - p += ZT_C25519_PRIVATE_KEY_LEN; + _privateKey = new ECC::Private(); + memcpy(_privateKey->data, b.field(p, ZT_ECC_PRIVATE_KEY_SET_LEN), ZT_ECC_PRIVATE_KEY_SET_LEN); + p += ZT_ECC_PRIVATE_KEY_SET_LEN; } return (p - startAt); @@ -290,7 +290,7 @@ class Identity { /** * @return C25519 public key */ - inline const C25519::Public& publicKey() const + inline const ECC::Public& publicKey() const { return _publicKey; } @@ -298,15 +298,15 @@ class Identity { /** * @return C25519 key pair (only returns valid pair if private key is present in this Identity object) */ - inline const C25519::Pair privateKeyPair() const + inline const ECC::Pair privateKeyPair() const { - C25519::Pair pair; + ECC::Pair pair; pair.pub = _publicKey; if (_privateKey) { pair.priv = *_privateKey; } else { - memset(pair.priv.data, 0, ZT_C25519_PRIVATE_KEY_LEN); + memset(pair.priv.data, 0, ZT_ECC_PRIVATE_KEY_SET_LEN); } return pair; } @@ -321,11 +321,11 @@ class Identity { inline bool operator==(const Identity& id) const { - return ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_C25519_PUBLIC_KEY_LEN) == 0)); + return ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN) == 0)); } inline bool operator<(const Identity& id) const { - return ((_address < id._address) || ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_C25519_PUBLIC_KEY_LEN) < 0))); + return ((_address < id._address) || ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN) < 0))); } inline bool operator!=(const Identity& id) const { @@ -346,8 +346,8 @@ class Identity { private: Address _address; - C25519::Public _publicKey; - C25519::Private* _privateKey; + ECC::Public _publicKey; + ECC::Private* _privateKey; }; } // namespace ZeroTier diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index af1e7930d..195cc5763 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -70,7 +70,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment* RR, void* tPtr, int32_t const SharedPtr peer(RR->topology->getPeer(tPtr, sourceAddress)); if (peer) { if (! _authenticated) { - if (! dearmor(peer->key(), peer->aesKeys())) { + if (! dearmor(peer->key(), peer->aesKeys(), RR->identity)) { RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, packetId(), sourceAddress, hops(), "invalid MAC"); peer->recordIncomingInvalidPacket(_path); return true; @@ -404,13 +404,13 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment* RR, void* tPtr, const bo uint8_t key[ZT_SYMMETRIC_KEY_SIZE]; if (RR->identity.agree(id, key)) { - if (dearmor(key, peer->aesKeysIfSupported())) { // ensure packet is authentic, otherwise drop + if (dearmor(key, peer->aesKeysIfSupported(), RR->identity)) { // ensure packet is authentic, otherwise drop RR->t->incomingPacketDroppedHELLO(tPtr, _path, pid, fromAddress, "address collision"); Packet outp(id.address(), RR->identity.address(), Packet::VERB_ERROR); outp.append((uint8_t)Packet::VERB_HELLO); outp.append((uint64_t)pid); outp.append((uint8_t)Packet::ERROR_IDENTITY_COLLISION); - outp.armor(key, true, peer->aesKeysIfSupported()); + outp.armor(key, true, false, peer->aesKeysIfSupported(), peer->identity()); Metrics::pkt_error_out++; Metrics::pkt_error_identity_collision_out++; _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); @@ -428,7 +428,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment* RR, void* tPtr, const bo else { // Identity is the same as the one we already have -- check packet integrity - if (! dearmor(peer->key(), peer->aesKeysIfSupported())) { + if (! dearmor(peer->key(), peer->aesKeysIfSupported(), RR->identity)) { RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, pid, fromAddress, hops(), "invalid MAC"); return true; } @@ -454,7 +454,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment* RR, void* tPtr, const bo // Check packet integrity and MAC (this is faster than locallyValidate() so do it first to filter out total crap) SharedPtr newPeer(new Peer(RR, RR->identity, id)); - if (! dearmor(newPeer->key(), newPeer->aesKeysIfSupported())) { + if (! dearmor(newPeer->key(), newPeer->aesKeysIfSupported(), RR->identity)) { RR->t->incomingPacketMessageAuthenticationFailure(tPtr, _path, pid, fromAddress, hops(), "invalid MAC"); return true; } @@ -520,39 +520,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment* RR, void* tPtr, const bo outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR); outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR); outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION); - - if (protoVersion >= 5) { - _path->address().serialize(outp); - } - else { - /* LEGACY COMPATIBILITY HACK: - * - * For a while now (since 1.0.3), ZeroTier has recognized changes in - * its network environment empirically by examining its external network - * address as reported by trusted peers. In versions prior to 1.1.0 - * (protocol version < 5), they did this by saving a snapshot of this - * information (in SelfAwareness.hpp) keyed by reporting device ID and - * address type. - * - * This causes problems when clustering is combined with symmetric NAT. - * Symmetric NAT remaps ports, so different endpoints in a cluster will - * report back different exterior addresses. Since the old code keys - * this by device ID and not sending physical address and compares the - * entire address including port, it constantly thinks its external - * surface is changing and resets connections when talking to a cluster. - * - * In new code we key by sending physical address and device and we also - * take the more conservative position of only interpreting changes in - * IP address (neglecting port) as a change in network topology that - * necessitates a reset. But we can make older clients work here by - * nulling out the port field. Since this info is only used for empirical - * detection of link changes, it doesn't break anything else. - */ - InetAddress tmpa(_path->address()); - tmpa.setPort(0); - tmpa.serialize(outp); - } - + _path->address().serialize(outp); const unsigned int worldUpdateSizeAt = outp.size(); outp.addSize(2); // make room for 16-bit size field if ((planetWorldId) && (RR->topology->planetWorldTimestamp() > planetWorldTimestamp) && (planetWorldId == RR->topology->planetWorldId())) { @@ -573,7 +541,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment* RR, void* tPtr, const bo } outp.setAt(worldUpdateSizeAt, (uint16_t)(outp.size() - (worldUpdateSizeAt + 2))); - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), peer->identity()); peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; _path->send(RR, tPtr, outp.data(), outp.size(), now); @@ -736,7 +704,7 @@ bool IncomingPacket::_doWHOIS(const RuntimeEnvironment* RR, void* tPtr, const Sh if (count > 0) { Metrics::pkt_ok_out++; - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), RR->identity); _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); } @@ -968,7 +936,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment* RR, void* tPtr, cons outp.append((uint64_t)packetId()); outp.append((uint64_t)nwid); const int64_t now = RR->node->now(); - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), peer->identity()); peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); @@ -998,7 +966,7 @@ bool IncomingPacket::_doECHO(const RuntimeEnvironment* RR, void* tPtr, const Sha if (size() > ZT_PACKET_IDX_PAYLOAD) { outp.append(reinterpret_cast(data()) + ZT_PACKET_IDX_PAYLOAD, size() - ZT_PACKET_IDX_PAYLOAD); } - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), peer->identity()); peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); @@ -1195,7 +1163,7 @@ bool IncomingPacket::_doNETWORK_CONFIG_REQUEST(const RuntimeEnvironment* RR, voi outp.append(requestPacketId); outp.append((unsigned char)Packet::ERROR_UNSUPPORTED_OPERATION); outp.append(nwid); - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), peer->identity()); Metrics::pkt_error_out++; Metrics::pkt_error_unsupported_op_out++; _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); @@ -1219,7 +1187,7 @@ bool IncomingPacket::_doNETWORK_CONFIG(const RuntimeEnvironment* RR, void* tPtr, outp.append((uint64_t)network->id()); outp.append((uint64_t)configUpdateId); const int64_t now = RR->node->now(); - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), peer->identity()); peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); @@ -1264,7 +1232,7 @@ bool IncomingPacket::_doMULTICAST_GATHER(const RuntimeEnvironment* RR, void* tPt outp.append((uint32_t)mg.adi()); const unsigned int gatheredLocally = RR->mc->gather(peer->address(), nwid, mg, outp, gatherLimit); if (gatheredLocally > 0) { - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), peer->identity()); peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; _path->send(RR, tPtr, outp.data(), outp.size(), now); @@ -1370,7 +1338,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment* RR, void* tPtr outp.append((unsigned char)0x02); // flag 0x02 = contains gather results if (RR->mc->gather(peer->address(), nwid, to, outp, gatherLimit)) { const int64_t now = RR->node->now(); - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), peer->identity()); peer->recordOutgoingPacket(_path, outp.packetId(), outp.payloadLength(), outp.verb(), ZT_QOS_NO_FLOW, now); Metrics::pkt_ok_out++; _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); @@ -1512,7 +1480,7 @@ void IncomingPacket::_sendErrorNeedCredentials(const RuntimeEnvironment* RR, voi outp.append(packetId()); outp.append((uint8_t)Packet::ERROR_NEED_MEMBERSHIP_CERTIFICATE); outp.append(nwid); - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); + outp.armor(peer->key(), true, false, peer->aesKeysIfSupported(), peer->identity()); Metrics::pkt_error_out++; Metrics::pkt_error_need_membership_cert_out++; _path->send(RR, tPtr, outp.data(), outp.size(), RR->node->now()); diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index 2438e4f30..0d5fd7ce4 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -13,7 +13,6 @@ #include "Multicaster.hpp" -#include "C25519.hpp" #include "CertificateOfMembership.hpp" #include "Constants.hpp" #include "Network.hpp" @@ -190,7 +189,7 @@ void Multicaster::send(void* tPtr, int64_t now, const SharedPtr& networ if (! network->config().disableCompression()) { outp.compress(); } - outp.armor(bestMulticastReplicator->key(), true, bestMulticastReplicator->aesKeysIfSupported()); + outp.armor(bestMulticastReplicator->key(), true, false, bestMulticastReplicator->aesKeysIfSupported(), bestMulticastReplicator->identity()); Metrics::pkt_multicast_frame_out++; bestMulticastReplicatorPath->send(RR, tPtr, outp.data(), outp.size(), now); return; diff --git a/node/Network.cpp b/node/Network.cpp index 70587a51c..4b5cdd02d 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -18,6 +18,7 @@ #include "Address.hpp" #include "Buffer.hpp" #include "Constants.hpp" +#include "ECC.hpp" #include "InetAddress.hpp" #include "MAC.hpp" #include "Metrics.hpp" @@ -1113,10 +1114,10 @@ uint64_t Network::handleConfigChunk(void* tPtr, const uint64_t packetId, const A if (((chunkIndex + chunkLen) > totalLength) || (totalLength >= ZT_NETWORKCONFIG_DICT_CAPACITY)) { // >= since we need room for a null at the end return 0; } - if ((chunk[ptr] != 1) || (chunk.at(ptr + 1) != ZT_C25519_SIGNATURE_LEN)) { + if ((chunk[ptr] != 1) || (chunk.at(ptr + 1) != ZT_ECC_SIGNATURE_LEN)) { return 0; } - const uint8_t* sig = reinterpret_cast(chunk.field(ptr + 3, ZT_C25519_SIGNATURE_LEN)); + const uint8_t* sig = reinterpret_cast(chunk.field(ptr + 3, ZT_ECC_SIGNATURE_LEN)); // We can use the signature, which is unique per chunk, to get a per-chunk ID for local deduplication use for (unsigned int i = 0; i < 16; ++i) { @@ -1146,7 +1147,7 @@ uint64_t Network::handleConfigChunk(void* tPtr, const uint64_t packetId, const A if (! controllerId) { // we should always have the controller identity by now, otherwise how would we have queried it the first time? return 0; } - if (! controllerId.verify(chunk.field(start, ptr - start), ptr - start, sig, ZT_C25519_SIGNATURE_LEN)) { + if (! controllerId.verify(chunk.field(start, ptr - start), ptr - start, sig, ZT_ECC_SIGNATURE_LEN)) { return 0; } diff --git a/node/Node.cpp b/node/Node.cpp index 4b9911a66..ed4b71605 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -17,6 +17,7 @@ #include "Address.hpp" #include "Buffer.hpp" #include "Constants.hpp" +#include "ECC.hpp" #include "Identity.hpp" #include "Metrics.hpp" #include "Multicaster.hpp" @@ -818,10 +819,10 @@ void Node::ncSendConfig(uint64_t nwid, uint64_t requestPacketId, const Address& outp.append((uint32_t)totalSize); outp.append((uint32_t)chunkIndex); - C25519::Signature sig(RR->identity.sign(reinterpret_cast(outp.data()) + sigStart, outp.size() - sigStart)); + ECC::Signature sig(RR->identity.sign(reinterpret_cast(outp.data()) + sigStart, outp.size() - sigStart)); outp.append((uint8_t)1); - outp.append((uint16_t)ZT_C25519_SIGNATURE_LEN); - outp.append(sig.data, ZT_C25519_SIGNATURE_LEN); + outp.append((uint16_t)ZT_ECC_SIGNATURE_LEN); + outp.append(sig.data, ZT_ECC_SIGNATURE_LEN); outp.compress(); RR->sw->send((void*)0, outp, true); diff --git a/node/Packet.cpp b/node/Packet.cpp index b0967af1d..88af76105 100644 --- a/node/Packet.cpp +++ b/node/Packet.cpp @@ -13,6 +13,8 @@ #include "Packet.hpp" +#include "ECC.hpp" + #include #include #include @@ -1083,11 +1085,13 @@ static inline int LZ4_decompress_safe(const char* source, char* dest, int compre const unsigned char Packet::ZERO_KEY[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -void Packet::armor(const void* key, bool encryptPayload, const AES aesKeys[2]) +void Packet::armor(const void* key, bool encryptPayload, bool extendedArmor, const AES aesKeys[2], const Identity& identity) { uint8_t* const data = reinterpret_cast(unsafeData()); + + this->setExtendedArmor(extendedArmor); + if ((aesKeys) && (encryptPayload)) { - // char tmp0[16],tmp1[16]; setCipher(ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV); uint8_t* const payload = data + ZT_PACKET_IDX_VERB; @@ -1118,10 +1122,12 @@ void Packet::armor(const void* key, bool encryptPayload, const AES aesKeys[2]) if (ZT_HAS_FAST_CRYPTO()) { const unsigned int payloadLen = (encryptPayload) ? (size() - ZT_PACKET_IDX_VERB) : 0; uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8]; + uint64_t mac[2]; + ZT_FAST_SINGLE_PASS_SALSA2012(keyStream, payloadLen + 64, (data + ZT_PACKET_IDX_IV), mangledKey); Salsa20::memxor(data + ZT_PACKET_IDX_VERB, reinterpret_cast(keyStream + 8), payloadLen); - uint64_t mac[2]; Poly1305::compute(mac, data + ZT_PACKET_IDX_VERB, size() - ZT_PACKET_IDX_VERB, keyStream); + #ifdef ZT_NO_TYPE_PUNNING memcpy(data + ZT_PACKET_IDX_MAC, mac, 8); #else @@ -1129,9 +1135,10 @@ void Packet::armor(const void* key, bool encryptPayload, const AES aesKeys[2]) #endif } else { - Salsa20 s20(mangledKey, data + ZT_PACKET_IDX_IV); - uint64_t macKey[4]; + uint64_t mac[2]; + + Salsa20 s20(mangledKey, data + ZT_PACKET_IDX_IV); s20.crypt12(ZERO_KEY, macKey, sizeof(macKey)); uint8_t* const payload = data + ZT_PACKET_IDX_VERB; @@ -1139,24 +1146,62 @@ void Packet::armor(const void* key, bool encryptPayload, const AES aesKeys[2]) if (encryptPayload) { s20.crypt12(payload, payload, payloadLen); } - uint64_t mac[2]; Poly1305::compute(mac, payload, payloadLen, macKey); memcpy(data + ZT_PACKET_IDX_MAC, mac, 8); } } + + /* NOTE: this is currently only ever used with NONE encryption for HELLO packets. */ + if (extendedArmor) { + ECC::Pair ephemeralKeyPair = ECC::generate(); + uint8_t ephemeralSymmetric[32]; + ECC::agree(ephemeralKeyPair, identity.publicKey(), ephemeralSymmetric, 32); + + AES cipher(ephemeralSymmetric); + AES::CTR aesCtr(cipher); + aesCtr.init(data, 0, data + ZT_PACKET_IDX_EXTENDED_ARMOR_START); + aesCtr.crypt(data + ZT_PACKET_IDX_EXTENDED_ARMOR_START, size() - ZT_PACKET_IDX_EXTENDED_ARMOR_START); + aesCtr.finish(); + + this->append(ephemeralKeyPair.pub.data, ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN); + } } -bool Packet::dearmor(const void* key, const AES aesKeys[2]) +bool Packet::dearmor(const void* key, const AES aesKeys[2], const Identity& identity) { uint8_t* const data = reinterpret_cast(unsafeData()); + const unsigned int cs = cipher(); + + if (extendedArmor() && (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)) { + if (size() < (ZT_PACKET_IDX_VERB + 1 + ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN)) { + return false; + } + uint8_t ephemeralSymmetric[32]; + ECC::Public ephemeralKey; + memcpy(ephemeralKey.data, data + (size() - ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN), ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN); + ECC::agree(identity.privateKeyPair(), ephemeralKey, ephemeralSymmetric, 32); + + AES cipher(ephemeralSymmetric); + AES::CTR aesCtr(cipher); + aesCtr.init(data, 0, data + ZT_PACKET_IDX_EXTENDED_ARMOR_START); + aesCtr.crypt(data + ZT_PACKET_IDX_EXTENDED_ARMOR_START, (size() - ZT_PACKET_IDX_EXTENDED_ARMOR_START) - ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN); + aesCtr.finish(); + + this->setSize(size() - ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN); + + /* Note: both the MAC and the data were encrypted with the ephemeral key. We don't need + * a separate MAC for the ephemeral encryption because the MAC check below is obviously + * going to fail if the ephemeral key was incorrect. */ + } + const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB; unsigned char* const payload = data + ZT_PACKET_IDX_VERB; - const unsigned int cs = cipher(); if (cs == ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV) { if (aesKeys) { uint64_t tag[2]; + #ifdef ZT_NO_UNALIGNED_ACCESS Utils::copy<8>(tag, data); Utils::copy<8>(tag + 1, data + ZT_PACKET_IDX_MAC); diff --git a/node/Packet.hpp b/node/Packet.hpp index f038c05dc..804618476 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -18,6 +18,7 @@ #include "Address.hpp" #include "Buffer.hpp" #include "Constants.hpp" +#include "Identity.hpp" #include "Poly1305.hpp" #include "Salsa20.hpp" #include "Utils.hpp" @@ -57,10 +58,15 @@ * 10 - 1.4.0 ... 1.4.6 * 11 - 1.4.7 ... 1.4.8 * + Multipath capability and load balancing (beta) - * 12 - 1.4.8 ... CURRENT (1.4 series) + * 12 - 1.4.8 ... 1.16.0 * + AES-GMAC-SIV backported for faster peer-to-peer crypto + * 13 - 1.16.0 ... CURRENT + * + Old deprecated "encrypted" flag removed + * + Ephemeral keying with second encryption pass to hide HELLO etc. + * + Encrypted HELLO packets to anyone but roots + * + Remove deprecated parsing of LAN announcements */ -#define ZT_PROTO_VERSION 12 +#define ZT_PROTO_VERSION 13 /** * Minimum supported protocol version @@ -98,6 +104,18 @@ */ #define ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 1 +/** + * Cipher suite: NONE + * + * This differs from POLY1305/NONE in that *no* crypto is done, not even + * authentication. This is for trusted local LAN interconnects for internal + * SDN use within a data center. + * + * For this mode the MAC field becomes a trusted path ID and must match the + * configured ID of a trusted path or the packet is discarded. + */ +#define ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH 2 + /** * AES-GMAC-SIV backported from 2.x */ @@ -114,23 +132,15 @@ #define ZT_KBKDF_LABEL_AES_GMAC_SIV_K1 '1' /** - * Cipher suite: NONE + * Header flag indicating ephemeral keying and second encryption pass. * - * This differs from POLY1305/NONE in that *no* crypto is done, not even - * authentication. This is for trusted local LAN interconnects for internal - * SDN use within a data center. + * If this is set, the packet will have an ephemeral key appended to it its payload + * will be encrypted with AES-CTR using this ephemeral key and the packet's header + * as an IV. * - * For this mode the MAC field becomes a trusted path ID and must match the - * configured ID of a trusted path or the packet is discarded. + * Note that this is a reuse of a flag that has long been deprecated and ignored. */ -#define ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH 2 - -/** - * DEPRECATED payload encrypted flag, may be re-used in the future. - * - * This has been replaced by the three-bit cipher suite selection field. - */ -#define ZT_PROTO_FLAG_ENCRYPTED 0x80 +#define ZT_PROTO_FLAG_EXTENDED_ARMOR 0x80 /** * Header flag indicating that a packet is fragmented @@ -145,66 +155,8 @@ */ #define ZT_PROTO_VERB_FLAG_COMPRESSED 0x80 -/** - * Rounds used for Salsa20 encryption in ZT - * - * Discussion: - * - * DJB (Salsa20's designer) designed Salsa20 with a significant margin of 20 - * rounds, but has said repeatedly that 12 is likely sufficient. So far (as of - * July 2015) there are no published attacks against 12 rounds, let alone 20. - * - * In cryptography, a "break" means something different from what it means in - * common discussion. If a cipher is 256 bits strong and someone finds a way - * to reduce key search to 254 bits, this constitutes a "break" in the academic - * literature. 254 bits is still far beyond what can be leveraged to accomplish - * a "break" as most people would understand it -- the actual decryption and - * reading of traffic. - * - * Nevertheless, "attacks only get better" as cryptographers like to say. As - * a result, they recommend not using anything that's shown any weakness even - * if that weakness is so far only meaningful to academics. It may be a sign - * of a deeper problem. - * - * So why choose a lower round count? - * - * Turns out the speed difference is nontrivial. On a Macbook Pro (Core i3) 20 - * rounds of SSE-optimized Salsa20 achieves ~508mb/sec/core, while 12 rounds - * hits ~832mb/sec/core. ZeroTier is designed for multiple objectives: - * security, simplicity, and performance. In this case a deference was made - * for performance. - * - * Meta discussion: - * - * The cipher is not the thing you should be paranoid about. - * - * I'll qualify that. If the cipher is known to be weak, like RC4, or has a - * key size that is too small, like DES, then yes you should worry about - * the cipher. - * - * But if the cipher is strong and your adversary is anyone other than the - * intelligence apparatus of a major superpower, you are fine in that - * department. - * - * Go ahead. Search for the last ten vulnerabilities discovered in SSL. Not - * a single one involved the breaking of a cipher. Now broaden your search. - * Look for issues with SSH, IPSec, etc. The only cipher-related issues you - * will find might involve the use of RC4 or MD5, algorithms with known - * issues or small key/digest sizes. But even weak ciphers are difficult to - * exploit in the real world -- you usually need a lot of data and a lot of - * compute time. No, virtually EVERY security vulnerability you will find - * involves a problem with the IMPLEMENTATION not with the cipher. - * - * A flaw in ZeroTier's protocol or code is incredibly, unbelievably - * more likely than a flaw in Salsa20 or any other cipher or cryptographic - * primitive it uses. We're talking odds of dying in a car wreck vs. odds of - * being personally impacted on the head by a meteorite. Nobody without a - * billion dollar budget is going to break into your network by actually - * cracking Salsa20/12 (or even /8) in the field. - * - * So stop worrying about the cipher unless you are, say, the Kremlin and your - * adversary is the NSA and the GCHQ. In that case... well that's above my - * pay grade. I'll just say defense in depth. +/* + * Rounds used for deprecated Salsa20 encryption */ #define ZT_PROTO_SALSA20_ROUNDS 12 @@ -227,6 +179,11 @@ #define ZT_PACKET_IDX_VERB 27 #define ZT_PACKET_IDX_PAYLOAD 28 +/** + * Index where extended armor encryption starts (right after flags, before MAC) + */ +#define ZT_PACKET_IDX_EXTENDED_ARMOR_START ZT_PACKET_IDX_MAC + /** * Packet buffer size (can be changed) */ @@ -1253,6 +1210,29 @@ class Packet : public Buffer { } } + /** + * @return True if packet is encrypted with an extra ephemeral key + */ + inline bool extendedArmor() const + { + return (((unsigned char)(*this)[ZT_PACKET_IDX_FLAGS] & ZT_PROTO_FLAG_EXTENDED_ARMOR) != 0); + } + + /** + * Set this packet's extended armor flag + * + * @param f Extended armor flag value + */ + inline void setExtendedArmor(bool f) + { + if (f) { + (*this)[ZT_PACKET_IDX_FLAGS] |= (char)ZT_PROTO_FLAG_EXTENDED_ARMOR; + } + else { + (*this)[ZT_PACKET_IDX_FLAGS] &= (char)(~ZT_PROTO_FLAG_EXTENDED_ARMOR); + } + } + /** * @return True if compressed (result only valid if unencrypted) */ @@ -1301,13 +1281,6 @@ class Packet : public Buffer { { unsigned char& b = (*this)[ZT_PACKET_IDX_FLAGS]; b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH - // Set DEPRECATED "encrypted" flag -- used by pre-1.0.3 peers - if (c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) { - b |= ZT_PROTO_FLAG_ENCRYPTED; - } - else { - b &= (~ZT_PROTO_FLAG_ENCRYPTED); - } } /** @@ -1389,9 +1362,11 @@ class Packet : public Buffer { * * @param key 32-byte key * @param encryptPayload If true, encrypt packet payload, else just MAC + * @param extendedArmor Use an ephemeral key to encrypt payload (for encrypted HELLO) + * @param identity Identity of packet recipient/destination * @param aesKeys If non-NULL these are the two keys for AES-GMAC-SIV */ - void armor(const void* key, bool encryptPayload, const AES aesKeys[2]); + void armor(const void* key, bool encryptPayload, bool extendedArmor, const AES aesKeys[2], const Identity& identity); /** * Verify and (if encrypted) decrypt packet @@ -1402,9 +1377,10 @@ class Packet : public Buffer { * * @param key 32-byte key * @param aesKeys If non-NULL these are the two keys for AES-GMAC-SIV + * @param identity Receiver's identity (must include secret) * @return False if packet is invalid or failed MAC authenticity check */ - bool dearmor(const void* key, const AES aesKeys[2]); + bool dearmor(const void* key, const AES aesKeys[2], const Identity& identity); /** * Encrypt/decrypt a separately armored portion of a packet diff --git a/node/Peer.cpp b/node/Peer.cpp index ec8521c4b..68ed4d64e 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -15,6 +15,7 @@ #include "../version.h" #include "Constants.hpp" +#include "Identity.hpp" #include "InetAddress.hpp" #include "Metrics.hpp" #include "Network.hpp" @@ -251,7 +252,7 @@ void Peer::received( Metrics::pkt_push_direct_paths_out++; outp->setAt(ZT_PACKET_IDX_PAYLOAD, (uint16_t)count); outp->compress(); - outp->armor(_key, true, aesKeysIfSupported()); + outp->armor(_key, true, false, aesKeysIfSupported(), _id); Metrics::pkt_push_direct_paths_out++; path->send(RR, tPtr, outp->data(), outp->size(), now); } @@ -401,7 +402,7 @@ void Peer::introduce(void* const tPtr, const int64_t now, const SharedPtr& outp.append((uint8_t)4); outp.append(other->_paths[theirs].p->address().rawIpData(), 4); } - outp.armor(_key, true, aesKeysIfSupported()); + outp.armor(_key, true, false, aesKeysIfSupported(), _id); Metrics::pkt_rendezvous_out++; _paths[mine].p->send(RR, tPtr, outp.data(), outp.size(), now); } @@ -418,7 +419,7 @@ void Peer::introduce(void* const tPtr, const int64_t now, const SharedPtr& outp.append((uint8_t)4); outp.append(_paths[mine].p->address().rawIpData(), 4); } - outp.armor(other->_key, true, other->aesKeysIfSupported()); + outp.armor(other->_key, true, false, other->aesKeysIfSupported(), other->identity()); Metrics::pkt_rendezvous_out++; other->_paths[theirs].p->send(RR, tPtr, outp.data(), outp.size(), now); } @@ -463,13 +464,13 @@ void Peer::sendHELLO(void* tPtr, const int64_t localSocket, const InetAddress& a Metrics::pkt_hello_out++; if (atAddress) { - outp.armor(_key, false, nullptr); // false == don't encrypt full payload, but add MAC + outp.armor(_key, false, true, nullptr, _id); RR->node->expectReplyTo(outp.packetId()); RR->node->putPacket(tPtr, RR->node->lowBandwidthModeEnabled() ? localSocket : -1, atAddress, outp.data(), outp.size()); } else { RR->node->expectReplyTo(outp.packetId()); - RR->sw->send(tPtr, outp, false); // false == don't encrypt full payload, but add MAC + RR->sw->send(tPtr, outp, true); } } @@ -477,7 +478,7 @@ void Peer::attemptToContactAt(void* tPtr, const int64_t localSocket, const InetA { if ((! sendFullHello) && (_vProto >= 5) && (! ((_vMajor == 1) && (_vMinor == 1) && (_vRevision == 0)))) { Packet outp(_id.address(), RR->identity.address(), Packet::VERB_ECHO); - outp.armor(_key, true, aesKeysIfSupported()); + outp.armor(_key, true, false, aesKeysIfSupported(), _id); Metrics::pkt_echo_out++; RR->node->expectReplyTo(outp.packetId()); RR->node->putPacket(tPtr, localSocket, atAddress, outp.data(), outp.size()); diff --git a/node/Revocation.hpp b/node/Revocation.hpp index 671b87043..b6edccf57 100644 --- a/node/Revocation.hpp +++ b/node/Revocation.hpp @@ -17,9 +17,9 @@ #include "../include/ZeroTierOne.h" #include "Address.hpp" #include "Buffer.hpp" -#include "C25519.hpp" #include "Constants.hpp" #include "Credential.hpp" +#include "ECC.hpp" #include "Identity.hpp" #include "Utils.hpp" @@ -152,8 +152,8 @@ class Revocation : public Credential { if (! forSign) { b.append((uint8_t)1); // 1 == Ed25519 signature - b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); - b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); + b.append((uint16_t)ZT_ECC_SIGNATURE_LEN); + b.append(_signature.data, ZT_ECC_SIGNATURE_LEN); } // This is the size of any additional fields, currently 0. @@ -189,10 +189,10 @@ class Revocation : public Credential { _type = (Credential::Type)b[p++]; if (b[p++] == 1) { - if (b.template at(p) == ZT_C25519_SIGNATURE_LEN) { + if (b.template at(p) == ZT_ECC_SIGNATURE_LEN) { p += 2; - memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); - p += ZT_C25519_SIGNATURE_LEN; + memcpy(_signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN); + p += ZT_ECC_SIGNATURE_LEN; } else { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; @@ -219,7 +219,7 @@ class Revocation : public Credential { Address _target; Address _signedBy; Credential::Type _type; - C25519::Signature _signature; + ECC::Signature _signature; }; } // namespace ZeroTier diff --git a/node/Switch.cpp b/node/Switch.cpp index ec651bbd5..6b0e2b081 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -78,31 +78,7 @@ void Switch::onRemotePacket(void* tPtr, const int64_t localSocket, const InetAdd const SharedPtr path(RR->topology->getPath(localSocket, fromAddr)); path->received(now); - if (len == 13) { - /* LEGACY: before VERB_PUSH_DIRECT_PATHS, peers used broadcast - * announcements on the LAN to solve the 'same network problem.' We - * no longer send these, but we'll listen for them for a while to - * locate peers with versions <1.0.4. */ - - const Address beaconAddr(reinterpret_cast(data) + 8, 5); - if (beaconAddr == RR->identity.address()) { - return; - } - if (! RR->node->shouldUsePathForZeroTierTraffic(tPtr, beaconAddr, localSocket, fromAddr)) { - return; - } - const SharedPtr peer(RR->topology->getPeer(tPtr, beaconAddr)); - if (peer) { // we'll only respond to beacons from known peers - if ((now - _lastBeaconResponse) >= 2500) { // limit rate of responses - _lastBeaconResponse = now; - Packet outp(peer->address(), RR->identity.address(), Packet::VERB_NOP); - outp.armor(peer->key(), true, peer->aesKeysIfSupported()); - Metrics::pkt_nop_out++; - path->send(RR, tPtr, outp.data(), outp.size(), now); - } - } - } - else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { // SECURITY: min length check is important since we do some C-style stuff below! + if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { if (reinterpret_cast(data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { // Handle fragment ---------------------------------------------------- @@ -519,9 +495,7 @@ void Switch::onLocalEthernet(void* tPtr, const SharedPtr& network, cons // this prevents problems related to trying to do rx while inside of doing tx, such as acquiring same lock recursively // - std::thread([=]() { - RR->node->putFrame(tPtr, network->id(), network->userPtr(), peerMac, from, ZT_ETHERTYPE_IPV6, 0, adv, 72); - }).detach(); + std::thread([=]() { RR->node->putFrame(tPtr, network->id(), network->userPtr(), peerMac, from, ZT_ETHERTYPE_IPV6, 0, adv, 72); }).detach(); return; // NDP emulation done. We have forged a "fake" reply, so no need to send actual NDP query. } // else no NDP emulation @@ -556,9 +530,7 @@ void Switch::onLocalEthernet(void* tPtr, const SharedPtr& network, cons // // same pattern as putFrame call above // - std::thread([=]() { - RR->node->putFrame(tPtr, network->id(), network->userPtr(), from, to, etherType, vlanId, data, len); - }).detach(); + std::thread([=]() { RR->node->putFrame(tPtr, network->id(), network->userPtr(), from, to, etherType, vlanId, data, len); }).detach(); } else if (to[0] == MAC::firstOctetForNetwork(network->id())) { // Destination is another ZeroTier peer on the same network @@ -1155,7 +1127,7 @@ void Switch::_sendViaSpecificPath(void* tPtr, SharedPtr peer, SharedPtrkey(), encrypt, peer->aesKeysIfSupported()); + packet.armor(peer->key(), encrypt, false, peer->aesKeysIfSupported(), peer->identity()); } RR->node->expectReplyTo(packet.packetId()); } diff --git a/node/Tag.hpp b/node/Tag.hpp index 24aa00d7b..0243264af 100644 --- a/node/Tag.hpp +++ b/node/Tag.hpp @@ -16,9 +16,9 @@ #include "Address.hpp" #include "Buffer.hpp" -#include "C25519.hpp" #include "Constants.hpp" #include "Credential.hpp" +#include "ECC.hpp" #include "Identity.hpp" #include @@ -137,9 +137,9 @@ class Tag : public Credential { _issuedTo.appendTo(b); _signedBy.appendTo(b); if (! forSign) { - b.append((uint8_t)1); // 1 == Ed25519 - b.append((uint16_t)ZT_C25519_SIGNATURE_LEN); // length of signature - b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); + b.append((uint8_t)1); // 1 == Ed25519 + b.append((uint16_t)ZT_ECC_SIGNATURE_LEN); // length of signature + b.append(_signature.data, ZT_ECC_SIGNATURE_LEN); } b.append((uint16_t)0); // length of additional fields, currently 0 @@ -170,12 +170,12 @@ class Tag : public Credential { _signedBy.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH); p += ZT_ADDRESS_LENGTH; if (b[p++] == 1) { - if (b.template at(p) != ZT_C25519_SIGNATURE_LEN) { + if (b.template at(p) != ZT_ECC_SIGNATURE_LEN) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN; } p += 2; - memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); - p += ZT_C25519_SIGNATURE_LEN; + memcpy(_signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN); + p += ZT_ECC_SIGNATURE_LEN; } else { p += 2 + b.template at(p); @@ -251,7 +251,7 @@ class Tag : public Credential { int64_t _ts; Address _issuedTo; Address _signedBy; - C25519::Signature _signature; + ECC::Signature _signature; }; } // namespace ZeroTier diff --git a/node/World.hpp b/node/World.hpp index b730543ad..6806a01b9 100644 --- a/node/World.hpp +++ b/node/World.hpp @@ -15,8 +15,8 @@ #define ZT_WORLD_HPP #include "Buffer.hpp" -#include "C25519.hpp" #include "Constants.hpp" +#include "ECC.hpp" #include "Identity.hpp" #include "InetAddress.hpp" @@ -41,7 +41,7 @@ /** * The (more than) maximum length of a serialized World */ -#define ZT_WORLD_MAX_SERIALIZED_LENGTH (((1024 + (32 * ZT_WORLD_MAX_STABLE_ENDPOINTS_PER_ROOT)) * ZT_WORLD_MAX_ROOTS) + ZT_C25519_PUBLIC_KEY_LEN + ZT_C25519_SIGNATURE_LEN + 128) +#define ZT_WORLD_MAX_SERIALIZED_LENGTH (((1024 + (32 * ZT_WORLD_MAX_STABLE_ENDPOINTS_PER_ROOT)) * ZT_WORLD_MAX_ROOTS) + ZT_ECC_PUBLIC_KEY_SET_LEN + ZT_ECC_SIGNATURE_LEN + 128) /** * World ID for Earth @@ -150,7 +150,7 @@ class World { /** * @return C25519 signature */ - inline const C25519::Signature& signature() const + inline const ECC::Signature& signature() const { return _signature; } @@ -158,7 +158,7 @@ class World { /** * @return Public key that must sign next update */ - inline const C25519::Public& updatesMustBeSignedBy() const + inline const ECC::Public& updatesMustBeSignedBy() const { return _updatesMustBeSignedBy; } @@ -177,7 +177,7 @@ class World { if ((_id == update._id) && (_ts < update._ts) && (_type == update._type)) { Buffer tmp; update.serialize(tmp, true); - return C25519::verify(_updatesMustBeSignedBy, tmp.data(), tmp.size(), update._signature); + return ECC::verify(_updatesMustBeSignedBy, tmp.data(), tmp.size(), update._signature); } return false; } @@ -199,9 +199,9 @@ class World { b.append((uint8_t)_type); b.append((uint64_t)_id); b.append((uint64_t)_ts); - b.append(_updatesMustBeSignedBy.data, ZT_C25519_PUBLIC_KEY_LEN); + b.append(_updatesMustBeSignedBy.data, ZT_ECC_PUBLIC_KEY_SET_LEN); if (! forSign) { - b.append(_signature.data, ZT_C25519_SIGNATURE_LEN); + b.append(_signature.data, ZT_ECC_SIGNATURE_LEN); } b.append((uint8_t)_roots.size()); for (std::vector::const_iterator r(_roots.begin()); r != _roots.end(); ++r) { @@ -244,10 +244,10 @@ class World { p += 8; _ts = b.template at(p); p += 8; - memcpy(_updatesMustBeSignedBy.data, b.field(p, ZT_C25519_PUBLIC_KEY_LEN), ZT_C25519_PUBLIC_KEY_LEN); - p += ZT_C25519_PUBLIC_KEY_LEN; - memcpy(_signature.data, b.field(p, ZT_C25519_SIGNATURE_LEN), ZT_C25519_SIGNATURE_LEN); - p += ZT_C25519_SIGNATURE_LEN; + memcpy(_updatesMustBeSignedBy.data, b.field(p, ZT_ECC_PUBLIC_KEY_SET_LEN), ZT_ECC_PUBLIC_KEY_SET_LEN); + p += ZT_ECC_PUBLIC_KEY_SET_LEN; + memcpy(_signature.data, b.field(p, ZT_ECC_SIGNATURE_LEN), ZT_ECC_SIGNATURE_LEN); + p += ZT_ECC_SIGNATURE_LEN; const unsigned int numRoots = (unsigned int)b[p++]; if (numRoots > ZT_WORLD_MAX_ROOTS) { throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW; @@ -275,7 +275,7 @@ class World { inline bool operator==(const World& w) const { return ( - (_id == w._id) && (_ts == w._ts) && (memcmp(_updatesMustBeSignedBy.data, w._updatesMustBeSignedBy.data, ZT_C25519_PUBLIC_KEY_LEN) == 0) && (memcmp(_signature.data, w._signature.data, ZT_C25519_SIGNATURE_LEN) == 0) + (_id == w._id) && (_ts == w._ts) && (memcmp(_updatesMustBeSignedBy.data, w._updatesMustBeSignedBy.data, ZT_ECC_PUBLIC_KEY_SET_LEN) == 0) && (memcmp(_signature.data, w._signature.data, ZT_ECC_SIGNATURE_LEN) == 0) && (_roots == w._roots) && (_type == w._type)); } inline bool operator!=(const World& w) const @@ -294,7 +294,7 @@ class World { * @param signWith Key to sign this World with (can have the same public as the next-update signing key, but doesn't have to) * @return Signed World object */ - static inline World make(World::Type t, uint64_t id, uint64_t ts, const C25519::Public& sk, const std::vector& roots, const C25519::Pair& signWith) + static inline World make(World::Type t, uint64_t id, uint64_t ts, const ECC::Public& sk, const std::vector& roots, const ECC::Pair& signWith) { World w; w._id = id; @@ -305,7 +305,7 @@ class World { Buffer tmp; w.serialize(tmp, true); - w._signature = C25519::sign(signWith, tmp.data(), tmp.size()); + w._signature = ECC::sign(signWith, tmp.data(), tmp.size()); return w; } @@ -314,8 +314,8 @@ class World { uint64_t _id; uint64_t _ts; Type _type; - C25519::Public _updatesMustBeSignedBy; - C25519::Signature _signature; + ECC::Public _updatesMustBeSignedBy; + ECC::Signature _signature; std::vector _roots; }; diff --git a/objects.mk b/objects.mk index 4c9d2f88e..bba4c6fa3 100644 --- a/objects.mk +++ b/objects.mk @@ -2,7 +2,7 @@ CORE_OBJS=\ node/AES.o \ node/AES_aesni.o \ node/AES_armcrypto.o \ - node/C25519.o \ + node/ECC.o \ node/Capability.o \ node/CertificateOfMembership.o \ node/CertificateOfOwnership.o \ diff --git a/one.cpp b/one.cpp index 2e4e63847..0b99f32b1 100644 --- a/one.cpp +++ b/one.cpp @@ -13,6 +13,7 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE +#include "node/ECC.hpp" #endif #include @@ -25,6 +26,7 @@ #include "node/Constants.hpp" #ifdef __WINDOWS__ +// clang-format off #include #include #include @@ -39,6 +41,7 @@ #include "windows/ZeroTierOne/ServiceInstaller.h" #include "windows/ZeroTierOne/ServiceBase.h" #include "windows/ZeroTierOne/ZeroTierOneService.h" +// clang-format on #else #include #include @@ -1552,9 +1555,9 @@ static int idtool(int argc,char **argv) fprintf(stderr,"%s is not readable" ZT_EOL_S,argv[3]); return 1; } - C25519::Signature signature = id.sign(inf.data(),(unsigned int)inf.length()); + ECC::Signature signature = id.sign(inf.data(),(unsigned int)inf.length()); char hexbuf[1024]; - printf("%s",Utils::hex(signature.data,ZT_C25519_SIGNATURE_LEN,hexbuf)); + printf("%s",Utils::hex(signature.data,ZT_ECC_SIGNATURE_LEN,hexbuf)); } else if (!strcmp(argv[1],"verify")) { if (argc < 5) { idtoolPrintHelp(stdout,argv[0]); @@ -1602,14 +1605,14 @@ static int idtool(int argc,char **argv) return 1; } - C25519::Pair kp(C25519::generate()); + ECC::Pair kp(ECC::generate()); char idtmp[4096]; nlohmann::json mj; mj["objtype"] = "world"; mj["worldType"] = "moon"; - mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,ZT_C25519_PUBLIC_KEY_LEN,idtmp); - mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,ZT_C25519_PRIVATE_KEY_LEN,idtmp); + mj["updatesMustBeSignedBy"] = mj["signingKey"] = Utils::hex(kp.pub.data,ZT_ECC_PUBLIC_KEY_SET_LEN,idtmp); + mj["signingKey_SECRET"] = Utils::hex(kp.priv.data,ZT_ECC_PRIVATE_KEY_SET_LEN,idtmp); mj["id"] = id.address().toString(idtmp); nlohmann::json seedj; seedj["identity"] = id.toString(false,idtmp); @@ -1646,11 +1649,11 @@ static int idtool(int argc,char **argv) return 1; } - C25519::Pair signingKey; - C25519::Public updatesMustBeSignedBy; - Utils::unhex(OSUtils::jsonString(mj["signingKey"],"").c_str(),signingKey.pub.data,ZT_C25519_PUBLIC_KEY_LEN); - Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],"").c_str(),signingKey.priv.data,ZT_C25519_PRIVATE_KEY_LEN); - Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],"").c_str(),updatesMustBeSignedBy.data,ZT_C25519_PUBLIC_KEY_LEN); + ECC::Pair signingKey; + ECC::Public updatesMustBeSignedBy; + Utils::unhex(OSUtils::jsonString(mj["signingKey"],"").c_str(),signingKey.pub.data,ZT_ECC_PUBLIC_KEY_SET_LEN); + Utils::unhex(OSUtils::jsonString(mj["signingKey_SECRET"],"").c_str(),signingKey.priv.data,ZT_ECC_PRIVATE_KEY_SET_LEN); + Utils::unhex(OSUtils::jsonString(mj["updatesMustBeSignedBy"],"").c_str(),updatesMustBeSignedBy.data,ZT_ECC_PUBLIC_KEY_SET_LEN); std::vector roots; nlohmann::json &rootsj = mj["roots"]; diff --git a/selftest.cpp b/selftest.cpp index 0a18caa74..1c5f7c1a1 100644 --- a/selftest.cpp +++ b/selftest.cpp @@ -11,42 +11,40 @@ */ /****/ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "node/Constants.hpp" -#include "node/Hashtable.hpp" -#include "node/RuntimeEnvironment.hpp" -#include "node/InetAddress.hpp" -#include "node/Utils.hpp" -#include "node/Identity.hpp" #include "node/Buffer.hpp" -#include "node/Packet.hpp" -#include "node/Salsa20.hpp" +#include "node/CertificateOfMembership.hpp" +#include "node/Constants.hpp" +#include "node/Dictionary.hpp" +#include "node/ECC.hpp" +#include "node/Hashtable.hpp" +#include "node/Identity.hpp" +#include "node/IncomingPacket.hpp" +#include "node/InetAddress.hpp" #include "node/MAC.hpp" #include "node/NetworkConfig.hpp" -#include "node/Peer.hpp" -#include "node/Dictionary.hpp" -#include "node/SHA512.hpp" -#include "node/C25519.hpp" -#include "node/Poly1305.hpp" -#include "node/CertificateOfMembership.hpp" #include "node/Node.hpp" -#include "node/IncomingPacket.hpp" - +#include "node/Packet.hpp" +#include "node/Peer.hpp" +#include "node/Poly1305.hpp" +#include "node/RuntimeEnvironment.hpp" +#include "node/SHA512.hpp" +#include "node/Salsa20.hpp" +#include "node/Utils.hpp" #include "osdep/OSUtils.hpp" #include "osdep/Phy.hpp" #include "osdep/PortMapper.hpp" #include "osdep/Thread.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + #if defined(ZT_USE_X64_ASM_SALSA2012) && defined(ZT_ARCH_X64) #include "ext/x64-salsa2012-asm/salsa2012.h" #endif @@ -62,653 +60,1174 @@ using namespace ZeroTier; ////////////////////////////////////////////////////////////////////////////// -#define KNOWN_GOOD_IDENTITY "8e4df28b72:0:ac3d46abe0c21f3cfe7a6c8d6a85cfcffcb82fbd55af6a4d6350657c68200843fa2e16f9418bbd9702cae365f2af5fb4c420908b803a681d4daef6114d78a2d7:bd8dd6e4ce7022d2f812797a80c6ee8ad180dc4ebf301dec8b06d1be08832bddd63a2f1cfa7b2c504474c75bdc8898ba476ef92e8e2d0509f8441985171ff16e" -#define KNOWN_BAD_IDENTITY "9e4df28b72:0:ac3d46abe0c21f3cfe7a6c8d6a85cfcffcb82fbd55af6a4d6350657c68200843fa2e16f9418bbd9702cae365f2af5fb4c420908b803a681d4daef6114d78a2d7:bd8dd6e4ce7022d2f812797a80c6ee8ad180dc4ebf301dec8b06d1be08832bddd63a2f1cfa7b2c504474c75bdc8898ba476ef92e8e2d0509f8441985171ff16e" +#define KNOWN_GOOD_IDENTITY \ + "8e4df28b72:0:ac3d46abe0c21f3cfe7a6c8d6a85cfcffcb82fbd55af6a4d6350657c68200843fa2e16f9418bbd9702cae365f2af5fb4c420908b803a681d4daef6114d78a2d7:" \ + "bd8dd6e4ce7022d2f812797a80c6ee8ad180dc4ebf301dec8b06d1be08832bddd63a2f1cfa7b2c504474c75bdc8898ba476ef92e8e2d0509f8441985171ff16e" +#define KNOWN_BAD_IDENTITY \ + "9e4df28b72:0:ac3d46abe0c21f3cfe7a6c8d6a85cfcffcb82fbd55af6a4d6350657c68200843fa2e16f9418bbd9702cae365f2af5fb4c420908b803a681d4daef6114d78a2d7:" \ + "bd8dd6e4ce7022d2f812797a80c6ee8ad180dc4ebf301dec8b06d1be08832bddd63a2f1cfa7b2c504474c75bdc8898ba476ef92e8e2d0509f8441985171ff16e" -static const unsigned char s20TV0Key[32] = { 0x0f,0x62,0xb5,0x08,0x5b,0xae,0x01,0x54,0xa7,0xfa,0x4d,0xa0,0xf3,0x46,0x99,0xec,0x3f,0x92,0xe5,0x38,0x8b,0xde,0x31,0x84,0xd7,0x2a,0x7d,0xd0,0x23,0x76,0xc9,0x1c }; -static const unsigned char s20TV0Iv[8] = { 0x28,0x8f,0xf6,0x5d,0xc4,0x2b,0x92,0xf9 }; -static const unsigned char s20TV0Ks[64] = { 0x5e,0x5e,0x71,0xf9,0x01,0x99,0x34,0x03,0x04,0xab,0xb2,0x2a,0x37,0xb6,0x62,0x5b,0xf8,0x83,0xfb,0x89,0xce,0x3b,0x21,0xf5,0x4a,0x10,0xb8,0x10,0x66,0xef,0x87,0xda,0x30,0xb7,0x76,0x99,0xaa,0x73,0x79,0xda,0x59,0x5c,0x77,0xdd,0x59,0x54,0x2d,0xa2,0x08,0xe5,0x95,0x4f,0x89,0xe4,0x0e,0xb7,0xaa,0x80,0xa8,0x4a,0x61,0x76,0x66,0x3f }; +static const unsigned char s20TV0Key[32] = { 0x0f, 0x62, 0xb5, 0x08, 0x5b, 0xae, 0x01, 0x54, 0xa7, 0xfa, 0x4d, 0xa0, 0xf3, 0x46, 0x99, 0xec, 0x3f, 0x92, 0xe5, 0x38, 0x8b, 0xde, 0x31, 0x84, 0xd7, 0x2a, 0x7d, 0xd0, 0x23, 0x76, 0xc9, 0x1c }; +static const unsigned char s20TV0Iv[8] = { 0x28, 0x8f, 0xf6, 0x5d, 0xc4, 0x2b, 0x92, 0xf9 }; +static const unsigned char s20TV0Ks[64] = { 0x5e, 0x5e, 0x71, 0xf9, 0x01, 0x99, 0x34, 0x03, 0x04, 0xab, 0xb2, 0x2a, 0x37, 0xb6, 0x62, 0x5b, 0xf8, 0x83, 0xfb, 0x89, 0xce, 0x3b, 0x21, 0xf5, 0x4a, 0x10, 0xb8, 0x10, 0x66, 0xef, 0x87, 0xda, + 0x30, 0xb7, 0x76, 0x99, 0xaa, 0x73, 0x79, 0xda, 0x59, 0x5c, 0x77, 0xdd, 0x59, 0x54, 0x2d, 0xa2, 0x08, 0xe5, 0x95, 0x4f, 0x89, 0xe4, 0x0e, 0xb7, 0xaa, 0x80, 0xa8, 0x4a, 0x61, 0x76, 0x66, 0x3f }; -static const unsigned char s2012TV0Key[32] = { 0x0f,0x62,0xb5,0x08,0x5b,0xae,0x01,0x54,0xa7,0xfa,0x4d,0xa0,0xf3,0x46,0x99,0xec,0x3f,0x92,0xe5,0x38,0x8b,0xde,0x31,0x84,0xd7,0x2a,0x7d,0xd0,0x23,0x76,0xc9,0x1c }; -static const unsigned char s2012TV0Iv[8] = { 0x28,0x8f,0xf6,0x5d,0xc4,0x2b,0x92,0xf9 }; -static const unsigned char s2012TV0Ks[64] = { 0x99,0xDB,0x33,0xAD,0x11,0xCE,0x0C,0xCB,0x3B,0xFD,0xBF,0x8D,0x0C,0x18,0x16,0x04,0x52,0xD0,0x14,0xCD,0xE9,0x89,0xB4,0xC4,0x11,0xA5,0x59,0xFF,0x7C,0x20,0xA1,0x69,0xE6,0xDC,0x99,0x09,0xD8,0x16,0xBE,0xCE,0xDC,0x40,0x63,0xCE,0x07,0xCE,0xA8,0x28,0xF4,0x4B,0xF9,0xB6,0xC9,0xA0,0xA0,0xB2,0x00,0xE1,0xB5,0x2A,0xF4,0x18,0x59,0xC5 }; +static const unsigned char s2012TV0Key[32] = { 0x0f, 0x62, 0xb5, 0x08, 0x5b, 0xae, 0x01, 0x54, 0xa7, 0xfa, 0x4d, 0xa0, 0xf3, 0x46, 0x99, 0xec, 0x3f, 0x92, 0xe5, 0x38, 0x8b, 0xde, 0x31, 0x84, 0xd7, 0x2a, 0x7d, 0xd0, 0x23, 0x76, 0xc9, 0x1c }; +static const unsigned char s2012TV0Iv[8] = { 0x28, 0x8f, 0xf6, 0x5d, 0xc4, 0x2b, 0x92, 0xf9 }; +static const unsigned char s2012TV0Ks[64] = { 0x99, 0xDB, 0x33, 0xAD, 0x11, 0xCE, 0x0C, 0xCB, 0x3B, 0xFD, 0xBF, 0x8D, 0x0C, 0x18, 0x16, 0x04, 0x52, 0xD0, 0x14, 0xCD, 0xE9, 0x89, 0xB4, 0xC4, 0x11, 0xA5, 0x59, 0xFF, 0x7C, 0x20, 0xA1, 0x69, + 0xE6, 0xDC, 0x99, 0x09, 0xD8, 0x16, 0xBE, 0xCE, 0xDC, 0x40, 0x63, 0xCE, 0x07, 0xCE, 0xA8, 0x28, 0xF4, 0x4B, 0xF9, 0xB6, 0xC9, 0xA0, 0xA0, 0xB2, 0x00, 0xE1, 0xB5, 0x2A, 0xF4, 0x18, 0x59, 0xC5 }; -static const unsigned char poly1305TV0Input[32] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -static const unsigned char poly1305TV0Key[32] = { 0x74,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x33,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b,0x65,0x79,0x20,0x66,0x6f,0x72,0x20,0x50,0x6f,0x6c,0x79,0x31,0x33,0x30,0x35 }; -static const unsigned char poly1305TV0Tag[16] = { 0x49,0xec,0x78,0x09,0x0e,0x48,0x1e,0xc6,0xc2,0x6b,0x33,0xb9,0x1c,0xcc,0x03,0x07 }; +static const unsigned char poly1305TV0Input[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const unsigned char poly1305TV0Key[32] = { + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x33, 0x32, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x50, 0x6f, 0x6c, 0x79, 0x31, 0x33, 0x30, 0x35 +}; +static const unsigned char poly1305TV0Tag[16] = { 0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03, 0x07 }; -static const unsigned char poly1305TV1Input[12] = { 0x48,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,0x6c,0x64,0x21 }; -static const unsigned char poly1305TV1Key[32] = { 0x74,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x33,0x32,0x2d,0x62,0x79,0x74,0x65,0x20,0x6b,0x65,0x79,0x20,0x66,0x6f,0x72,0x20,0x50,0x6f,0x6c,0x79,0x31,0x33,0x30,0x35 }; -static const unsigned char poly1305TV1Tag[16] = { 0xa6,0xf7,0x45,0x00,0x8f,0x81,0xc9,0x16,0xa2,0x0d,0xcc,0x74,0xee,0xf2,0xb2,0xf0 }; +static const unsigned char poly1305TV1Input[12] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21 }; +static const unsigned char poly1305TV1Key[32] = { + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x33, 0x32, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x50, 0x6f, 0x6c, 0x79, 0x31, 0x33, 0x30, 0x35 +}; +static const unsigned char poly1305TV1Tag[16] = { 0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2, 0xf0 }; -static const char *sha512TV0Input = "supercalifragilisticexpealidocious"; -static const unsigned char sha512TV0Digest[64] = { 0x18,0x2a,0x85,0x59,0x69,0xe5,0xd3,0xe6,0xcb,0xf6,0x05,0x24,0xad,0xf2,0x88,0xd1,0xbb,0xf2,0x52,0x92,0x81,0x24,0x31,0xf6,0xd2,0x52,0xf1,0xdb,0xc1,0xcb,0x44,0xdf,0x21,0x57,0x3d,0xe1,0xb0,0x6b,0x68,0x75,0x95,0x9f,0x3b,0x6f,0x87,0xb1,0x13,0x81,0xd0,0xbc,0x79,0x2c,0x43,0x3a,0x13,0x55,0x3c,0xe0,0x84,0xc2,0x92,0x55,0x31,0x1c }; +static const char* sha512TV0Input = "supercalifragilisticexpealidocious"; +static const unsigned char sha512TV0Digest[64] = { 0x18, 0x2a, 0x85, 0x59, 0x69, 0xe5, 0xd3, 0xe6, 0xcb, 0xf6, 0x05, 0x24, 0xad, 0xf2, 0x88, 0xd1, 0xbb, 0xf2, 0x52, 0x92, 0x81, 0x24, + 0x31, 0xf6, 0xd2, 0x52, 0xf1, 0xdb, 0xc1, 0xcb, 0x44, 0xdf, 0x21, 0x57, 0x3d, 0xe1, 0xb0, 0x6b, 0x68, 0x75, 0x95, 0x9f, 0x3b, 0x6f, + 0x87, 0xb1, 0x13, 0x81, 0xd0, 0xbc, 0x79, 0x2c, 0x43, 0x3a, 0x13, 0x55, 0x3c, 0xe0, 0x84, 0xc2, 0x92, 0x55, 0x31, 0x1c }; -struct C25519TestVector -{ - unsigned char pub1[64]; - unsigned char priv1[64]; - unsigned char pub2[64]; - unsigned char priv2[64]; - unsigned char agreement[64]; - unsigned char agreementSignedBy1[96]; - unsigned char agreementSignedBy2[96]; +struct C25519TestVector { + unsigned char pub1[64]; + unsigned char priv1[64]; + unsigned char pub2[64]; + unsigned char priv2[64]; + unsigned char agreement[64]; + unsigned char agreementSignedBy1[96]; + unsigned char agreementSignedBy2[96]; }; #define ZT_NUM_C25519_TEST_VECTORS 32 static const C25519TestVector C25519_TEST_VECTORS[ZT_NUM_C25519_TEST_VECTORS] = { - {{0xa1,0xfc,0x7a,0xb4,0x6d,0xdf,0x7d,0xcf,0xe7,0xec,0x75,0xe5,0xfa,0xdd,0x11,0xcb,0xcc,0x37,0xf8,0x84,0x5d,0x1c,0x92,0x4e,0x09,0x89,0x65,0xfc,0xd8,0xe9,0x5a,0x30,0xda,0xe4,0x86,0xa3,0x35,0xb4,0x19,0x0c,0xbc,0x7b,0xcb,0x3e,0xb9,0x4c,0xbd,0x16,0xe8,0x3d,0x13,0x2b,0xc9,0xc3,0x39,0xea,0xf1,0x42,0xe7,0x6f,0x69,0x78,0x9a,0xb7},{0xe5,0xf3,0x7b,0xd4,0x0e,0xc9,0xdc,0x77,0x50,0x86,0xdc,0xf4,0x2e,0xbc,0xdb,0x27,0xf0,0x73,0xd4,0x58,0x73,0xc4,0x4b,0x71,0x8b,0x3c,0xc5,0x4f,0xa8,0x7c,0xa4,0x84,0xd9,0x96,0x23,0x73,0xb4,0x03,0x16,0xbf,0x1e,0xa1,0x2d,0xd8,0xc4,0x8a,0xe7,0x82,0x10,0xda,0xc9,0xe5,0x45,0x9b,0x01,0xdc,0x73,0xa6,0xc9,0x17,0xa8,0x15,0x31,0x6d},{0x3e,0x49,0xa4,0x0e,0x3a,0xaf,0xa3,0x07,0x3d,0xf7,0x2a,0xec,0x43,0xb1,0xd4,0x09,0x1a,0xcb,0x8e,0x92,0xf9,0x65,0x95,0x04,0x6d,0x2d,0x9b,0x34,0xa3,0xbf,0x51,0x00,0xe2,0xee,0x23,0xf5,0x28,0x0a,0xa9,0xb1,0x57,0x0b,0x96,0x56,0x62,0xba,0x12,0x94,0xaf,0xc6,0x5f,0xb5,0x61,0x43,0x0f,0xde,0x0b,0xab,0xfa,0x4f,0xfe,0xc5,0xe7,0x18},{0x00,0x4d,0x41,0x8d,0xe4,0x69,0x23,0xae,0x98,0xc4,0x3e,0x77,0x0f,0x1d,0x94,0x5d,0x29,0x3e,0x94,0x5a,0x38,0x39,0x20,0x0f,0xd3,0x6f,0x76,0xa2,0x29,0x02,0x03,0xcb,0x0b,0x7f,0x4f,0x1a,0x29,0x51,0x13,0x33,0x7c,0x99,0xb3,0x81,0x82,0x39,0x44,0x05,0x97,0xfb,0x0d,0xf2,0x93,0xa2,0x40,0x94,0xf4,0xff,0x5d,0x09,0x61,0xe4,0x5f,0x76},{0xab,0xce,0xd2,0x24,0xe8,0x93,0xb0,0xe7,0x72,0x14,0xdc,0xbb,0x7d,0x0f,0xd8,0x94,0x16,0x9e,0xb5,0x7f,0xd7,0x19,0x5f,0x3e,0x2d,0x45,0xd5,0xf7,0x90,0x0b,0x3e,0x05,0x18,0x2e,0x2b,0xf4,0xfa,0xd4,0xec,0x62,0x4a,0x4f,0x48,0x50,0xaf,0x1c,0xe8,0x9f,0x1a,0xe1,0x3d,0x70,0x49,0x00,0xa7,0xe3,0x5b,0x1e,0xa1,0x9b,0x68,0x1e,0xa1,0x73},{0xed,0xb6,0xd0,0xf0,0x06,0x6e,0x33,0x9c,0x86,0xfb,0xe8,0xc3,0x6c,0x8d,0xde,0xdd,0xa6,0xa0,0x2d,0xb9,0x07,0x29,0xa3,0x13,0xbb,0xa4,0xba,0xec,0x48,0xc8,0xf4,0x56,0x82,0x79,0xe2,0xb1,0xd3,0x3d,0x83,0x9f,0x10,0xe8,0x52,0xe6,0x8b,0x1c,0x33,0x9e,0x2b,0xd2,0xdb,0x62,0x1c,0x56,0xfd,0x50,0x40,0x77,0x81,0xab,0x21,0x67,0x3e,0x09,0x4f,0xf2,0x51,0xac,0x7d,0xe7,0xd1,0x5d,0x4b,0xe2,0x08,0xc6,0x3f,0x6a,0x4d,0xc8,0x5d,0x74,0xf6,0x3b,0xec,0x8e,0xc6,0x0c,0x32,0x27,0x2f,0x9c,0x09,0x48,0x59,0x10},{0x23,0x0f,0xa3,0xe2,0x69,0xce,0xb9,0xb9,0xd1,0x1c,0x4e,0xab,0x63,0xc9,0x2e,0x1e,0x7e,0xa2,0xa2,0xa0,0x49,0x2e,0x78,0xe4,0x8a,0x02,0x3b,0xa7,0xab,0x1f,0xd4,0xce,0x05,0xe2,0x80,0x09,0x09,0x3c,0x61,0xc7,0x10,0x3a,0x9c,0xf4,0x95,0xac,0x89,0x6f,0x23,0xb3,0x09,0xe2,0x24,0x3f,0xf6,0x96,0x02,0x36,0x41,0x16,0x32,0xe1,0x66,0x05,0x4f,0xf2,0x51,0xac,0x7d,0xe7,0xd1,0x5d,0x4b,0xe2,0x08,0xc6,0x3f,0x6a,0x4d,0xc8,0x5d,0x74,0xf6,0x3b,0xec,0x8e,0xc6,0x0c,0x32,0x27,0x2f,0x9c,0x09,0x48,0x59,0x10}}, - {{0xfd,0x81,0x14,0xf1,0x67,0x07,0x44,0xbb,0x93,0x84,0xa2,0xdc,0x36,0xdc,0xcc,0xb3,0x9e,0x82,0xd4,0x8b,0x42,0x56,0xfb,0xf2,0x6e,0x83,0x3b,0x16,0x2c,0x29,0xfb,0x39,0x29,0x48,0x85,0xe3,0xe3,0xf7,0xe7,0x80,0x49,0xd3,0x01,0x30,0x5a,0x2c,0x3f,0x4c,0xea,0x13,0xeb,0xda,0xf4,0x56,0x75,0x8d,0x50,0x1e,0x19,0x2d,0x29,0x2b,0xfb,0xdb},{0x85,0x34,0x4d,0xf7,0x39,0xbf,0x98,0x79,0x8c,0x98,0xeb,0x8d,0x61,0x27,0xec,0x87,0x56,0xcd,0xd0,0xa6,0x55,0x77,0xee,0xf0,0x20,0xd0,0x59,0x39,0x95,0xab,0x29,0x82,0x8e,0x61,0xf8,0xad,0xed,0xb6,0x27,0xc3,0xd8,0x16,0xce,0x67,0x78,0xe2,0x04,0x4b,0x0c,0x2d,0x2f,0xc3,0x24,0x72,0xbc,0x53,0xbd,0xfe,0x39,0x23,0xd4,0xaf,0x27,0x84},{0x11,0xbe,0x5f,0x5a,0x73,0xe7,0x42,0xef,0xff,0x3c,0x47,0x6a,0x0e,0x6b,0x9e,0x96,0x21,0xa3,0xdf,0x49,0xe9,0x3f,0x40,0xfc,0xab,0xb3,0x66,0xd3,0x3d,0xfa,0x02,0x29,0xf3,0x43,0x45,0x3c,0x70,0xa3,0x5d,0x39,0xf7,0xc0,0x6a,0xcd,0xfa,0x1d,0xbe,0x3b,0x91,0x41,0xe4,0xb0,0x60,0xc0,0x22,0xf7,0x2c,0x11,0x2b,0x1c,0x5f,0x24,0xef,0x53},{0xfd,0x3f,0x09,0x06,0xc9,0x39,0x8d,0x48,0xfa,0x6b,0xc9,0x80,0xbf,0xf6,0xd6,0x76,0xb3,0x62,0x70,0x88,0x4f,0xde,0xde,0xb9,0xb4,0xf0,0xce,0xf3,0x74,0x0d,0xea,0x00,0x9e,0x9c,0x29,0xe1,0xa2,0x1b,0xbd,0xb5,0x83,0xcc,0x12,0xd8,0x48,0x08,0x5b,0xe5,0xd6,0xf9,0x11,0x5c,0xe0,0xd9,0xc3,0x3c,0x26,0xbd,0x69,0x9f,0x5c,0x6f,0x0c,0x6f},{0xca,0xd4,0x76,0x32,0x8b,0xbe,0x0c,0x65,0x75,0x43,0x73,0xc2,0xf2,0xfd,0x7f,0xeb,0xe4,0x62,0xc5,0x0d,0x0f,0xf9,0x01,0xc8,0xb9,0xfa,0xca,0xb4,0x12,0x1c,0xb4,0xac,0x0e,0x5f,0x18,0xfc,0x0c,0x7f,0x2a,0x55,0xc5,0xfd,0x4d,0x83,0xb2,0x02,0x31,0x6a,0x3f,0x14,0xee,0x9d,0x11,0xa8,0x06,0xad,0xeb,0x93,0x19,0x79,0xb1,0xf2,0x78,0x05},{0x85,0xe6,0xe2,0xf2,0x96,0xe7,0xa2,0x8b,0x7e,0x36,0xbd,0x7b,0xf4,0x28,0x6a,0xd7,0xbc,0x2a,0x6a,0x59,0xfd,0xc0,0xc8,0x3d,0x50,0x0f,0x0c,0x2b,0x12,0x3a,0x75,0xc7,0x56,0xbb,0x7f,0x7d,0x4e,0xd4,0x03,0xb8,0x7b,0xde,0xde,0x99,0x65,0x9e,0xc4,0xa6,0x6e,0xfe,0x00,0x88,0xeb,0x9d,0xa4,0xa9,0x9d,0x37,0xc9,0x4a,0xcf,0x69,0xc4,0x01,0xba,0xa8,0xce,0xeb,0x72,0xcb,0x64,0x8b,0x9f,0xc1,0x1f,0x9a,0x9e,0x99,0xcc,0x39,0xec,0xd9,0xbb,0xd9,0xce,0xc2,0x74,0x6f,0xd0,0x2a,0xb9,0xc6,0xe3,0xf5,0xe7,0xf4},{0xb1,0x39,0x50,0xb1,0x1a,0x08,0x42,0x2b,0xdd,0x6d,0x20,0x9f,0x0f,0x37,0xba,0x69,0x97,0x21,0x30,0x7a,0x71,0x2f,0xce,0x98,0x09,0x04,0xa2,0x98,0x6a,0xed,0x02,0x1d,0x5d,0x30,0x8f,0x03,0x47,0x6b,0x89,0xfd,0xf7,0x1a,0xca,0x46,0x6f,0x51,0x69,0x9a,0x2b,0x18,0x77,0xe4,0xad,0x0d,0x7a,0x66,0xd2,0x2c,0x28,0xa0,0xd3,0x0a,0x99,0x0d,0xba,0xa8,0xce,0xeb,0x72,0xcb,0x64,0x8b,0x9f,0xc1,0x1f,0x9a,0x9e,0x99,0xcc,0x39,0xec,0xd9,0xbb,0xd9,0xce,0xc2,0x74,0x6f,0xd0,0x2a,0xb9,0xc6,0xe3,0xf5,0xe7,0xf4}}, - {{0x02,0x3a,0x7e,0x0c,0x6d,0x96,0x3c,0x5d,0x44,0x56,0x5d,0xc1,0x49,0x94,0x35,0x12,0x9d,0xff,0x8a,0x5d,0x91,0x74,0xa8,0x15,0xee,0x5d,0x1e,0x72,0xbe,0x86,0x15,0x68,0xe7,0x36,0xa2,0x4a,0xb8,0xa2,0xa4,0x4c,0xd8,0x95,0xe3,0xc7,0xbb,0x32,0x21,0x90,0x64,0x52,0x32,0xeb,0x26,0xd3,0x4f,0xf0,0x8e,0x27,0x40,0xea,0xed,0xdb,0xf5,0xc4},{0x76,0x99,0x64,0x70,0xf4,0x50,0xc8,0xcc,0x4a,0x5a,0xa5,0x0f,0xeb,0x2d,0xc7,0x0e,0x73,0xd0,0x65,0x7d,0xc3,0xce,0x73,0x03,0x20,0x2f,0xad,0x65,0xfd,0x12,0xe4,0x7f,0xfd,0x45,0x3a,0x6e,0xc5,0x9a,0x06,0x67,0x0e,0xa6,0x7b,0x21,0x49,0x2d,0x01,0x1b,0x8e,0x03,0x6e,0x10,0x08,0x0c,0x68,0xd9,0x60,0x47,0xa4,0xe2,0x52,0xfd,0x3c,0xf4},{0xa3,0xe2,0x5f,0x16,0x39,0x78,0x96,0xf7,0x47,0x6f,0x93,0x5d,0x27,0x7b,0x58,0xe0,0xc5,0xdb,0x71,0x7d,0xa9,0x6f,0xf8,0x8b,0x69,0xdd,0x50,0xea,0x91,0x0d,0x66,0x77,0xaf,0x8f,0xd5,0x9f,0x8a,0x26,0x69,0x4c,0x64,0x37,0x62,0x81,0x6f,0x05,0x9a,0x08,0x0d,0xe1,0x69,0x24,0x77,0x3f,0x50,0xb2,0x49,0x4d,0x93,0xef,0x2e,0x87,0xff,0xde},{0xb3,0x32,0xe2,0x67,0x79,0x32,0x5f,0x64,0x47,0x49,0x1c,0xd3,0x8f,0x95,0x44,0xfd,0x4c,0x7e,0xbf,0x6b,0xb7,0xaf,0x2c,0xdd,0x8f,0xa5,0xd8,0x2f,0xbf,0xa0,0x8a,0x6b,0x58,0x25,0xc9,0x12,0x23,0x6f,0xe6,0x05,0xa8,0xd0,0x68,0x6e,0x0c,0xee,0x70,0xe4,0xa3,0x86,0x51,0x04,0x6d,0xca,0xd5,0xed,0xcf,0x74,0x1d,0x60,0x9e,0x86,0x2d,0x05},{0x91,0xf4,0x5f,0x4a,0xcb,0xd8,0xfd,0x5f,0xb9,0x3d,0x04,0xb8,0xec,0x35,0x85,0x4f,0x58,0x20,0xd1,0x1f,0x47,0xc4,0xf4,0xcb,0x21,0x4e,0x9a,0xf1,0x6e,0xbf,0xe3,0xd3,0x62,0xe3,0x82,0xf6,0xba,0xa8,0xdf,0x92,0xe2,0x3c,0xe5,0xf0,0x16,0x8a,0xeb,0xa4,0xbb,0xc7,0x81,0xaf,0x15,0x19,0x87,0x5f,0xb7,0xe0,0x4c,0x12,0xff,0x2c,0xa9,0xc8},{0xaf,0x85,0xe0,0x36,0x43,0xdf,0x41,0x17,0xda,0xde,0x5e,0xb6,0x33,0xd0,0xce,0x62,0x70,0x5f,0x85,0x24,0x6c,0x3e,0x1b,0xe1,0x52,0xc1,0x9b,0x1c,0xcd,0x61,0x80,0x9c,0xa0,0xe8,0x18,0xee,0x40,0x91,0x93,0x82,0xdb,0x33,0x44,0xff,0xd4,0xf6,0x6f,0x5d,0xf0,0x0e,0x92,0x92,0x81,0x55,0x46,0x06,0xac,0x58,0x81,0x3b,0x04,0xc7,0xf7,0x0d,0xd2,0x0c,0x08,0x6d,0x46,0xdb,0x43,0x28,0x31,0xd8,0xcd,0x87,0x50,0xbb,0xd3,0x07,0xf5,0x72,0x0b,0x15,0x7c,0x16,0xab,0x03,0xd9,0x4b,0x07,0x38,0x97,0xe8,0xd6,0xb5},{0x93,0xff,0x6d,0xc3,0x62,0xf7,0xcc,0x20,0x95,0xc2,0x2f,0x7d,0x1d,0x9b,0xd1,0x63,0xfc,0x61,0x47,0xb3,0x22,0x0f,0xca,0xb0,0x16,0xcf,0x29,0x53,0x46,0x97,0xb1,0x36,0x46,0xac,0x48,0x13,0x92,0xe4,0x46,0x68,0xcf,0x09,0x4e,0xfa,0x59,0x45,0x24,0x08,0xdb,0xb4,0x6f,0x20,0x55,0x12,0xd9,0x75,0x9d,0x8e,0x0b,0xf8,0x63,0xe0,0xf9,0x01,0xd2,0x0c,0x08,0x6d,0x46,0xdb,0x43,0x28,0x31,0xd8,0xcd,0x87,0x50,0xbb,0xd3,0x07,0xf5,0x72,0x0b,0x15,0x7c,0x16,0xab,0x03,0xd9,0x4b,0x07,0x38,0x97,0xe8,0xd6,0xb5}}, - {{0x14,0x35,0xa6,0x7d,0xc1,0xb5,0x71,0xca,0x42,0x50,0x90,0xa7,0x72,0x85,0xbe,0x78,0x7a,0x5f,0x83,0x1e,0xbe,0xef,0x6a,0xbe,0x48,0xc5,0x68,0x14,0x0c,0xf7,0x44,0x5c,0x2e,0xfd,0x1b,0xcc,0xee,0x09,0x23,0x82,0x31,0xad,0xaf,0x4b,0x73,0x9c,0xf2,0x88,0x3c,0xf3,0xb5,0x43,0x8b,0x53,0xf9,0xac,0x17,0x86,0x1c,0xc2,0x53,0x43,0xec,0x03},{0x7b,0x36,0x6c,0xcc,0xb5,0xb2,0x23,0x3d,0x7c,0xe5,0xe7,0xcf,0x06,0xe2,0x32,0x0b,0xc5,0x3b,0x7f,0x86,0x40,0xfc,0xaf,0xba,0x94,0xe0,0x88,0x58,0x5b,0xac,0xe8,0xc3,0xe8,0xc3,0xdf,0xc4,0x45,0x29,0xe8,0xf0,0x1c,0x10,0x0d,0x50,0x81,0x29,0x30,0xa8,0x27,0xb5,0x3e,0xb8,0x25,0xf1,0x17,0x30,0xc6,0x05,0xe3,0x3e,0x45,0x38,0xa8,0x3c},{0xce,0xd9,0x45,0x28,0xb0,0xce,0xa5,0x47,0xa8,0x29,0x32,0x76,0x99,0x73,0x8d,0x74,0xf9,0xed,0x0a,0xd0,0xf1,0xd8,0x7e,0x44,0x63,0x9e,0x9a,0xcf,0x7c,0x35,0x8a,0x29,0xbb,0x71,0x66,0x8d,0xa7,0xfc,0x05,0x3d,0xd4,0x4b,0x65,0x20,0xf5,0xa4,0x64,0xd8,0x9d,0x16,0x80,0x9c,0xb2,0x3c,0x3e,0xd4,0x9d,0x09,0x88,0x8e,0xbb,0x58,0xf8,0x77},{0xe1,0x29,0xb3,0x16,0xe6,0xa0,0xdb,0x64,0x08,0x36,0xdc,0x33,0xad,0x8b,0x30,0x26,0x17,0x56,0xd7,0x34,0x17,0xd1,0xdd,0x23,0x38,0x58,0x25,0x01,0x42,0x5a,0x9d,0x18,0x3e,0xac,0x31,0xfa,0x43,0x28,0xc4,0x65,0xfb,0x30,0x2f,0x8c,0x16,0x52,0x32,0x1b,0x19,0xb7,0x31,0xf6,0x67,0xa7,0xd8,0xed,0x9a,0xa3,0x95,0x01,0xd7,0xb9,0xe7,0xcc},{0x81,0x2d,0x11,0xa9,0x11,0xf1,0x22,0xe2,0x67,0x70,0xc4,0xba,0x34,0xa1,0x75,0x8c,0xf6,0x0c,0x63,0xe7,0x01,0x3c,0x64,0x6c,0xe8,0xd0,0xf8,0x8e,0x88,0xdf,0x5c,0x61,0x68,0x5d,0x1f,0xeb,0x83,0x1f,0x40,0xb8,0xa8,0x56,0x57,0x26,0x81,0x2c,0xa3,0x0e,0x48,0x4c,0x45,0x4d,0x0d,0x3d,0x6e,0x99,0x52,0xbd,0x0b,0xd8,0x05,0xc5,0xf9,0x61},{0x92,0x45,0xbe,0xe6,0xb4,0x7a,0xfa,0x28,0xd4,0x5b,0x6b,0x17,0xc6,0x13,0x61,0x5d,0x5f,0xd7,0x90,0xbb,0x89,0x35,0x7a,0x02,0x50,0x57,0x56,0x5f,0x19,0xb5,0xb6,0xc5,0x77,0x1e,0x1b,0xc0,0xd7,0x7a,0x29,0xbd,0xe7,0x24,0x01,0x2d,0x37,0xc0,0x38,0x6f,0xc8,0x35,0xa1,0x1b,0xe0,0xea,0x16,0xad,0xbc,0xdc,0xd4,0x8d,0x4e,0x71,0xdb,0x05,0x9e,0xb5,0x53,0x6b,0x5c,0xf1,0x7d,0x15,0x8b,0xd7,0xc7,0x8b,0x89,0x9d,0xfd,0x28,0x7c,0xa1,0x31,0xe2,0xf0,0x2c,0x3a,0x8d,0x0e,0x23,0x85,0x4e,0xf0,0xd1,0xc0,0x83},{0x7b,0x88,0xeb,0x45,0x1c,0x7f,0xfd,0xbe,0xba,0xac,0x53,0x28,0x59,0xe8,0xad,0x28,0xf1,0x97,0x2d,0x6c,0x31,0xa6,0xae,0x47,0x10,0x69,0x68,0x55,0xa6,0x9c,0x03,0x62,0xb7,0x2f,0x31,0x46,0x2a,0x2b,0x98,0xdd,0xe9,0xf9,0xfe,0x77,0x71,0x41,0x54,0xf8,0x59,0x02,0x7a,0xe3,0x45,0x67,0xb6,0xf7,0x94,0x31,0x3e,0x62,0x62,0x2a,0xf9,0x0a,0x9e,0xb5,0x53,0x6b,0x5c,0xf1,0x7d,0x15,0x8b,0xd7,0xc7,0x8b,0x89,0x9d,0xfd,0x28,0x7c,0xa1,0x31,0xe2,0xf0,0x2c,0x3a,0x8d,0x0e,0x23,0x85,0x4e,0xf0,0xd1,0xc0,0x83}}, - {{0x27,0x4d,0x84,0x08,0x95,0x84,0xc8,0xeb,0x1c,0x9a,0x0f,0xca,0x09,0x6f,0x48,0x8b,0x2b,0x06,0xa0,0xae,0xf2,0xe3,0x8a,0xfe,0xd7,0x52,0x4b,0xf2,0xc6,0x7c,0xc1,0x55,0x87,0x2e,0x5a,0xb4,0xc2,0x43,0x0a,0x0d,0xd0,0x00,0xa8,0xe1,0x46,0x68,0x79,0xd8,0x8c,0x01,0x36,0xb7,0x5a,0x61,0x04,0xe9,0x7e,0xbb,0xc9,0xee,0xaa,0x12,0x13,0xda},{0x78,0x66,0xd0,0xa2,0x50,0x82,0x8d,0xb0,0xa0,0x20,0xac,0xa4,0xb6,0xa0,0x31,0xf7,0x7d,0x93,0x37,0x67,0xbb,0x60,0xa2,0x1e,0x36,0xce,0x3d,0x48,0x1d,0x79,0x99,0xa5,0x19,0xd8,0x89,0x1b,0xcb,0x14,0x87,0xb7,0x62,0xfd,0xd2,0xef,0xbb,0x13,0x41,0x4d,0xf1,0x77,0x5c,0x7f,0x6c,0x3b,0x94,0x7d,0xb4,0xba,0x87,0x3e,0xc8,0xe1,0x3c,0x0a},{0xd9,0x9e,0x14,0x89,0xd6,0xf8,0x49,0xa2,0xe2,0x19,0xfe,0x94,0xaa,0xf7,0x35,0xf9,0x4a,0xf8,0xf3,0x18,0x68,0x96,0x47,0xc6,0x23,0x7c,0xb0,0x53,0xcb,0xd8,0x90,0x31,0xb7,0x50,0x0e,0x06,0xc3,0x84,0x75,0xf1,0xac,0x16,0x4d,0xc1,0xbe,0xf1,0x80,0x33,0x47,0x56,0x6f,0x33,0x94,0x5c,0x81,0x03,0x4c,0x2f,0x6d,0xac,0x73,0xba,0x91,0x3c},{0x2f,0xa9,0xb6,0xe8,0x73,0xe2,0xef,0x6d,0x6d,0xd7,0x2e,0xa0,0x51,0x61,0x24,0x81,0x8c,0xa8,0x47,0x40,0xe1,0xc7,0x75,0x79,0xc8,0xec,0xb2,0x23,0x41,0xad,0x61,0x3b,0xea,0x8a,0xdf,0x63,0xed,0xe1,0x8e,0x50,0x70,0x6e,0x86,0xed,0xb0,0xba,0x27,0x48,0x8e,0xb9,0x63,0x39,0x78,0x58,0x4f,0x1e,0xbc,0x45,0xf3,0xf2,0x3a,0x73,0x9b,0x8c},{0xad,0x42,0xc5,0x84,0xca,0xe1,0xe1,0x23,0x2a,0x73,0x15,0x3c,0x9a,0xfe,0x85,0x8d,0xa3,0x2c,0xcf,0x46,0x8d,0x7f,0x1c,0x61,0xd7,0x0e,0xb1,0xa6,0xb4,0xae,0xab,0x63,0xc4,0x0e,0xf2,0xa0,0x5d,0xa6,0xf3,0x5d,0x35,0x41,0xea,0x03,0x91,0xb1,0x3a,0x07,0xe6,0xed,0x6c,0x8c,0xcb,0x75,0x27,0xf1,0x26,0x58,0xf0,0x62,0x57,0xe4,0x33,0x00},{0x1f,0xed,0x53,0xc6,0xef,0x38,0x26,0xa4,0x18,0x88,0x8f,0x5c,0x49,0x1c,0x15,0x7d,0x77,0x90,0x06,0x39,0xe0,0x7c,0x25,0xed,0x79,0x05,0x66,0xe0,0x5e,0x94,0xe3,0x46,0x6f,0x96,0xd8,0xc1,0x11,0xa4,0x11,0x6f,0x78,0x42,0x8e,0x89,0xc7,0xc3,0xed,0xd2,0x9e,0x68,0x47,0x79,0x89,0x23,0x70,0x14,0x21,0x60,0x2d,0xfe,0x37,0x4b,0xc8,0x0a,0x16,0x73,0x7c,0xc4,0x55,0x3f,0x25,0x04,0x08,0x75,0x74,0x68,0xbc,0xe4,0x3a,0xae,0x4c,0x0e,0xd2,0x85,0xa1,0xbc,0x81,0xc0,0xc9,0xfe,0x9a,0x44,0x7b,0x83,0xdf,0xc7},{0x27,0x77,0x97,0x84,0x0f,0x2d,0x8d,0x33,0xb8,0x4e,0xdb,0x8b,0xea,0x58,0x52,0x88,0x95,0x88,0x55,0x5f,0xb8,0xc4,0xc9,0xd6,0x1f,0x1e,0xee,0x60,0xb5,0xeb,0x78,0x72,0xb5,0xe5,0x22,0x2b,0x7f,0x5e,0xc7,0x9b,0x29,0x55,0x8e,0x2a,0xfc,0x65,0x55,0x4a,0x02,0xad,0x64,0x06,0xd4,0x25,0xe1,0x96,0x6f,0xee,0x96,0xcd,0x29,0xc6,0x64,0x00,0x16,0x73,0x7c,0xc4,0x55,0x3f,0x25,0x04,0x08,0x75,0x74,0x68,0xbc,0xe4,0x3a,0xae,0x4c,0x0e,0xd2,0x85,0xa1,0xbc,0x81,0xc0,0xc9,0xfe,0x9a,0x44,0x7b,0x83,0xdf,0xc7}}, - {{0x5e,0xc5,0x5b,0x9c,0xdb,0x14,0x05,0x18,0x6b,0xe2,0x1d,0x16,0x77,0x22,0x0e,0xd2,0xe4,0x57,0x82,0x6e,0x5b,0xc5,0x6a,0xb9,0x34,0x20,0xdb,0x72,0xe2,0xe1,0xeb,0x1b,0x34,0x00,0x04,0xbf,0x83,0xf6,0x4f,0x12,0x45,0x08,0xf0,0x95,0x2a,0xdc,0x3a,0x14,0xb3,0x29,0x0b,0x99,0xcd,0x73,0x31,0xbd,0x04,0xbb,0x49,0x1c,0xde,0xcf,0x09,0x9e},{0x15,0x80,0x3e,0x2a,0xfb,0xc0,0x8d,0x62,0x19,0x27,0x83,0x04,0xcc,0xf5,0xd1,0xbb,0x40,0x41,0xbe,0x93,0x59,0x6e,0x27,0x6d,0x95,0x24,0x0a,0x07,0x27,0x86,0x10,0x75,0xf7,0x0a,0x11,0xfc,0x53,0xd0,0x4c,0x15,0xf8,0x6e,0x22,0x3f,0xeb,0x12,0x97,0x8a,0x3d,0x69,0xd8,0x96,0xc9,0x53,0x10,0x9c,0x02,0x95,0xe4,0xd3,0x1a,0xd5,0x43,0x82},{0x40,0x09,0x2c,0x17,0x7e,0xba,0xce,0x1f,0xfc,0xc1,0x8e,0xc3,0x1c,0xa2,0x34,0x52,0x78,0x16,0x23,0x71,0x82,0x40,0xf8,0x6d,0x67,0x65,0x67,0x50,0x53,0xd9,0xc8,0x5e,0x7e,0x8a,0x98,0xa3,0xc6,0x2a,0x4d,0x27,0xf3,0xb9,0xbb,0xae,0x43,0x29,0x6e,0x02,0x1c,0xe9,0x01,0xd6,0xcd,0xd8,0x91,0x44,0x95,0x2b,0x9e,0xa5,0x4f,0xd0,0x00,0xb9},{0x3a,0xe8,0x3d,0xb3,0x32,0xdc,0xc2,0xc8,0xe3,0x36,0x2f,0xc9,0x30,0x3a,0xc0,0x76,0x56,0xd3,0x0b,0x06,0xbe,0x8f,0xe7,0xf1,0x66,0x61,0x25,0x42,0x28,0xdc,0x08,0x81,0x84,0x3a,0x57,0x96,0x27,0xa6,0xcf,0xd6,0x8f,0x35,0xa2,0xc3,0x76,0x86,0x4f,0xcf,0x5f,0xa1,0x85,0x28,0x4f,0x4a,0x3a,0xbb,0x5c,0x25,0x4b,0xcc,0x46,0xfe,0xf2,0x04},{0x62,0xc8,0xa2,0x0a,0x59,0xb8,0x97,0xd2,0x68,0x94,0x00,0x3b,0x01,0xac,0x91,0x6e,0x97,0x8e,0x08,0xe3,0xfe,0x9f,0x9e,0x9f,0x4b,0xcc,0x5d,0x1d,0xb9,0xbf,0x07,0x83,0xfe,0x51,0x2a,0xdf,0x79,0x2e,0x07,0xc9,0x98,0x9b,0xbe,0xb6,0xe4,0x0a,0x20,0x44,0x86,0xea,0xb1,0x61,0x58,0x11,0x32,0x8e,0x7b,0xb9,0x67,0x2d,0xf0,0x78,0xb2,0x93},{0x1a,0x65,0xb3,0x6f,0xa2,0x45,0x29,0x53,0xd7,0x23,0x4d,0xff,0x8e,0xe9,0xb9,0xef,0x16,0xa0,0xdd,0x48,0xdf,0x70,0xd2,0xe1,0x56,0xca,0xd1,0xd0,0x4a,0x9d,0x63,0x92,0x2b,0xfd,0x7b,0x87,0x39,0x3c,0x12,0xc7,0xe5,0x91,0x31,0x95,0x78,0xc4,0x58,0x95,0x89,0x6e,0x2c,0x90,0xb4,0x0b,0xb2,0xfe,0x52,0xc0,0x86,0xc4,0x2e,0x56,0x97,0x0c,0x20,0xf2,0xbc,0x6a,0x9b,0x89,0xfb,0xe9,0x85,0x95,0xd6,0x22,0x5e,0x4d,0x6d,0x83,0x9d,0xf4,0xbe,0x66,0x05,0x32,0xb6,0xe2,0xf1,0x96,0x42,0xa4,0xc8,0x8c,0x1b,0xec},{0x43,0x85,0xff,0xb9,0xcf,0x04,0x83,0x40,0x70,0x3a,0x9c,0x48,0xb4,0xc2,0x99,0x3b,0xa0,0x39,0xf1,0x39,0x58,0x7f,0xd2,0x49,0x94,0x3c,0xc3,0xe1,0xb6,0x56,0x38,0x55,0x6f,0xb5,0x1a,0x90,0xa2,0x04,0x2f,0x19,0xf8,0xb1,0x65,0x5a,0xad,0xcd,0x1c,0x56,0x42,0x38,0xc2,0x52,0x09,0xd6,0x41,0x98,0x5d,0x5f,0xa5,0xe7,0xc2,0x55,0xa1,0x09,0x20,0xf2,0xbc,0x6a,0x9b,0x89,0xfb,0xe9,0x85,0x95,0xd6,0x22,0x5e,0x4d,0x6d,0x83,0x9d,0xf4,0xbe,0x66,0x05,0x32,0xb6,0xe2,0xf1,0x96,0x42,0xa4,0xc8,0x8c,0x1b,0xec}}, - {{0xf2,0x4a,0x96,0x57,0xc3,0x2f,0xe6,0x9f,0xed,0x7f,0xcc,0xe9,0xea,0xbe,0xd2,0x23,0x4e,0x47,0x13,0xd9,0x53,0x19,0x31,0x14,0x0a,0xd3,0x9b,0x95,0xa7,0x9c,0x88,0x5e,0x08,0xb2,0x16,0xda,0x45,0x61,0x1d,0x6b,0xdf,0xb1,0x14,0x0c,0x66,0xfd,0x3a,0xbe,0x25,0xdc,0xfd,0xcd,0xcc,0x5e,0x28,0x77,0x5a,0xa9,0x8b,0x84,0x77,0x26,0x9d,0xa6},{0xea,0xde,0x4d,0xab,0x09,0x02,0xbf,0x90,0xf8,0xae,0x8b,0x50,0x01,0xb2,0x9d,0x7c,0x0a,0x3b,0x60,0xda,0x34,0xa9,0xbb,0x4d,0xa5,0x53,0x18,0x65,0xec,0xaa,0xc9,0x29,0xb2,0xf7,0x74,0x14,0x63,0x5f,0x88,0xcf,0x4e,0x70,0x1b,0x11,0x64,0x73,0x15,0x6b,0x5a,0x8c,0xb8,0x4e,0x0f,0x83,0xae,0x4b,0x5c,0x52,0x1c,0x6a,0x0f,0x54,0x77,0xc8},{0xae,0xff,0x55,0xbf,0x78,0xb5,0xde,0x33,0xeb,0x87,0xea,0x13,0x7d,0x36,0x22,0x06,0x32,0xc4,0x7e,0xca,0x65,0x37,0xcc,0x83,0x0e,0xda,0x54,0xb3,0xd2,0xe6,0xe7,0x7f,0xe1,0x90,0x11,0x25,0x16,0x83,0x25,0x43,0xb4,0x38,0x06,0xbb,0x6c,0x62,0x7d,0x84,0x1f,0xf3,0x7b,0xeb,0xae,0x50,0xd8,0xfb,0xb9,0xf2,0xf9,0xc3,0x6f,0x59,0xb7,0xb0},{0x95,0x15,0x83,0x19,0x56,0x9c,0x11,0xd8,0x31,0x87,0x1d,0xe3,0x3f,0x07,0x89,0xb2,0xcb,0x81,0xf0,0xeb,0x0b,0x1e,0x74,0x08,0xa2,0x4a,0x0e,0x82,0xc6,0x45,0x8c,0x32,0xb4,0x8f,0xfd,0x76,0xeb,0x5e,0xc7,0x62,0xdc,0xcb,0xee,0xad,0xcf,0xcf,0xea,0x33,0x9d,0xb0,0x02,0x64,0x66,0x77,0x14,0x97,0x0c,0x6e,0x79,0xe8,0x58,0x32,0x0f,0xe6},{0xcb,0x2f,0xaf,0x53,0xd8,0x41,0x48,0x41,0x6f,0x36,0x78,0x80,0x83,0x5c,0x0d,0x4c,0x1b,0xf4,0x39,0xe0,0x34,0x4f,0xc2,0xb2,0x4e,0xf0,0xac,0xc2,0xf8,0x15,0x7a,0x81,0x9f,0x46,0x2b,0xe3,0xb9,0x39,0x05,0x89,0xa2,0xda,0x1a,0x63,0x51,0xb4,0x78,0x0f,0xfe,0x2f,0x9d,0xce,0x99,0x38,0xa9,0x7e,0xcb,0x80,0x57,0x9f,0xa2,0x28,0x0f,0x6a},{0x1b,0xec,0x67,0x50,0xd1,0x28,0x65,0x55,0xb8,0xde,0x3b,0x2e,0x1e,0x33,0xd8,0x1b,0xba,0x2e,0x78,0x6a,0xb8,0x0b,0x8c,0xa0,0x55,0x34,0x25,0x90,0x9a,0xe2,0xf5,0xaa,0x95,0x0c,0x6f,0x2a,0xb0,0x92,0x1d,0x48,0x5b,0x56,0x8c,0x82,0x8f,0xa7,0x15,0x75,0x26,0x61,0x85,0xc8,0x7d,0xda,0xf5,0x2a,0xf3,0x3c,0x34,0xc1,0x20,0x67,0xbb,0x04,0xec,0x7c,0xe2,0xcb,0x31,0xcf,0x23,0xda,0x5d,0x8a,0x05,0x00,0x9b,0x23,0x34,0xd0,0xed,0x56,0x10,0x0a,0x90,0x6b,0x73,0x26,0x6b,0xf0,0xd7,0xbc,0xd8,0xc7,0x89,0xc8},{0x90,0x43,0x54,0x87,0x44,0x00,0x07,0xca,0xa8,0x2b,0xec,0x55,0xa0,0xd2,0x8c,0x07,0x03,0xaa,0x61,0x1a,0x7d,0x0f,0x90,0x13,0x67,0x99,0x46,0x20,0xcd,0x70,0xcb,0xa7,0x96,0xdf,0x0c,0x13,0xc4,0x41,0x11,0xd6,0xc3,0x33,0x02,0x96,0x4f,0x1d,0xbd,0x06,0xa9,0xa1,0x31,0x0a,0xc3,0xdf,0x6d,0x52,0x6c,0xc6,0xbe,0xc5,0xb6,0x2a,0xb1,0x0f,0xec,0x7c,0xe2,0xcb,0x31,0xcf,0x23,0xda,0x5d,0x8a,0x05,0x00,0x9b,0x23,0x34,0xd0,0xed,0x56,0x10,0x0a,0x90,0x6b,0x73,0x26,0x6b,0xf0,0xd7,0xbc,0xd8,0xc7,0x89,0xc8}}, - {{0x4f,0x3a,0xdd,0x0f,0xcf,0x7f,0x27,0xda,0x27,0xc4,0xa6,0x2b,0x6b,0xd1,0x9f,0x59,0x73,0x5f,0xd4,0xb7,0xf0,0x86,0x16,0xc9,0xdd,0xa6,0xf9,0x9b,0x17,0xb2,0xb9,0x71,0xe7,0x4c,0xa1,0x17,0x79,0xe0,0xcc,0xae,0x10,0xec,0x28,0x3a,0x09,0xf2,0x8b,0x34,0x9c,0xac,0x16,0x2a,0xa9,0x21,0xe8,0xa7,0x18,0xc0,0xc4,0x9f,0x30,0xa0,0x25,0x62},{0x23,0x4c,0xd4,0xae,0x52,0x30,0xf6,0x64,0xb9,0xe1,0x47,0xca,0xf8,0xf3,0x3a,0x6b,0x8b,0xf3,0x29,0xe2,0x9b,0x5d,0xbb,0x0a,0x60,0x52,0x03,0x40,0x53,0x5c,0x9e,0x35,0x03,0xd4,0xec,0xd7,0x67,0xf4,0x92,0xd2,0x98,0x96,0xf2,0xa7,0xf4,0x25,0x6a,0x80,0x9c,0x75,0xc6,0xf2,0x1f,0x67,0x11,0x00,0x0d,0xda,0x1e,0xb2,0x58,0xa7,0x8c,0x39},{0x55,0x1b,0x80,0xbb,0xf3,0xc5,0x1a,0x84,0x34,0xf5,0x0a,0x8a,0x8a,0xe1,0x8c,0xea,0xa6,0xfb,0xd0,0x26,0xc9,0xa2,0x30,0x37,0x3e,0xba,0x98,0xfe,0x81,0x8a,0x52,0x37,0x0b,0x74,0x4e,0x3d,0x26,0x8f,0x82,0x4b,0xc0,0x6a,0x01,0x10,0x91,0x8f,0x89,0xb5,0x62,0x3f,0x1e,0x70,0xcc,0x25,0x77,0x39,0x74,0x88,0xdd,0xbc,0xbe,0x72,0x08,0x63},{0xe2,0x9a,0x46,0xd2,0x74,0xdc,0x0f,0x8a,0xa3,0xbd,0x20,0xb7,0xc7,0xd9,0x83,0x4b,0x58,0xa6,0xe3,0xbd,0xc5,0x00,0xb6,0x18,0x04,0x25,0x81,0xbd,0x99,0xb3,0xb1,0x2a,0x7a,0x68,0x6d,0xe1,0x3e,0x23,0x8d,0x29,0x9e,0x7a,0x30,0x56,0x4c,0x22,0xb6,0xf4,0x7d,0x7d,0x4f,0xfd,0x76,0xa5,0x9d,0x05,0x41,0x7c,0x7a,0x2d,0x7b,0xbe,0xcf,0x73},{0x7b,0xae,0x11,0x86,0x8a,0x38,0xbd,0x56,0x3c,0xf3,0x3c,0x9c,0x49,0xa4,0x68,0x0f,0x2b,0xdf,0xf2,0xa1,0xbc,0xc2,0xed,0x08,0x09,0x96,0xd0,0x7e,0x9b,0xe3,0x0a,0x72,0x13,0x03,0xd4,0x35,0x0a,0x94,0x60,0x09,0x4a,0xaa,0xca,0x35,0x8e,0xed,0x12,0xdd,0x26,0x8f,0xf8,0xa9,0xa2,0x8a,0x7f,0xac,0xf3,0x09,0xc7,0x22,0xc5,0x73,0xec,0xa0},{0xe9,0xc5,0x57,0x0d,0x85,0xbf,0x10,0xe2,0xd1,0xf5,0xd7,0x22,0xe9,0x6a,0x67,0x8d,0xd3,0x9f,0x1a,0xef,0x7f,0xc0,0x2b,0xe1,0xfd,0x2c,0xc2,0x5f,0x39,0xf9,0x34,0xd0,0x87,0x94,0x41,0x8a,0x65,0xa5,0x20,0x48,0xa4,0x20,0x5f,0x7a,0xc7,0x37,0x00,0x60,0x59,0x84,0x2a,0x1d,0xff,0x02,0xc3,0xe8,0x20,0xaa,0x39,0x13,0xac,0xf3,0xd7,0x05,0xbd,0xef,0x11,0x66,0x71,0xb8,0x9f,0x1e,0xe5,0xee,0x2e,0x37,0xfb,0x34,0xed,0xc5,0xa4,0x40,0x6e,0x38,0x31,0x0a,0x1c,0xaf,0x0d,0xd3,0x98,0xac,0x12,0x40,0xea,0x9c},{0xc6,0xcd,0x7a,0xbd,0x14,0xdb,0xe4,0xed,0xbf,0x46,0x70,0x23,0xbd,0xdb,0xc3,0xce,0x60,0xd5,0x6b,0x17,0x4c,0x23,0xfa,0x78,0x05,0xcc,0x18,0xed,0x42,0x03,0xa5,0xb7,0xdf,0x28,0x0e,0xd4,0x5d,0x31,0xd8,0xb9,0xdc,0xe9,0xf6,0x26,0xc5,0xe1,0xb3,0x80,0x0d,0x62,0xaf,0x2d,0xbd,0xd6,0xe4,0xbb,0x16,0x82,0xc8,0x13,0x2a,0x6f,0xb9,0x06,0xbd,0xef,0x11,0x66,0x71,0xb8,0x9f,0x1e,0xe5,0xee,0x2e,0x37,0xfb,0x34,0xed,0xc5,0xa4,0x40,0x6e,0x38,0x31,0x0a,0x1c,0xaf,0x0d,0xd3,0x98,0xac,0x12,0x40,0xea,0x9c}}, - {{0x6f,0x46,0xcd,0x96,0xc4,0x13,0xf4,0x11,0x62,0x49,0x8c,0x5c,0x78,0x27,0xef,0xc8,0xb9,0xe2,0x7d,0xf1,0x0d,0x37,0xf2,0xfe,0x85,0x35,0x82,0x60,0x23,0xb6,0x7b,0x17,0xd2,0x91,0xef,0x01,0x9e,0x99,0x35,0xab,0xc7,0xfb,0xa1,0xa3,0x13,0x44,0x3f,0x3c,0x16,0xcb,0xd8,0xf0,0xbf,0x9e,0x65,0x4d,0x07,0xe0,0xfd,0x8e,0x32,0x61,0x95,0xd5},{0xb7,0x81,0x16,0x2f,0xcb,0xa4,0x30,0x4e,0x6d,0xf5,0xf0,0x3f,0xfe,0xd9,0x81,0x20,0xa6,0x0e,0x2b,0xa8,0xc5,0xed,0x0d,0x9a,0x28,0x9c,0xe3,0xa9,0xb7,0xbf,0x87,0x0f,0xa5,0xf9,0x33,0xe7,0xa6,0x7f,0x9b,0xac,0xb6,0xcc,0xaf,0xfc,0xa7,0x4a,0x4d,0x36,0x39,0xa9,0xb6,0xf5,0x09,0xde,0x8d,0x37,0x11,0x07,0xd1,0x8a,0xf5,0x7b,0x66,0xe1},{0xcc,0xe0,0x07,0x62,0xbe,0x10,0x8c,0x3a,0xa2,0x96,0x5d,0x11,0xc7,0xd5,0x50,0xc3,0xbb,0x55,0x21,0xc5,0x40,0x27,0x7d,0xdb,0xad,0xd2,0x61,0x2a,0x42,0x5f,0x94,0x23,0x77,0x83,0x3a,0x99,0xe8,0xda,0x79,0x8c,0x1e,0xa8,0x44,0x04,0xec,0xf5,0xd1,0x55,0x1e,0x58,0xf1,0x6e,0x4d,0x27,0xa4,0x91,0xec,0x59,0xc8,0x17,0x36,0x58,0x2a,0x1f},{0x6d,0xf8,0x73,0xa3,0x38,0x61,0x1d,0x95,0x09,0xde,0xe5,0x26,0x1b,0x15,0x16,0xfb,0xf5,0x16,0xa8,0xf3,0x9e,0x3a,0x6b,0xb5,0x8c,0xee,0xa8,0x66,0x79,0xc3,0x9e,0xb4,0xe1,0xc2,0x85,0x0e,0x86,0x10,0x5a,0x4e,0x8b,0x4c,0x0a,0x7a,0xd8,0x8a,0x48,0xf4,0xa0,0x79,0x37,0xe3,0xa5,0x90,0x05,0x5e,0xbd,0xa1,0xf6,0x09,0x58,0x9c,0x6f,0x09},{0x66,0x47,0x6d,0x60,0x06,0x2d,0x90,0x8f,0xae,0x6c,0x01,0xe9,0xb0,0xf9,0x6b,0xa5,0x4a,0xe1,0xdb,0xd3,0x64,0x42,0x37,0x5c,0x11,0x40,0x7a,0xce,0x4e,0x83,0xc3,0x2c,0x2e,0xd2,0x67,0x76,0xfb,0x8c,0x5d,0xab,0xe8,0xb8,0xd6,0x2b,0xf8,0x86,0xff,0x96,0xf3,0xa8,0x0e,0x2b,0x1a,0x68,0xf5,0xe4,0xee,0x49,0xa6,0x8c,0x41,0x1f,0x97,0xbf},{0x81,0x92,0x4e,0xc6,0xab,0x00,0xdd,0xf9,0xf9,0xb7,0xe0,0x0a,0xa9,0x3f,0x0a,0xf9,0x32,0x73,0xf6,0x22,0xec,0x95,0xd9,0x20,0x8a,0x3f,0xeb,0x0d,0xc7,0x79,0x6f,0xb3,0x85,0xf4,0xe1,0x11,0xe1,0xcc,0xaa,0x1b,0xfd,0xf3,0x43,0xff,0x66,0x73,0x0f,0x09,0xcc,0xa4,0x6c,0xb8,0x2a,0x0f,0x53,0x58,0x63,0x32,0x06,0xd9,0x6b,0x1a,0x14,0x04,0x85,0x3f,0x2f,0x2b,0x05,0xfb,0xed,0xe9,0x08,0x0d,0x21,0x49,0xc9,0x79,0xdf,0x6f,0x77,0x89,0xd7,0x74,0x09,0x57,0x1a,0xd2,0xa7,0x43,0xbf,0x08,0x8e,0x98,0xbc,0x2f},{0xe3,0xb1,0xc4,0x81,0xe6,0xec,0x07,0x58,0xa4,0xcb,0x7e,0xd5,0xae,0x9d,0x43,0xf1,0xb7,0xe2,0x0a,0x1f,0xd5,0xe8,0x14,0xba,0x22,0xff,0xb7,0x20,0x76,0x08,0xdc,0x9a,0x44,0x4c,0x1c,0xcd,0x38,0x4d,0xb5,0xd8,0xa9,0x1b,0x9d,0xbb,0x13,0x5a,0x6c,0xe9,0x5d,0xa4,0x42,0x0e,0xde,0x9a,0x47,0x8a,0x2a,0x97,0x42,0x86,0x87,0x98,0x3f,0x04,0x85,0x3f,0x2f,0x2b,0x05,0xfb,0xed,0xe9,0x08,0x0d,0x21,0x49,0xc9,0x79,0xdf,0x6f,0x77,0x89,0xd7,0x74,0x09,0x57,0x1a,0xd2,0xa7,0x43,0xbf,0x08,0x8e,0x98,0xbc,0x2f}}, - {{0xff,0xe3,0x69,0x7b,0x62,0x45,0x40,0x5f,0x1c,0x49,0x65,0xd6,0xae,0x24,0x16,0x84,0xfa,0x69,0x6c,0x1f,0x6c,0x65,0xee,0x52,0xe9,0x6c,0x54,0xc7,0x31,0x9b,0xc2,0x74,0x4f,0xc0,0x16,0xb8,0xf8,0x75,0x5f,0x45,0xb5,0xf3,0xa0,0xd9,0xbe,0x25,0x82,0xbd,0x3c,0x03,0xe0,0x14,0x15,0x6a,0xd5,0x64,0x08,0x65,0x13,0x33,0xc2,0xab,0xe0,0x45},{0x6f,0x5a,0x90,0x80,0x25,0x13,0xc2,0xa7,0xfe,0x1c,0xa1,0x07,0x81,0x4b,0x09,0xd3,0xbd,0xda,0x55,0xa8,0xaa,0x62,0x19,0x03,0xe9,0x9f,0x77,0xef,0xff,0xd4,0x5e,0x53,0xbc,0x9d,0x71,0xb8,0xc4,0xc2,0x85,0xb9,0xb4,0x3d,0x95,0xb8,0xfd,0x44,0xb7,0xc8,0x6f,0x93,0x15,0x04,0x16,0x7e,0x01,0xf2,0x09,0x23,0x96,0x69,0xe5,0x65,0x52,0x34},{0xaf,0xfe,0x4f,0x34,0x4e,0xfe,0x51,0xa5,0xb2,0xd8,0x31,0x74,0x7b,0xae,0xfb,0xb9,0x33,0xc1,0xdc,0x66,0xe6,0x95,0x9e,0xce,0x77,0x7d,0x55,0x3c,0xa6,0x6c,0x09,0x23,0x5a,0x1a,0x5e,0x1a,0x41,0xd3,0xad,0x5f,0x86,0xd0,0x14,0xf5,0xe0,0xda,0xf1,0xce,0x19,0x90,0x45,0x0c,0x4c,0xb1,0xd3,0xc8,0x4c,0xdb,0x7e,0x49,0xf5,0xac,0xde,0xff},{0x1b,0x9b,0x6b,0x30,0xd3,0x19,0x37,0x83,0xad,0x05,0xca,0xba,0x22,0x85,0x33,0x7f,0x55,0x60,0xe3,0x14,0x8c,0x39,0x87,0xd1,0x4c,0x21,0x27,0xa0,0xae,0x4a,0x56,0x15,0x50,0x6c,0x99,0xca,0xff,0xde,0x10,0xc6,0x9f,0x6c,0x70,0xd1,0x66,0xb4,0x87,0xd8,0xfc,0x46,0xf2,0xcf,0x0c,0xd8,0xc3,0x14,0x5d,0x27,0xbd,0xed,0x32,0x36,0x7c,0xed},{0x64,0x6b,0x74,0xc7,0x60,0x36,0xc5,0xe4,0xb6,0xde,0x02,0x1a,0x09,0xaf,0x65,0xb1,0x94,0xa3,0xf4,0x95,0xf5,0xb0,0xef,0x86,0xb5,0x13,0x26,0x0b,0xe8,0xc5,0x5c,0x77,0xf5,0xe6,0xb6,0x10,0x36,0x87,0xa3,0xd2,0x7c,0x17,0x2c,0xb9,0xb0,0x90,0x9e,0x8c,0x0a,0x7d,0x73,0xb2,0x29,0xeb,0xa7,0x85,0xd7,0x04,0x14,0xf9,0x77,0xb7,0xf4,0x89},{0x7f,0x1c,0x5a,0x57,0x14,0xf6,0x30,0x07,0xf9,0xfe,0x42,0x98,0xcb,0x3d,0xac,0x04,0x30,0x0d,0xc6,0xd0,0x4f,0x8a,0xbc,0xdd,0x3e,0xc3,0xb7,0x74,0xc8,0x3b,0x1a,0xcc,0x6a,0x54,0x9e,0xb9,0xbe,0xf0,0x7c,0x35,0x35,0x1a,0x50,0x4c,0xc2,0x38,0x41,0x46,0xc8,0xc4,0x81,0x2b,0x26,0x56,0x6f,0x8a,0x9f,0x74,0x87,0xe0,0x01,0x82,0xe2,0x09,0xf3,0x9a,0xc5,0x33,0x5a,0x7d,0xb6,0xbb,0xff,0x20,0x4d,0xc1,0x99,0x3d,0xcc,0x5a,0xc7,0xd1,0xbe,0x4c,0xcf,0xc8,0x09,0x79,0x15,0x5e,0x0c,0xc6,0x26,0x36,0xe6,0xd9},{0x4d,0x2f,0x08,0x84,0x32,0xcf,0xe0,0x3b,0xa8,0x3e,0xa5,0xf8,0x3a,0xe8,0xa9,0x04,0x5a,0x74,0x67,0xcb,0x41,0x22,0xc5,0xc4,0x9a,0xa5,0xc1,0xa7,0x94,0x8b,0xa5,0x35,0x00,0x00,0x1a,0xaf,0xfb,0xed,0x40,0xb8,0x2b,0x28,0xf1,0xb1,0x02,0xd3,0x8b,0xc0,0x32,0x4a,0xa5,0x0a,0xa4,0xc3,0xbf,0xb3,0xf5,0xb7,0x65,0x8e,0x88,0xdf,0xd0,0x0e,0xf3,0x9a,0xc5,0x33,0x5a,0x7d,0xb6,0xbb,0xff,0x20,0x4d,0xc1,0x99,0x3d,0xcc,0x5a,0xc7,0xd1,0xbe,0x4c,0xcf,0xc8,0x09,0x79,0x15,0x5e,0x0c,0xc6,0x26,0x36,0xe6,0xd9}}, - {{0xc8,0x8e,0x1c,0xea,0x02,0x6a,0xfd,0x88,0x8b,0xa9,0x9d,0xdd,0xba,0xea,0x77,0x30,0x88,0x1a,0x93,0x49,0xda,0x05,0x18,0xbb,0x4a,0x6a,0x11,0xc4,0x48,0x72,0x77,0x1f,0x6e,0x2b,0x9a,0xe3,0x27,0xbe,0xe1,0x75,0x32,0x30,0xa6,0x12,0x26,0x44,0xbf,0xb2,0xa5,0x51,0x0b,0x48,0x3a,0xea,0xc5,0xd4,0x24,0x3f,0x4e,0xe8,0xe5,0xc3,0xfb,0xc2},{0xcb,0x56,0x3c,0x00,0x28,0x15,0x72,0x16,0x23,0x4e,0x2e,0x2c,0x8c,0xe8,0x7c,0x44,0x82,0x2a,0xe0,0x57,0xa3,0x0a,0xc4,0x42,0xb5,0x07,0xe1,0x1b,0x78,0x8b,0x3d,0x4d,0xcb,0xe4,0x56,0x72,0x0b,0x85,0x52,0xd8,0x55,0xe2,0xcd,0x38,0xd2,0x83,0xb6,0x05,0xd2,0x9f,0x63,0x9e,0x7f,0xca,0xe5,0x95,0x36,0x61,0x9b,0xca,0x09,0x27,0x53,0x82},{0x24,0x67,0x10,0xd6,0x8a,0x1a,0x8e,0xb8,0x53,0xef,0xb7,0x67,0x2a,0xfd,0xb8,0xd6,0xe3,0xf7,0x41,0x95,0x8c,0x50,0xca,0x1d,0x21,0x21,0x41,0xd1,0xef,0x2d,0x9b,0x53,0xa9,0x42,0xcd,0xda,0x6d,0x12,0x1b,0xbd,0x0a,0xe1,0x4d,0x95,0xc6,0xaa,0x40,0xfd,0x98,0xfb,0x26,0x21,0x5e,0xaf,0x8e,0x6b,0xc9,0x36,0x2c,0x66,0x31,0x24,0x45,0x87},{0x5e,0xf9,0x1d,0x10,0xb5,0x79,0x1f,0x80,0x85,0x90,0xc3,0x7f,0x2b,0x73,0xbf,0x83,0x0b,0x5d,0x46,0xae,0x79,0xef,0x09,0x71,0x29,0xfb,0x83,0xde,0x1f,0xe2,0xdb,0x1b,0xa2,0x22,0xee,0x50,0x21,0x9d,0x9c,0x35,0x14,0x48,0x13,0xa5,0xd1,0x68,0xf4,0x61,0x1f,0xd7,0xe2,0xd6,0x42,0x1c,0xdc,0x58,0xec,0x8b,0x03,0x6b,0xdf,0x64,0x06,0x30},{0xf9,0xa6,0x88,0x74,0x07,0x19,0x15,0x38,0xaf,0xac,0x07,0x10,0xe0,0xd9,0x22,0xf3,0x78,0xb0,0xbf,0x60,0xa3,0x0f,0xea,0x0f,0xa8,0x64,0xa9,0xa3,0x82,0xe1,0x4c,0x29,0x36,0x22,0x6d,0x43,0x9c,0xde,0x22,0xbf,0xc6,0x85,0xf7,0xe9,0xe0,0x79,0x80,0xfe,0x9d,0xd6,0x24,0xbd,0x29,0xa4,0x8c,0x35,0x21,0x87,0x45,0x7f,0x88,0xd9,0x9a,0x9d},{0x49,0x43,0x19,0x14,0xcc,0x4a,0x11,0x01,0x05,0xd1,0x4e,0x39,0x6d,0xb0,0x22,0x65,0x32,0x6e,0x67,0x04,0x50,0x85,0x53,0x42,0x90,0x2c,0xc0,0x63,0x2f,0xbd,0x15,0x90,0x1b,0x3f,0x03,0x90,0x16,0x7f,0x7b,0x49,0x74,0xd0,0x3d,0x81,0x80,0x1e,0x9e,0x2e,0xa9,0x13,0x6a,0x10,0x14,0xc1,0xfd,0xf9,0x25,0x3a,0x1d,0x52,0x93,0x0a,0x77,0x03,0xa2,0xdd,0xce,0x9f,0x2a,0x35,0xc9,0x93,0x7c,0xa2,0x2c,0xf6,0x38,0x73,0xb3,0xab,0x7f,0x55,0xb6,0x62,0xa2,0x8d,0x6a,0x3e,0x88,0x04,0x9b,0xa2,0x19,0x64,0x55,0x01},{0x22,0x03,0x49,0x58,0x76,0x3c,0x85,0x45,0x5e,0x73,0x78,0x8f,0x65,0xc9,0x50,0xf8,0xd7,0x16,0x92,0xa4,0xd1,0x79,0xce,0xf3,0x00,0x34,0x38,0xb8,0xcc,0x96,0x9f,0xa6,0x87,0x28,0xcb,0x19,0x28,0xad,0x83,0xb5,0x09,0x96,0x54,0xe8,0x2a,0xb9,0x9b,0xff,0x60,0x85,0x31,0x28,0x62,0x36,0xd2,0x0e,0xad,0x2a,0xe1,0x84,0x80,0xeb,0x6f,0x00,0xa2,0xdd,0xce,0x9f,0x2a,0x35,0xc9,0x93,0x7c,0xa2,0x2c,0xf6,0x38,0x73,0xb3,0xab,0x7f,0x55,0xb6,0x62,0xa2,0x8d,0x6a,0x3e,0x88,0x04,0x9b,0xa2,0x19,0x64,0x55,0x01}}, - {{0xeb,0x18,0x95,0x94,0x5f,0x15,0x8c,0xb8,0x4d,0x6e,0x7d,0xc0,0x96,0x6c,0x52,0xa2,0x5f,0x43,0x67,0xc2,0x3a,0x10,0x5b,0xf1,0x8f,0x21,0x89,0x06,0x77,0xe9,0xab,0x2e,0xcd,0x17,0x9c,0x9a,0xd7,0x89,0x7e,0x53,0x58,0x60,0x9b,0xce,0x90,0xd9,0x13,0x2d,0x78,0xc4,0x2c,0x1c,0x4c,0xe8,0x23,0x70,0xff,0xa0,0x42,0x98,0x25,0x40,0xd6,0xd8},{0xb6,0xfb,0xdd,0x5d,0x35,0xf2,0x2b,0x89,0xda,0x8e,0x90,0xee,0x03,0x4e,0x75,0xdb,0x4c,0x45,0xc8,0x00,0xde,0x06,0x27,0xde,0x44,0xb5,0x5b,0xc7,0x56,0xc3,0xf5,0xbb,0xee,0xa6,0x21,0xd4,0xd9,0xb9,0x24,0x9c,0x4c,0xbc,0x23,0xe5,0xeb,0x05,0xb6,0xd0,0xd0,0xbf,0x49,0x95,0x01,0xb4,0x97,0xad,0xb5,0x71,0x8d,0x4b,0x32,0xd0,0xdd,0x1a},{0xfd,0x11,0xd7,0xe4,0x46,0xcd,0xd8,0x44,0x89,0x0a,0xe7,0x44,0x59,0xe9,0xcf,0x9f,0xd6,0xf1,0x74,0x56,0x04,0x78,0xfa,0x29,0x46,0x8a,0x8d,0x1b,0xbe,0x41,0x92,0x1c,0x8d,0x74,0x01,0x1b,0xc1,0xf8,0x26,0xf4,0xc2,0x68,0xc3,0x23,0x8c,0x68,0x7c,0x0a,0xad,0xdd,0x50,0x10,0xcf,0xdb,0x78,0xc5,0x79,0x28,0x37,0x63,0x92,0x1a,0x1d,0xea},{0xd2,0x2a,0xf0,0x66,0x15,0x8b,0xcb,0x83,0xcf,0x34,0xa1,0x33,0x6b,0xd5,0xa8,0x98,0x3b,0xd7,0x09,0x0d,0x70,0xa5,0x8a,0xc0,0x73,0xcf,0xde,0x59,0xd5,0x13,0x41,0xd2,0x43,0x8b,0xb4,0xc3,0x5b,0x6f,0xf1,0xed,0x47,0x76,0xe6,0x5e,0xb8,0x2a,0x7e,0x20,0x91,0xa0,0x9d,0xc1,0xa2,0x0a,0x6d,0x97,0x7d,0xeb,0xe3,0x64,0x5f,0x86,0xff,0x3e},{0x45,0xd8,0xdc,0xe4,0x3a,0x3a,0x44,0xdc,0x7f,0xa8,0x92,0x11,0x1b,0x4f,0xfa,0xcf,0x21,0xff,0xfb,0x20,0xb0,0x02,0x6d,0x0e,0x1c,0xde,0xe8,0x51,0xd8,0x2c,0x72,0x0e,0xbf,0xf6,0x9a,0xd3,0xd3,0xfe,0xfa,0x98,0x4e,0xc2,0xf0,0x16,0xda,0x39,0x93,0xc4,0xe0,0x33,0x9a,0x43,0xe8,0x7a,0xc5,0x0f,0x0b,0xa4,0x45,0xf0,0x5e,0x7a,0xa9,0x42},{0xdb,0x4e,0x17,0x76,0x8b,0x3c,0x98,0x7f,0x58,0x76,0x97,0xc9,0x3f,0x99,0x01,0x05,0x42,0x7e,0xfd,0x83,0x99,0xaa,0x19,0xb5,0x72,0x4c,0x69,0xed,0x6e,0x21,0x79,0x6e,0x3b,0x71,0xe5,0xab,0x23,0x84,0xe7,0xfe,0x58,0x2b,0x0d,0x1e,0x75,0x7c,0x29,0xb3,0x2d,0x66,0xc2,0x45,0x88,0xac,0x86,0x29,0xe4,0xaa,0x9e,0x71,0xa1,0x88,0xf9,0x06,0xda,0xa3,0xdd,0x7b,0x6c,0xd9,0xc9,0x73,0xe9,0x56,0xd1,0xee,0x5b,0xf9,0xae,0xc0,0x29,0xbe,0x20,0x6c,0xc7,0xf9,0xc5,0x2d,0x6d,0xad,0x8f,0x49,0xf8,0x17,0xdb,0x7a},{0xb8,0xb7,0xec,0xeb,0x3e,0x40,0x77,0x6c,0xab,0x10,0xfe,0x9f,0xd1,0x40,0xfe,0xd2,0x88,0x8e,0xb0,0x55,0xae,0x75,0xb1,0xcc,0x9d,0x6c,0x11,0x28,0x95,0x38,0x9f,0xb9,0x59,0xe2,0x29,0xc3,0xbc,0x09,0x16,0x1f,0x17,0x9e,0x15,0x78,0x09,0x61,0x07,0x9e,0xad,0x67,0x98,0xa9,0x24,0xff,0xf9,0x4b,0xa2,0x76,0x09,0xa0,0xd7,0x1b,0xed,0x05,0xda,0xa3,0xdd,0x7b,0x6c,0xd9,0xc9,0x73,0xe9,0x56,0xd1,0xee,0x5b,0xf9,0xae,0xc0,0x29,0xbe,0x20,0x6c,0xc7,0xf9,0xc5,0x2d,0x6d,0xad,0x8f,0x49,0xf8,0x17,0xdb,0x7a}}, - {{0xc3,0x92,0x4d,0x01,0x9c,0xea,0x5a,0x8d,0xbd,0x5c,0x12,0x58,0x6d,0x03,0x26,0xbf,0xa4,0xdd,0xf7,0x26,0xa4,0x0d,0x22,0xe0,0xbd,0xcc,0x6f,0x30,0x9e,0xf9,0x4c,0x1f,0x03,0x52,0xab,0x38,0xe9,0x9c,0x08,0x9c,0x09,0xe5,0x87,0x5c,0x24,0x1a,0xe2,0x75,0xcb,0x18,0x8a,0x63,0x50,0xd1,0x23,0x45,0x49,0x93,0x40,0x2c,0x09,0xd4,0xac,0x39},{0xd4,0xe7,0xb7,0x05,0xfd,0xd6,0xf3,0x57,0xfb,0xc2,0x2f,0x2c,0x71,0x80,0xf5,0xc3,0xa6,0x0a,0x23,0x9d,0x1d,0xa8,0x68,0x10,0x8a,0xfa,0x68,0x9d,0x2b,0xcf,0x96,0xa9,0xe6,0x0e,0x07,0x32,0x23,0x09,0x87,0x16,0xc5,0xbb,0x76,0x22,0xfc,0xb4,0x59,0x6d,0x67,0xfd,0x29,0x51,0x95,0x4c,0xe2,0x8c,0x18,0xab,0xda,0x84,0xc3,0x62,0x80,0x14},{0xc9,0xa1,0xfe,0xc3,0x48,0x0d,0xee,0x54,0x44,0xff,0x9c,0x46,0x04,0x0e,0x74,0xda,0xa4,0x6a,0x56,0x02,0x5f,0x76,0x0e,0xb5,0xc1,0xc9,0xe9,0xb2,0x6e,0x07,0x49,0x0c,0xf7,0x4b,0xee,0xd6,0x0a,0xad,0x94,0x03,0x58,0x2d,0x60,0x95,0xf8,0x16,0x7b,0x49,0x0b,0x01,0x66,0x3e,0x17,0x01,0xe5,0x54,0x7d,0xd7,0xbb,0x10,0xd1,0xad,0xad,0x79},{0xb2,0xd8,0x10,0x29,0xeb,0xb8,0x4e,0x2b,0x39,0x85,0x5c,0xb3,0xdc,0xf5,0x87,0xca,0xca,0x9c,0x7a,0x8c,0x2b,0x08,0xe8,0x25,0xe2,0xcf,0x70,0xe2,0xe6,0xfb,0xdb,0x0c,0xc3,0x0d,0x71,0x11,0x83,0x65,0xf2,0x71,0x08,0x1b,0x32,0x6e,0x6c,0x51,0x50,0xf1,0xf6,0x4b,0x54,0x63,0x16,0x7f,0xfd,0x80,0x05,0x61,0x63,0xf1,0x80,0x6a,0x0b,0xfd},{0xa7,0x4b,0x75,0x38,0x90,0x64,0x96,0x7b,0xda,0x5e,0x08,0x9b,0x80,0xc4,0x72,0x3f,0x73,0xb2,0xdb,0xd3,0x4a,0xed,0xa4,0xdc,0x5c,0x79,0xe5,0x0f,0x7a,0xd3,0x0c,0xac,0xf9,0x99,0x5c,0x1a,0x0f,0xb3,0x1a,0x0f,0x5c,0xc3,0x9e,0x1a,0x2b,0xfa,0xc3,0xf0,0x40,0xe5,0x5f,0x36,0xd2,0x98,0x31,0xa1,0xaf,0x18,0x5f,0xae,0x92,0xf3,0x9e,0xc0},{0xf9,0xbf,0x52,0xe6,0xd3,0xe1,0x5d,0xd3,0x30,0xf3,0xa1,0x0c,0xc8,0x5a,0x97,0x55,0xab,0x67,0x67,0xd0,0x00,0x62,0x7b,0x80,0x70,0xbf,0x24,0xd0,0x09,0x8b,0x07,0x77,0xeb,0x3e,0xf0,0x5d,0xdf,0x7b,0xa9,0x7d,0xa4,0x6a,0x0d,0xf1,0xac,0x83,0x7d,0x64,0xb5,0xf4,0xc6,0xc4,0x12,0x0c,0x55,0x9f,0x67,0xbb,0xd5,0xe3,0xd3,0xdb,0x17,0x0f,0x90,0x2f,0x8f,0xc9,0xfd,0x4e,0x6c,0x8b,0xe6,0x99,0xfa,0xda,0x8f,0x1f,0xe6,0xc3,0xeb,0xd8,0x14,0x20,0xcc,0x3c,0x1c,0x23,0x77,0x28,0x9b,0x22,0x9a,0x5a,0x0c,0x43},{0xa2,0x78,0x37,0xc9,0x63,0xe1,0x31,0x36,0xc2,0x58,0xac,0xca,0xbb,0xa2,0x84,0xaa,0xb3,0x82,0xe2,0x19,0xb7,0x14,0x96,0x27,0x77,0xfa,0xa1,0x02,0xaa,0xff,0x55,0x82,0xba,0xc0,0x38,0x1a,0x69,0x35,0x48,0x87,0xc2,0xeb,0x48,0x08,0xea,0xc5,0x6b,0xfc,0x84,0x60,0x4e,0xce,0xd7,0xd2,0x86,0x8b,0x76,0xf3,0x46,0xe1,0x87,0x1f,0xff,0x09,0x90,0x2f,0x8f,0xc9,0xfd,0x4e,0x6c,0x8b,0xe6,0x99,0xfa,0xda,0x8f,0x1f,0xe6,0xc3,0xeb,0xd8,0x14,0x20,0xcc,0x3c,0x1c,0x23,0x77,0x28,0x9b,0x22,0x9a,0x5a,0x0c,0x43}}, - {{0x0e,0xa6,0x0c,0xef,0x12,0xd6,0x7d,0x71,0xd4,0x88,0x73,0x86,0x9a,0x88,0x8f,0x5b,0xd1,0xb6,0x12,0xc4,0x93,0x8b,0x5f,0xee,0xdd,0x9c,0x2a,0x7f,0x4d,0xfd,0xba,0x00,0x09,0x45,0x77,0xd2,0xcf,0xcd,0x3a,0x6f,0x27,0x44,0xe2,0x55,0x3e,0x79,0x88,0x4d,0x5f,0x38,0x34,0xe8,0xe7,0xc6,0x3a,0xde,0xef,0x99,0x15,0xea,0x88,0x79,0xd7,0xca},{0xa0,0x9a,0x0a,0x3a,0x42,0x35,0x54,0x78,0xb9,0x82,0x52,0xb4,0xc8,0x5c,0x4a,0x03,0xa1,0xb9,0x27,0xcc,0x99,0xec,0x03,0xdf,0xdd,0x6e,0xde,0xef,0x8f,0x7f,0xdc,0x5a,0xc3,0xcb,0x0e,0xa2,0x7e,0x93,0xe6,0xdd,0xbd,0xf1,0x1b,0x03,0x29,0x63,0x72,0x11,0x72,0x3d,0x24,0x6f,0xdf,0x8e,0xed,0xa4,0xe2,0x2a,0x4c,0x00,0xe2,0xc4,0x55,0x1b},{0xb2,0xf1,0xff,0xf6,0x3a,0x26,0xe1,0x74,0x52,0xba,0xee,0x28,0xb6,0x56,0x90,0x59,0xde,0x92,0x5f,0x84,0xd1,0x87,0xe2,0x64,0xce,0xdc,0x94,0x3c,0xb4,0xf8,0x01,0x0a,0x86,0x2f,0xfe,0x79,0x03,0x72,0xfc,0x26,0x21,0xc3,0x1e,0xec,0x63,0x29,0x64,0xcb,0x5f,0xcc,0xb6,0x78,0xf7,0xc8,0xd1,0xf8,0x5c,0xc4,0x4b,0xc0,0xc3,0x75,0x3e,0x46},{0x03,0x4b,0xb9,0xd1,0x50,0xa3,0x79,0xbe,0x74,0xa3,0xb5,0xd8,0x28,0x1b,0x6d,0x72,0x68,0x0a,0x9b,0x19,0xc9,0x13,0xc4,0x04,0x94,0x0a,0xcb,0x72,0xff,0x7d,0xb6,0x9a,0x1c,0xfd,0xe4,0xa3,0x75,0x13,0x57,0x36,0xfe,0x4a,0xf6,0xbc,0xca,0xd9,0x34,0x9b,0xef,0x90,0x02,0xd9,0xbd,0xdd,0x6f,0x22,0x54,0x36,0xb2,0x3f,0x22,0x65,0xef,0xe7},{0x04,0xd4,0x43,0xe8,0x8c,0xc4,0xfb,0xe5,0x55,0xd0,0xa4,0xea,0x20,0xf8,0xe1,0x8f,0xc2,0xbc,0x1f,0x55,0xf1,0x8d,0xda,0xc0,0x85,0xa4,0xef,0x36,0x97,0x22,0x8b,0x8e,0x77,0x4c,0x1a,0xa4,0xa0,0x6f,0xe1,0xdc,0x32,0x47,0xc4,0x3a,0xd8,0x8a,0xbd,0x19,0x30,0x1c,0x96,0x7a,0xb2,0x23,0x7c,0x16,0x03,0xa7,0x4f,0xfd,0xa6,0x50,0xd9,0xf7},{0xdf,0xc2,0x59,0xd2,0xa9,0x9b,0x1e,0xca,0xf0,0x39,0x2f,0xf8,0xc2,0xf3,0x91,0x55,0x1b,0xba,0x81,0x3a,0x67,0x1a,0xd4,0xf4,0xb0,0x9f,0xb6,0x18,0x38,0x65,0x3e,0x67,0xa0,0x37,0xc2,0x9a,0xc7,0xee,0x72,0x8e,0x13,0x64,0xd1,0x0a,0xda,0xbd,0x8d,0xa4,0x28,0x55,0x3a,0x2c,0x78,0x41,0xc6,0xfc,0x1c,0x0f,0xf8,0xd7,0x5f,0xe6,0xde,0x0b,0xd5,0xc0,0xaa,0x2c,0x5c,0xac,0x46,0xeb,0xa4,0x35,0x2a,0xab,0x00,0x2e,0xc0,0x8b,0x42,0x65,0x2f,0x2f,0x13,0x84,0x60,0x15,0xa3,0x69,0xee,0xab,0x0e,0x50,0xbf,0x5f},{0xc1,0xb0,0xac,0x4c,0xfa,0x62,0x52,0x22,0xae,0x8c,0x94,0x38,0xd9,0x6e,0x10,0x94,0xe7,0xaa,0xc0,0x92,0x93,0x06,0x55,0xf9,0x2e,0xd9,0x10,0x4d,0xcb,0x82,0x19,0x1f,0x27,0x16,0x81,0xdd,0xea,0x7a,0xa8,0xce,0x5a,0xdd,0x37,0x77,0x24,0x57,0xfb,0x40,0x3d,0x1b,0x48,0x88,0xda,0xce,0xe8,0xd2,0xed,0xe0,0x6e,0x29,0xeb,0xdb,0x95,0x09,0xd5,0xc0,0xaa,0x2c,0x5c,0xac,0x46,0xeb,0xa4,0x35,0x2a,0xab,0x00,0x2e,0xc0,0x8b,0x42,0x65,0x2f,0x2f,0x13,0x84,0x60,0x15,0xa3,0x69,0xee,0xab,0x0e,0x50,0xbf,0x5f}}, - {{0x3a,0x79,0x39,0x60,0xe9,0x93,0xad,0x78,0xf9,0x0b,0x99,0x64,0x71,0x76,0xad,0xdc,0x63,0xa3,0x38,0xbf,0x0a,0x36,0x22,0xcf,0x4f,0x84,0x3e,0x34,0xaf,0x0b,0xd4,0x5c,0xc0,0xa4,0x01,0x7c,0x07,0xc3,0xb4,0xcb,0xdb,0x39,0xdd,0x39,0xc7,0x5c,0xbd,0xcf,0x61,0x8b,0x72,0x74,0xd6,0x85,0xdc,0x5c,0x08,0x93,0x6d,0xe6,0xf1,0xeb,0xb9,0x7c},{0x71,0x12,0x20,0xbb,0x37,0xa6,0xd8,0x71,0xf7,0x58,0xaa,0xbd,0x30,0xfb,0xac,0x94,0x62,0x45,0xf0,0x1a,0xc3,0x4a,0x07,0x78,0x6d,0x17,0xf5,0x8d,0x69,0x3d,0x2e,0x15,0x96,0x48,0x1a,0xb0,0x7e,0xdd,0xf5,0x2d,0xe1,0x56,0xfc,0xe9,0x26,0x91,0x51,0xfe,0x5e,0x2a,0xdc,0x23,0x89,0x09,0x14,0xe6,0x17,0xa9,0x14,0x8c,0x8c,0xe8,0xe3,0x71},{0xe4,0xd0,0xa7,0x5a,0xce,0x93,0x1d,0x55,0xa2,0x3d,0xdd,0x7e,0x10,0x66,0x6d,0xc6,0x5c,0x87,0x9f,0x7a,0x52,0x5e,0x76,0x3f,0x09,0x9e,0xe5,0x8e,0x60,0x39,0x5e,0x3c,0x28,0x31,0xa4,0x12,0x39,0xfd,0xba,0xda,0xc8,0x59,0xdd,0x5b,0x26,0x78,0x8f,0x33,0xd2,0xc8,0x22,0x77,0x49,0xcf,0x34,0x61,0xbe,0x7a,0xa6,0x31,0xbe,0xe5,0xab,0xc2},{0x60,0xf5,0x52,0xbd,0xb1,0x9e,0x06,0xa3,0x94,0xad,0xe0,0x82,0x33,0x7c,0x41,0x17,0x5b,0x8a,0xbc,0x7c,0xce,0xd1,0x7e,0xfd,0x39,0x17,0xfd,0x90,0x5a,0x53,0x89,0x27,0x9f,0x27,0x7a,0x08,0xb2,0x66,0xda,0xb5,0xbf,0x3b,0x80,0xe2,0x1a,0x30,0x80,0x45,0x13,0xf3,0x4b,0x0c,0x4a,0xe9,0x0a,0x6e,0xf2,0x3e,0xa3,0x70,0x3d,0x89,0xd3,0xb2},{0x23,0x41,0x08,0x8d,0xa8,0x0b,0x6a,0xe0,0x65,0xb1,0x42,0x50,0x49,0xdd,0xd3,0xe8,0x89,0x13,0x7a,0x04,0xf0,0xd6,0x2f,0x6e,0x73,0xcd,0xdc,0x10,0xbb,0x02,0x6b,0xa2,0x25,0x58,0xa3,0x08,0x37,0x7c,0x8b,0x1f,0x4a,0x81,0x38,0x88,0xbd,0xf4,0x4f,0x24,0xe8,0xd6,0x9f,0x2f,0x13,0xeb,0x79,0x60,0x80,0x90,0x52,0x6b,0x8e,0xed,0xcb,0x77},{0x5b,0x88,0x63,0xaf,0xf9,0xe2,0x44,0x23,0xc8,0x02,0xe0,0x22,0x15,0x3d,0x2a,0xb7,0x40,0x76,0xe8,0x95,0xfd,0xa9,0xe3,0x85,0x94,0xa3,0xbb,0xce,0x61,0x19,0x0d,0xe2,0x95,0xdf,0x81,0x11,0x53,0x77,0xcd,0xf2,0xd8,0x4f,0xbf,0x19,0x6a,0x3d,0x4b,0xda,0xa4,0x56,0xa4,0xcd,0x9d,0x4f,0x52,0x53,0x7d,0xd8,0xac,0xe0,0xfb,0x9a,0x71,0x0c,0x59,0xf9,0x0b,0x03,0xf1,0x7b,0xaf,0x33,0xc3,0xe5,0x1e,0x8d,0x4f,0xbe,0x21,0xed,0x6b,0x15,0xdd,0xd2,0xeb,0x7c,0xe4,0x59,0x6c,0xf9,0x91,0xc1,0x3a,0x3a,0xb6,0x2b},{0x5e,0x54,0xe5,0x1b,0x3d,0x2c,0x00,0x80,0xdd,0xe4,0x10,0x50,0x98,0xb6,0x0e,0x3a,0xf7,0xde,0x67,0x2c,0x8e,0x7b,0xb4,0x73,0x0b,0xc7,0x12,0xb0,0x66,0x6b,0x3b,0x99,0xd9,0x33,0x78,0x5f,0x45,0xe5,0xec,0x15,0x02,0xfa,0x8b,0x86,0xfd,0xe0,0xb7,0x84,0x72,0xf2,0x68,0x5c,0xd6,0x2e,0x37,0xe9,0x49,0x32,0x2f,0xcd,0xcd,0x1e,0x99,0x0f,0x59,0xf9,0x0b,0x03,0xf1,0x7b,0xaf,0x33,0xc3,0xe5,0x1e,0x8d,0x4f,0xbe,0x21,0xed,0x6b,0x15,0xdd,0xd2,0xeb,0x7c,0xe4,0x59,0x6c,0xf9,0x91,0xc1,0x3a,0x3a,0xb6,0x2b}}, - {{0xfc,0xb9,0x4e,0x4e,0x11,0xfe,0xe1,0xc5,0xc7,0x49,0x54,0xd2,0x2f,0x13,0x34,0x7c,0x91,0x7d,0x98,0x43,0xe4,0xb7,0x48,0xea,0xe8,0x26,0xcb,0x26,0x1f,0xe4,0x99,0x10,0xb9,0x34,0xc2,0xac,0xa3,0x2c,0xbd,0x9e,0x80,0xd4,0x12,0x3b,0xb3,0xf0,0x01,0xae,0x91,0x9f,0xba,0x77,0x32,0x4d,0x9d,0xac,0x1f,0x8d,0xad,0xa7,0x46,0x44,0x85,0xfb},{0x65,0x05,0x0b,0xd2,0x41,0xd3,0x58,0x2a,0x14,0xbc,0x7b,0x15,0x4a,0x6a,0x6a,0x18,0x71,0x09,0x25,0x33,0xac,0x73,0x53,0xab,0xd9,0x0d,0x8d,0xdf,0x95,0x59,0x7e,0x02,0x4c,0x03,0x11,0x5c,0xdc,0x80,0x19,0xd5,0x13,0x66,0x7f,0xf7,0xd7,0x23,0x18,0x40,0x84,0x16,0x6b,0x52,0x82,0x96,0x05,0x1b,0xfa,0xcb,0x4b,0x77,0x00,0x12,0xa0,0x28},{0x13,0xe0,0x16,0x1e,0x24,0x24,0xe9,0xde,0x9c,0x86,0xa9,0xcf,0x02,0x96,0xdf,0x8c,0x64,0xcb,0x3d,0x7d,0x8a,0x2a,0x73,0x18,0x20,0xc8,0xb0,0xac,0x10,0xa0,0x52,0x0c,0x6c,0x17,0xd9,0xbd,0x3c,0x3e,0xe5,0x0c,0x4a,0xdb,0x59,0xcc,0x59,0x15,0x08,0x1e,0xfe,0xaa,0xe3,0xd6,0xa1,0x37,0xd6,0xd5,0x6d,0x8e,0xcd,0x57,0xa9,0x81,0xb3,0x43},{0x46,0x28,0x2b,0xa0,0xe5,0xe3,0xf0,0x72,0xa7,0xbc,0x8d,0xec,0x45,0x31,0x6e,0xdb,0xb2,0x4b,0x20,0xbf,0x64,0x74,0x26,0x70,0x9b,0xd6,0xd3,0x7f,0x9f,0xc1,0x59,0x03,0x2d,0xda,0x6f,0xaa,0x7c,0x92,0xc6,0xe0,0xe8,0xaa,0x1e,0x26,0xf0,0x1e,0xcc,0xef,0x6d,0x87,0x04,0x3c,0xed,0x52,0x15,0xb3,0x9f,0x01,0x4e,0xe3,0x3c,0xb6,0xbb,0xac},{0x86,0x1a,0x25,0x8e,0x41,0x85,0xf9,0xba,0x98,0x15,0xb1,0xec,0x50,0xb4,0xd0,0xab,0x55,0x54,0xbb,0x3b,0x61,0xfc,0x54,0xf3,0x09,0xea,0xaa,0x6e,0xbf,0x03,0xc3,0x58,0x1d,0x24,0xb5,0xd5,0x45,0x5a,0x7a,0x14,0xc3,0x6a,0xa9,0xd8,0x6f,0x41,0xc3,0xb4,0x9a,0x05,0x71,0xbc,0x23,0x67,0xc2,0xa8,0xf5,0x7b,0x69,0xa5,0xe1,0x7a,0x35,0x1d},{0x3b,0xf5,0xa8,0xc0,0x2a,0x7d,0x85,0x88,0xd4,0xf4,0x26,0xd3,0xf4,0xe3,0x52,0x35,0x37,0x06,0x1e,0x71,0xc2,0x3b,0x7b,0xeb,0xf0,0x07,0x30,0x6b,0x37,0x31,0xb9,0x27,0xd8,0x0b,0x17,0xae,0xff,0xd4,0x7c,0x59,0xd7,0x2d,0xea,0xcb,0x92,0x2f,0x93,0xc7,0xd7,0xc3,0xaf,0x75,0x73,0x6a,0x3f,0x89,0xe5,0x13,0x0c,0x28,0x47,0xf4,0xa4,0x07,0xfb,0xd9,0x77,0xb4,0x1e,0xb2,0x70,0xca,0x85,0x22,0x58,0xc6,0x0b,0x19,0xc2,0xa5,0xba,0xc3,0xc9,0xb6,0x4a,0xdb,0x7d,0x4d,0x66,0xde,0xeb,0x8c,0x1a,0x23,0xb8,0x4c},{0x8c,0x57,0x0e,0x9f,0x0a,0xb2,0xf4,0x07,0xdd,0x7b,0x46,0xf8,0xa0,0xb1,0x33,0x4c,0x2b,0x1e,0x1a,0xe0,0x28,0x17,0x14,0xba,0x14,0x06,0x40,0x1f,0x30,0x0a,0x19,0xcd,0xe7,0xca,0xfb,0xdb,0xb9,0x76,0xf8,0x8a,0x81,0x3d,0x03,0x86,0x7e,0x66,0x75,0x1d,0xec,0xff,0x6b,0xa7,0xea,0x4c,0x8c,0x60,0xd2,0x1f,0x72,0x11,0x4c,0x5d,0xeb,0x01,0xfb,0xd9,0x77,0xb4,0x1e,0xb2,0x70,0xca,0x85,0x22,0x58,0xc6,0x0b,0x19,0xc2,0xa5,0xba,0xc3,0xc9,0xb6,0x4a,0xdb,0x7d,0x4d,0x66,0xde,0xeb,0x8c,0x1a,0x23,0xb8,0x4c}}, - {{0x05,0x64,0x16,0x53,0xbb,0xb2,0x6e,0x81,0xfc,0xe6,0xec,0xc8,0x0c,0xc1,0x75,0x59,0x23,0xe2,0x4b,0xd8,0x6a,0x70,0x34,0x50,0x37,0xc6,0xc2,0xbd,0x27,0xfd,0xad,0x4c,0xee,0xe4,0xf7,0xfc,0x91,0x05,0x48,0x3c,0xd4,0x09,0x78,0x00,0xce,0x15,0x37,0xdc,0xe7,0xce,0x48,0x09,0x3e,0x7f,0x01,0x9b,0x03,0xc8,0x2f,0x9b,0xe6,0x42,0xe1,0x71},{0x64,0xbf,0x63,0x91,0xe5,0x3e,0x90,0x89,0x96,0xea,0x59,0x51,0x60,0x7b,0x5f,0xfe,0x0f,0x76,0x86,0x19,0x45,0x82,0xd9,0x5e,0x1a,0xd1,0xf6,0x04,0xc6,0xaa,0x71,0xda,0x80,0xed,0x75,0x51,0xc8,0x9a,0x27,0x09,0xc3,0x50,0xe4,0x14,0xa1,0xc3,0xf8,0x3a,0x6c,0x84,0xff,0x87,0xd5,0xf0,0xb0,0x3c,0x5a,0x57,0x14,0x90,0xc7,0x31,0xf8,0x47},{0x88,0x7d,0xcc,0x81,0x2b,0xbb,0x7e,0x96,0xbe,0x78,0xe1,0xb1,0xf2,0xed,0x6f,0xd8,0xff,0xbd,0x7f,0x8e,0xe5,0xeb,0x7f,0x7b,0xca,0xaf,0x9b,0x08,0x1a,0x77,0x69,0x1d,0xc2,0xa4,0x7c,0x4d,0xa6,0x74,0x8e,0x33,0x24,0xff,0x43,0xe1,0x8c,0x59,0xae,0x5f,0x95,0xa4,0x35,0x9e,0x61,0xb8,0xcc,0x4c,0x87,0xb9,0x76,0x53,0x20,0xa3,0xf3,0xf5},{0x13,0x2a,0xcc,0x07,0xb1,0x5f,0xc7,0xf1,0x08,0x0e,0x7d,0x7e,0x26,0x56,0xd8,0x16,0x9c,0xae,0xac,0xc4,0xf5,0x9c,0x15,0x67,0xae,0xc4,0xcc,0x3f,0xc0,0xaf,0x53,0x28,0x1f,0x65,0x14,0xe5,0x7f,0x0c,0xf5,0x7a,0xe3,0x93,0xc1,0xa3,0xd1,0x4a,0x09,0x7d,0x24,0xab,0x22,0xc4,0xc4,0xce,0x85,0x37,0x86,0xa8,0x9c,0x39,0x33,0xba,0x1b,0x83},{0x6d,0x3e,0x92,0x5a,0xa8,0xfa,0xe6,0x71,0x98,0xa8,0x82,0x38,0xcc,0xed,0xd6,0x92,0x7e,0x3e,0xcb,0xb2,0x82,0x92,0x7a,0x56,0x9e,0xd6,0x29,0x45,0x42,0x04,0x76,0x82,0xa5,0xfc,0xd9,0x0c,0x12,0x4c,0x98,0x04,0x2a,0x3a,0x98,0x01,0xb8,0x62,0xe8,0xe6,0x7c,0x51,0xe3,0x7d,0x97,0xf5,0x45,0xb4,0x13,0xdf,0x15,0x68,0xc3,0x00,0x75,0x40},{0x7e,0x89,0x3d,0x7c,0x78,0x36,0x3c,0x85,0xda,0xb6,0x9b,0x6d,0xbc,0x52,0x7d,0xc6,0xaa,0xfd,0x90,0x62,0xe4,0xc4,0x1a,0x5a,0x2e,0xa1,0x57,0xd7,0xda,0x57,0xf4,0x58,0xc5,0x23,0x61,0x21,0xe1,0x93,0xfa,0x06,0x22,0xed,0x41,0x66,0x24,0x47,0xb9,0xed,0xc8,0x84,0x25,0x28,0x39,0xec,0xfb,0x29,0xa1,0xcd,0xe1,0x9d,0x02,0x48,0x6f,0x0a,0xe2,0x9f,0x98,0xfd,0x3d,0x18,0xa1,0x24,0x9c,0xc6,0x75,0xb8,0x99,0x76,0x2a,0xa4,0x9e,0xb1,0x97,0x2d,0x1c,0x99,0x65,0x5f,0x1f,0xda,0x14,0x4f,0x10,0x49,0xf1,0x7a},{0x2c,0xec,0x27,0x63,0xd2,0x77,0x14,0x2d,0x01,0x18,0x10,0xe0,0x23,0x1b,0xa2,0x25,0x61,0xd4,0x52,0xd9,0x90,0xde,0x97,0x7e,0xb8,0xfa,0x38,0x25,0xf2,0x91,0x07,0x3e,0xc4,0xa9,0x3e,0xb5,0x67,0x02,0x28,0x94,0x5c,0x34,0xa1,0x0a,0x5c,0x54,0x53,0xd9,0xb4,0xc4,0x5a,0x8e,0x57,0x18,0xc3,0x35,0xea,0x47,0x75,0xe0,0x44,0x01,0x71,0x09,0xe2,0x9f,0x98,0xfd,0x3d,0x18,0xa1,0x24,0x9c,0xc6,0x75,0xb8,0x99,0x76,0x2a,0xa4,0x9e,0xb1,0x97,0x2d,0x1c,0x99,0x65,0x5f,0x1f,0xda,0x14,0x4f,0x10,0x49,0xf1,0x7a}}, - {{0x41,0x10,0xd9,0x7f,0xb8,0x83,0x9e,0x42,0x43,0x7a,0xb0,0x6d,0xa6,0xcf,0xa5,0x7a,0x50,0x93,0x2d,0x13,0x94,0x37,0xa8,0x92,0x26,0x1f,0xad,0xe0,0x25,0x19,0x91,0x62,0x28,0xfb,0x18,0xbf,0x89,0xb0,0x42,0x80,0x14,0xcd,0xd2,0x72,0x84,0x1c,0xfd,0xe5,0xc3,0x71,0x3c,0x3f,0x12,0x5e,0xdd,0x53,0x39,0xf6,0x4b,0x9f,0xb3,0x5c,0xe3,0x15},{0xd0,0xc7,0x18,0x4d,0x68,0x9f,0xdd,0xec,0x81,0xf8,0xc6,0x0e,0x83,0x43,0x23,0x3d,0xfc,0xf3,0x66,0x55,0xa8,0x65,0x8b,0xd7,0x9b,0x3c,0x74,0x23,0xcd,0xae,0x60,0xe7,0x61,0xed,0x2c,0x7e,0xe7,0xa7,0x63,0x7d,0x72,0x47,0x6a,0x33,0x1c,0xaa,0x81,0xba,0x6f,0xd4,0x00,0xe7,0xa9,0x58,0xb2,0xad,0xee,0x3f,0x9c,0x70,0xff,0x2f,0x13,0x6f},{0x56,0x7b,0x19,0x66,0x42,0x9a,0x99,0x51,0x23,0x4f,0xb6,0xe7,0xcf,0x98,0xff,0x20,0x5a,0xc3,0x0e,0x36,0xc9,0xc6,0x20,0x25,0x0c,0x56,0x98,0xfb,0xbd,0xd6,0x66,0x4f,0x6f,0x94,0x85,0x8a,0x35,0xf3,0x50,0xad,0x87,0xde,0x95,0x9e,0xae,0x2a,0xd8,0xdd,0x78,0x87,0x96,0x2b,0xe0,0x12,0x95,0xd9,0x3b,0xb2,0x2a,0x06,0xe2,0xf0,0x06,0xd4},{0x42,0x24,0xdd,0x0a,0xd1,0x11,0x31,0x7e,0x56,0x45,0xb0,0x0e,0x86,0xc1,0x5d,0x8c,0x03,0x01,0xb8,0x33,0x20,0xbd,0x08,0x10,0xe5,0x70,0x92,0x2b,0x5b,0x86,0xd3,0x50,0x4c,0x1e,0xe3,0xd1,0x2a,0x4e,0x40,0x02,0x19,0x0b,0xf6,0x91,0xd9,0x9e,0xaa,0x54,0x7c,0x3d,0xba,0xc5,0x5a,0x9e,0xb2,0xbb,0x4e,0x0d,0x5b,0xdd,0x90,0xc9,0x7b,0xc2},{0x54,0x95,0xd5,0xdc,0x7e,0x7e,0xec,0xd4,0x67,0x08,0xdc,0x58,0xa9,0x80,0x8a,0x03,0x6a,0xf8,0x40,0xca,0x0d,0x5b,0x6c,0xe4,0xc9,0x71,0xa5,0xaf,0x2a,0xaa,0xe8,0x95,0x45,0xe7,0xe2,0xc3,0x47,0x84,0xc6,0xbe,0xe5,0x65,0xaf,0xcd,0x7c,0x20,0x5f,0x8b,0x19,0x61,0xe4,0xc9,0xc1,0x86,0xa5,0x6f,0x96,0xf3,0x9c,0x13,0x28,0x1b,0xcf,0x07},{0xc4,0x7f,0xf2,0x6f,0xcc,0x4a,0xf8,0xa4,0x1f,0x1d,0x6e,0x5e,0x30,0xb2,0x99,0x8f,0x5d,0x7c,0x26,0x1c,0x52,0x6f,0xd0,0x33,0xa7,0xf8,0xca,0x2a,0xc3,0x8c,0xa8,0xd1,0x50,0x4f,0xa7,0xe8,0xf2,0x10,0x4c,0xcd,0x8a,0x31,0x03,0xc8,0x93,0x2c,0xd7,0xe4,0x21,0xdb,0xa2,0x62,0x7b,0x1f,0x28,0x14,0x69,0x7e,0x87,0xac,0xf9,0xb4,0x97,0x00,0x62,0x86,0x14,0xd7,0xe4,0x65,0xdd,0x9e,0x1c,0x64,0x5f,0x3e,0xef,0xfe,0xa6,0x60,0x68,0x91,0x94,0x8a,0x1c,0x89,0xae,0xe4,0xcf,0x3a,0xdd,0xc0,0xb4,0x47,0xe8,0x8f},{0x12,0x80,0x00,0xda,0xce,0xc4,0x80,0x8f,0xa9,0xa1,0x5d,0x98,0x7d,0x2c,0xb2,0x9c,0x71,0xde,0x62,0x89,0x6a,0xe1,0x92,0xd7,0x96,0xdc,0xcd,0xc8,0x08,0x0e,0x48,0xbf,0x2a,0x53,0x72,0x90,0x31,0x71,0x49,0x02,0xda,0x4e,0x19,0x05,0x10,0xcb,0x41,0x97,0x44,0xdc,0x2d,0x1e,0x48,0xe5,0x0e,0x41,0x9d,0x7d,0x03,0xa3,0xe2,0x65,0xd4,0x01,0x62,0x86,0x14,0xd7,0xe4,0x65,0xdd,0x9e,0x1c,0x64,0x5f,0x3e,0xef,0xfe,0xa6,0x60,0x68,0x91,0x94,0x8a,0x1c,0x89,0xae,0xe4,0xcf,0x3a,0xdd,0xc0,0xb4,0x47,0xe8,0x8f}}, - {{0x00,0x4b,0x0b,0xf5,0x1f,0x07,0x1e,0x23,0xe3,0x93,0x7b,0x31,0x41,0x2a,0x0a,0x50,0x35,0xe2,0xbb,0xfe,0x51,0x77,0x6c,0xc9,0xc5,0x13,0xb9,0x87,0x79,0x65,0x68,0x20,0xcc,0x09,0x90,0xa9,0xe4,0xef,0x9f,0x1a,0xe1,0x69,0x76,0x14,0x82,0x42,0x88,0x4b,0xdc,0xe0,0x10,0x22,0xe2,0xd6,0x36,0x7c,0x0b,0xd9,0x08,0xea,0xfa,0xe4,0xfd,0x45},{0x57,0x5c,0x1e,0x20,0xb4,0xae,0x9e,0x9d,0x04,0xfb,0x1a,0xd7,0x23,0xd8,0x8a,0x6b,0x1b,0xb2,0xef,0xa9,0x06,0x38,0xbb,0x9b,0x43,0x2e,0xf1,0x81,0x0b,0x76,0xec,0x20,0x46,0x1b,0xc4,0x71,0x19,0x3e,0x79,0xe8,0xcf,0xea,0xdc,0x4b,0x3f,0x0b,0xeb,0x05,0x13,0x1a,0x2c,0xfe,0x16,0xe9,0xf0,0xc4,0x9c,0x41,0xab,0x45,0x1b,0xba,0x05,0xec},{0x06,0x0b,0x73,0xec,0x30,0x74,0x0d,0x8d,0x13,0x4b,0xef,0xac,0x3b,0x05,0xb6,0xed,0x2b,0x05,0xd1,0xa7,0x65,0xb0,0xcb,0x69,0x00,0xeb,0x47,0xe3,0x1c,0x07,0x8b,0x15,0xbf,0x69,0xff,0x27,0xb4,0xdb,0x77,0xaf,0xe9,0x9a,0xfb,0xb2,0x28,0xa4,0xf9,0x05,0xe4,0x3c,0x66,0x56,0x00,0x1a,0x2c,0x41,0xf2,0xe1,0x11,0x09,0xfa,0xe1,0x50,0x49},{0xbc,0x4d,0x6f,0x75,0x79,0x77,0x64,0x6b,0xec,0xac,0x1a,0x26,0x73,0x9c,0xf3,0xf1,0x4d,0x79,0xbe,0x6f,0x0c,0x07,0x22,0xd1,0xa1,0x31,0x75,0xa8,0x9c,0xb6,0x00,0x63,0x0d,0x40,0x17,0xec,0x83,0xda,0x82,0x2c,0x3b,0xfd,0x90,0xe3,0xbc,0xc2,0x2c,0xf5,0x3e,0x41,0xe9,0x98,0x57,0xa2,0xb7,0xce,0x5f,0x31,0xbb,0x0b,0x05,0x61,0x0f,0x55},{0xb7,0xab,0xb2,0x84,0xf1,0x67,0x24,0x16,0x61,0xe9,0x20,0x33,0x0b,0xff,0x22,0x61,0x70,0xa0,0x5d,0xf6,0xa8,0x33,0xc9,0x30,0x73,0xe5,0x89,0x36,0x59,0xea,0xa8,0xe7,0x03,0xf6,0x14,0xc1,0x79,0xb6,0x42,0xa5,0xc8,0x6c,0xb8,0x94,0x29,0x24,0x00,0x09,0xb5,0x54,0x3f,0xe1,0x6b,0xfb,0x4d,0x2d,0xa9,0x9a,0x02,0xa1,0xa5,0x09,0xf4,0xcb},{0x92,0xfa,0x18,0x84,0x3e,0xdb,0xdf,0x7d,0x87,0xd6,0x2d,0x07,0x05,0x2c,0xba,0xe4,0x30,0x76,0xa2,0xe8,0x71,0x3b,0x1b,0x93,0x5b,0xce,0x2e,0xec,0x50,0x6e,0x4a,0x0b,0x2d,0xbe,0xa3,0x76,0x92,0xf8,0xc8,0x4a,0x71,0x66,0xec,0xfa,0x36,0xc5,0xdb,0xab,0x99,0x9c,0xbf,0x99,0x07,0xe8,0xfe,0xf4,0x2f,0x90,0x16,0x5d,0xdc,0xbe,0xfa,0x08,0x93,0xde,0x13,0xf5,0x32,0x45,0x9a,0xde,0xa2,0x5d,0xb9,0xe0,0x38,0x4c,0x6a,0xcc,0x13,0x46,0x27,0x28,0xbf,0xf8,0x7a,0x9c,0x2e,0xde,0x6f,0xfe,0xe1,0x86,0x41,0x79},{0xa7,0x32,0x52,0x76,0x4f,0x3e,0x1b,0xab,0x82,0x18,0x14,0xe7,0x42,0x32,0xb8,0xa4,0x98,0xde,0xa4,0xd7,0xae,0x42,0x84,0xda,0x71,0xf7,0x78,0x40,0x56,0x94,0x64,0x49,0x34,0x37,0xeb,0xe3,0x05,0x4c,0xb9,0xbb,0xce,0xb2,0x72,0xc0,0x75,0x1c,0xc4,0xd5,0x1e,0x3a,0xc1,0x43,0xda,0xd1,0x81,0x82,0xa9,0xd5,0x0e,0x0a,0x5e,0xc2,0xd7,0x04,0x93,0xde,0x13,0xf5,0x32,0x45,0x9a,0xde,0xa2,0x5d,0xb9,0xe0,0x38,0x4c,0x6a,0xcc,0x13,0x46,0x27,0x28,0xbf,0xf8,0x7a,0x9c,0x2e,0xde,0x6f,0xfe,0xe1,0x86,0x41,0x79}}, - {{0xa3,0xdf,0x4a,0xfd,0xe6,0x74,0xb8,0xeb,0xed,0xe7,0x7e,0xd2,0xae,0xf8,0x40,0x80,0x3a,0x55,0x58,0x1d,0x6b,0xa4,0x32,0x6c,0x15,0xbb,0x67,0xdf,0x9e,0xb5,0x70,0x4b,0x7f,0x4d,0xfe,0x34,0x42,0x0c,0x4d,0xe3,0x97,0x87,0x6d,0x08,0xe8,0x4d,0x8a,0xa9,0xbc,0xbf,0x1b,0xb7,0x66,0x32,0xf4,0x7f,0x93,0xca,0xa4,0xd2,0x8f,0x02,0x7b,0xfa},{0xea,0xac,0xdf,0x25,0x39,0xf3,0x28,0xb6,0xbe,0xa8,0x4a,0x32,0x59,0x4b,0x4f,0xb5,0xd2,0xf7,0xf5,0x75,0x43,0x8b,0xb3,0x6a,0x98,0x8c,0x14,0xc9,0x3f,0x7e,0x5c,0x05,0xf0,0xeb,0x1d,0xc5,0xe6,0x1b,0x5d,0x7f,0x38,0x5d,0x9a,0xbe,0xc8,0x97,0x09,0x65,0x62,0x88,0x99,0xda,0x95,0x13,0x93,0xd9,0xa3,0x19,0x0a,0xa7,0x4a,0xb2,0x81,0xa4},{0x6e,0x70,0x65,0xaa,0x1b,0x16,0xcb,0xc1,0x59,0x6b,0xc9,0x4d,0xd1,0x0a,0x9d,0x8c,0x76,0x70,0x3c,0xc1,0xc1,0x66,0xa6,0x9f,0xfc,0xca,0xb0,0x3f,0x0e,0xe9,0xa9,0x36,0x09,0x4f,0x94,0xf3,0x32,0x25,0x34,0xf6,0xe4,0xf9,0x0b,0x0c,0xe6,0xe0,0x6d,0x9e,0xa5,0x52,0x82,0x9c,0xd4,0x43,0xa4,0xd1,0xd1,0x63,0x20,0xce,0xbc,0x4f,0x43,0xdc},{0x35,0xd6,0xc1,0x68,0xa6,0xd7,0xd3,0x36,0x82,0x2a,0x0f,0x29,0x3e,0xd6,0x15,0x29,0x19,0x73,0x14,0x78,0x87,0x86,0xca,0x9f,0x6e,0x17,0xea,0xaf,0x24,0x37,0xd6,0xb4,0xb0,0xee,0x84,0x90,0x2d,0x18,0xbd,0x26,0xc3,0xd4,0x39,0x4f,0x45,0xfa,0x2f,0x70,0xf2,0xe2,0x2a,0x2a,0x5c,0x65,0x15,0xcb,0xaf,0x92,0x9a,0xfc,0x06,0xe0,0x8a,0x1b},{0x5d,0xfa,0xc0,0x2b,0xc3,0x94,0x19,0xb4,0xd6,0x13,0xe3,0xcf,0x91,0xad,0x8c,0xe1,0x97,0x46,0xfe,0xea,0x74,0xe0,0x0c,0x03,0xf7,0x2e,0x51,0xa7,0xf2,0xbc,0xce,0xe8,0x6b,0xfd,0x2f,0x54,0x52,0x12,0x00,0x8d,0x95,0x91,0xc3,0xf6,0x25,0xf8,0x65,0x6a,0x9c,0x79,0x6b,0x71,0xc0,0x0c,0x29,0xfb,0xe7,0x14,0x9f,0x2f,0x1a,0x07,0x53,0x50},{0xe9,0xd4,0x46,0x0b,0x51,0x3f,0xf1,0xbe,0x0a,0x23,0xa5,0x38,0xa0,0xe3,0x70,0x14,0x63,0xf0,0x94,0xbb,0x1c,0x4f,0x23,0x05,0x1b,0x62,0x40,0x9b,0xf9,0x52,0x1b,0x41,0x51,0x57,0x2a,0x99,0x73,0xda,0xe1,0xcf,0xc5,0x4c,0x65,0x3a,0xc2,0x9d,0x73,0xda,0xc9,0x59,0xf1,0xdf,0xab,0x2b,0x27,0xe1,0x59,0x8b,0xa7,0x48,0xf9,0x36,0xcb,0x08,0xe3,0x5e,0x1d,0xdd,0xf9,0x20,0x4f,0x64,0xa9,0x26,0x74,0x97,0xf2,0x2d,0x31,0xac,0x8c,0x20,0x77,0x09,0xa9,0x8f,0xed,0x23,0x77,0x7e,0xd7,0x34,0x93,0x84,0xe7,0xaa},{0xaa,0xf7,0x64,0xdf,0x34,0x59,0x1c,0x2c,0xbc,0x47,0x08,0x6a,0x25,0xbf,0x9d,0x48,0x54,0xcf,0xa0,0x6c,0xfc,0xd4,0x10,0x39,0x9f,0x64,0x46,0xce,0xd9,0x95,0x28,0x89,0xdf,0x94,0x5e,0x74,0x0b,0x55,0x46,0x82,0xd9,0x3d,0x82,0x97,0x7d,0xd0,0x3e,0xd7,0xf6,0x6f,0xaa,0x97,0x3e,0xdf,0xa7,0xde,0xe3,0xc5,0xaf,0xd3,0xa0,0x5a,0x30,0x0d,0xe3,0x5e,0x1d,0xdd,0xf9,0x20,0x4f,0x64,0xa9,0x26,0x74,0x97,0xf2,0x2d,0x31,0xac,0x8c,0x20,0x77,0x09,0xa9,0x8f,0xed,0x23,0x77,0x7e,0xd7,0x34,0x93,0x84,0xe7,0xaa}}, - {{0x96,0x4e,0xf2,0x1e,0x3a,0xe5,0x77,0xbf,0xa7,0x1c,0x3d,0x66,0x08,0x06,0xca,0x55,0x43,0x7a,0x08,0xf8,0xff,0x55,0xb3,0xbc,0x9a,0x83,0x9a,0x2e,0xe6,0x97,0x14,0x32,0x36,0x57,0x5c,0xa4,0x04,0x78,0xb1,0x92,0xf4,0x23,0x94,0xe6,0x2a,0xef,0xd4,0xe7,0xc4,0x02,0x9f,0xa9,0x79,0x77,0x61,0x90,0xd6,0xdb,0x6e,0x28,0x7e,0xc0,0x1d,0x70},{0xc5,0xd1,0x5c,0x34,0x15,0xa9,0x1e,0x42,0x2a,0x1b,0x0d,0xf0,0x56,0x83,0x10,0xc3,0xc9,0x21,0xfd,0x05,0xfa,0x51,0x0e,0x11,0x28,0xcc,0x84,0xac,0x35,0xb5,0xd8,0xc8,0x5c,0x80,0x11,0x1f,0x60,0x1c,0x72,0x25,0x82,0x45,0xb5,0x4f,0x66,0x6b,0x52,0xb1,0xf7,0x28,0x0f,0x80,0x76,0x44,0xdc,0x15,0x70,0x39,0xe9,0xaf,0xc7,0x0a,0xa0,0x43},{0xff,0x20,0x5e,0x3b,0x75,0xe9,0x38,0x7c,0xa3,0x5c,0x8b,0x1a,0xec,0x17,0x8d,0xf0,0xef,0xb3,0x53,0x9b,0x16,0xa9,0x44,0xf9,0x34,0x45,0x13,0x66,0x80,0x24,0xdc,0x22,0x0e,0x51,0x94,0xed,0xe6,0x83,0x36,0x32,0x63,0x23,0x1b,0xf8,0x78,0xb4,0x04,0x7f,0x5a,0x50,0x54,0x12,0x19,0x04,0x61,0xdd,0x25,0xf0,0x48,0x29,0x04,0xc1,0x44,0xe2},{0x46,0x32,0x2d,0xc7,0xbc,0x05,0x2a,0xd3,0xb5,0xce,0x7d,0x47,0x5e,0xfc,0x90,0x38,0xef,0xfa,0x6f,0x42,0xf0,0x66,0x05,0x89,0x7c,0x9a,0xc1,0xfd,0xa2,0xe8,0xa7,0x38,0x18,0x6d,0x7f,0x9e,0xfb,0xbd,0x06,0x0c,0x70,0xd7,0x29,0x10,0x88,0x04,0x9f,0x24,0x28,0x9d,0xc7,0x84,0xdf,0xb6,0xec,0xb2,0xc7,0x1b,0xd1,0xc1,0x9d,0x56,0xb0,0x83},{0xda,0xd7,0x34,0xee,0x62,0x13,0x8f,0x47,0xad,0xb4,0x9c,0x98,0xe4,0xc5,0xb3,0x29,0x31,0x11,0x64,0xad,0xf5,0x0b,0x60,0xe1,0x0e,0x18,0x28,0x30,0x3c,0xa2,0xe3,0x29,0x89,0x0a,0x7e,0x18,0xba,0x30,0x9e,0x7d,0x53,0xf1,0x82,0xd5,0x27,0xe5,0xf3,0xab,0x15,0xcd,0x62,0x7e,0xdf,0xf0,0x0e,0x42,0xfa,0x6b,0x7b,0x54,0xd2,0x74,0x19,0x8f},{0x29,0x4d,0x28,0x80,0x62,0xb5,0x77,0xbb,0x69,0x70,0xb0,0xb7,0x10,0x2e,0xed,0xfc,0x13,0x34,0x93,0x7f,0xd8,0xfc,0xb5,0x7b,0xfe,0x34,0x0a,0xa3,0x95,0x5b,0xb1,0xa7,0xc6,0xab,0x82,0x79,0x25,0x23,0x94,0x12,0xa4,0x34,0xec,0x23,0xca,0xcb,0xd0,0xa3,0xf9,0x31,0x32,0xce,0x50,0x31,0x73,0x23,0x98,0x94,0xe3,0x08,0xd9,0x1e,0xc3,0x0b,0x39,0xe3,0x3b,0xf2,0xe8,0xb7,0x26,0x28,0x9d,0xb3,0x12,0x8d,0x16,0xca,0x89,0x26,0xa9,0x1c,0xa3,0x1f,0x36,0x10,0x60,0x6a,0x29,0x85,0xe7,0x2c,0xee,0xc1,0xb6,0xae},{0x68,0xed,0x3c,0x64,0xe6,0x87,0xf0,0x14,0x64,0xfc,0x38,0x3a,0x0f,0xd9,0x7a,0x5b,0x52,0x32,0x10,0xca,0xc6,0x83,0x0b,0xae,0x17,0x0e,0xfe,0x77,0xe0,0xe7,0x83,0xa1,0x2c,0x78,0x62,0x9c,0x79,0x08,0x2b,0xd4,0x85,0x72,0x27,0x8d,0x97,0x78,0x62,0x33,0x34,0xeb,0x5c,0xde,0x5d,0xaa,0x4d,0xfa,0xd1,0x67,0xa4,0xea,0x45,0xad,0xf9,0x06,0x39,0xe3,0x3b,0xf2,0xe8,0xb7,0x26,0x28,0x9d,0xb3,0x12,0x8d,0x16,0xca,0x89,0x26,0xa9,0x1c,0xa3,0x1f,0x36,0x10,0x60,0x6a,0x29,0x85,0xe7,0x2c,0xee,0xc1,0xb6,0xae}}, - {{0xd9,0x64,0xb2,0xe1,0x9f,0x0a,0x35,0xfc,0x9f,0xc3,0xa5,0x2a,0xa3,0x84,0xb4,0xf3,0x23,0xc4,0xf3,0x5a,0x9d,0xf8,0x7f,0x35,0xa9,0xf5,0x5b,0x68,0xfc,0x19,0x69,0x63,0x6a,0x13,0x19,0x32,0xcc,0x9d,0x0c,0x3c,0x7d,0xdd,0x85,0x16,0xa8,0xd9,0x2b,0x75,0x08,0x4b,0x9a,0xa5,0x6e,0xf3,0xe9,0xeb,0xed,0x5d,0x2e,0xfd,0x2e,0x0c,0x60,0xa2},{0x0f,0xf6,0x8c,0x3f,0x6e,0xee,0x56,0x4f,0x43,0x6f,0x54,0xbd,0x7a,0xe4,0xbe,0xa8,0x77,0x05,0x99,0xe7,0x9e,0x59,0x22,0x85,0x9b,0xc6,0xe4,0x2a,0x61,0x9c,0x19,0xb1,0x5a,0xeb,0x7a,0xf8,0x41,0x4e,0xe5,0x2a,0xd0,0xf7,0x44,0xf0,0x16,0xea,0x0c,0x04,0x19,0x6c,0xb6,0x30,0x3c,0x6e,0x2d,0x79,0x9a,0x8f,0x08,0x90,0x11,0xf1,0xc0,0x4d},{0x68,0xe7,0x1d,0x40,0xf1,0x07,0xc0,0xc6,0xb2,0x87,0x9c,0xa2,0x19,0x43,0x7a,0xdf,0x8a,0x5a,0x0f,0xe2,0x24,0x97,0xa0,0x38,0x79,0x20,0x38,0xa9,0x9c,0x77,0xc4,0x37,0xa6,0x02,0xe0,0x93,0x47,0xa4,0x55,0x21,0xc2,0x69,0xbe,0x09,0x05,0xaa,0x87,0x28,0xf1,0x95,0x2f,0xdb,0xf0,0xbf,0xd2,0x9e,0x5e,0x3a,0xfa,0xc6,0x2f,0x13,0x09,0xaf},{0xe1,0x9e,0xc8,0x4f,0xc9,0xdd,0x61,0x60,0x94,0xbc,0xd3,0xd6,0xde,0x11,0x6e,0xec,0x84,0xc4,0xdd,0xbe,0x20,0x46,0x6c,0xef,0xf6,0x9d,0x37,0x07,0x53,0x72,0x57,0xf9,0x02,0xb5,0x64,0x1f,0xe2,0x56,0xa4,0x38,0x6d,0xa4,0xed,0x23,0x9e,0xa3,0xf4,0x4d,0x77,0x52,0xdc,0x8c,0x51,0xfc,0x88,0x18,0xbc,0x83,0x2a,0xac,0xc1,0x1d,0x3d,0x59},{0x08,0x4f,0x78,0x21,0xfd,0x4b,0x85,0x86,0x4e,0x25,0xdd,0x47,0x60,0x7f,0x7e,0xc6,0xd3,0xa1,0xab,0x91,0x3f,0xeb,0xf6,0x40,0x7e,0x1b,0xbd,0x99,0x9c,0x7c,0x2f,0x4f,0xca,0x68,0xa5,0xf6,0x8c,0x1e,0xcb,0xb8,0x76,0xe2,0x87,0x5b,0x49,0x68,0x97,0x2c,0x21,0x5c,0x7c,0x93,0x79,0x9a,0x95,0xa1,0x3a,0x49,0xc9,0x6d,0x34,0x6b,0xa1,0x98},{0xb9,0x88,0x25,0x9a,0x3b,0x53,0x56,0xa1,0x48,0x0f,0xf0,0x92,0xde,0x4e,0x3e,0x3a,0xcf,0x02,0xdc,0x5c,0xc2,0xc3,0x78,0xad,0x8a,0x0c,0x3c,0xc7,0xdd,0xdd,0x71,0x6e,0x3f,0xd9,0x3a,0x57,0x2a,0x19,0xa5,0x3b,0x5c,0x46,0x7b,0xc9,0x0f,0x16,0xb3,0x58,0xa6,0x85,0xfa,0x91,0x2c,0x9a,0x9c,0x12,0xb6,0xd6,0x7d,0x9a,0xf0,0x9d,0xe9,0x02,0xad,0x12,0x87,0xda,0x85,0x58,0x6b,0xff,0x68,0x96,0x05,0x33,0xba,0x7f,0x08,0xf9,0xa9,0xa2,0xa9,0x46,0x43,0xe5,0x03,0x12,0xe4,0xbe,0x74,0xaa,0x46,0x4e,0x51,0xb3},{0x61,0x70,0x17,0x50,0x26,0xfa,0x51,0x83,0xe0,0xca,0xa9,0xb1,0xc3,0xc4,0x83,0xa9,0xb6,0x43,0x6b,0x7a,0x5b,0xe4,0x21,0x5a,0x6b,0xd4,0x34,0xf8,0xee,0x95,0x86,0x2d,0x03,0xbf,0xca,0xd0,0xfa,0x68,0x53,0xb2,0x97,0x50,0xad,0x89,0x2f,0x99,0x63,0x67,0x18,0x57,0x1f,0x57,0x41,0xbc,0xb7,0xc0,0x18,0xe7,0xb6,0xf3,0x0f,0xc4,0x49,0x0d,0xad,0x12,0x87,0xda,0x85,0x58,0x6b,0xff,0x68,0x96,0x05,0x33,0xba,0x7f,0x08,0xf9,0xa9,0xa2,0xa9,0x46,0x43,0xe5,0x03,0x12,0xe4,0xbe,0x74,0xaa,0x46,0x4e,0x51,0xb3}}, - {{0xc5,0xdf,0x86,0x8f,0xf1,0xa7,0xad,0x57,0xfd,0xb4,0x53,0xc3,0x92,0x1b,0x9e,0x2e,0xdd,0xc5,0xa4,0x3b,0x72,0xa6,0x9b,0x4a,0x15,0xca,0x35,0xed,0x3c,0x1a,0x3b,0x38,0x36,0xd6,0xf2,0x03,0xb6,0x97,0x1f,0xcb,0x40,0x5d,0x3c,0x25,0xfc,0xe7,0xff,0xc6,0xbe,0x61,0xe1,0x98,0x31,0x13,0xa9,0xbe,0x05,0x86,0xfe,0x5c,0xf6,0xcc,0xaa,0xf5},{0xd2,0x57,0x19,0x98,0xf8,0x74,0x90,0xb7,0x69,0x6e,0xdd,0x44,0xf1,0x8b,0xb1,0x9c,0xfd,0x5b,0x6b,0xc0,0x45,0xf2,0x49,0xa5,0x4b,0xff,0x8b,0x7f,0x87,0xe3,0xf9,0x71,0xab,0xfa,0xc8,0x17,0xed,0xeb,0x19,0xc6,0x3c,0xee,0x78,0xba,0x89,0x97,0x49,0x85,0x39,0x68,0x29,0x88,0x0b,0x1c,0xd1,0x42,0x8b,0xe8,0x1a,0x3b,0xeb,0x4d,0xef,0x3b},{0xea,0xfb,0xec,0x27,0xc3,0x92,0xc3,0x68,0x0d,0x3c,0x5b,0x20,0x20,0x9c,0x96,0xa7,0x39,0xfa,0x80,0x91,0xef,0x86,0x7d,0xa8,0x87,0xf6,0xef,0x14,0x01,0x46,0xf0,0x68,0x0a,0x8b,0xae,0x83,0x91,0x7e,0xa0,0x14,0x14,0xde,0xf9,0xa8,0xfd,0x67,0x57,0x17,0x20,0x46,0x43,0x49,0x07,0xf0,0x3e,0xc8,0xbe,0x66,0xaf,0x58,0x3a,0xbd,0xd8,0x00},{0x35,0xf5,0xc8,0x2c,0x0e,0x4b,0x56,0xe0,0xef,0x08,0x34,0x38,0x57,0xe9,0xde,0xdb,0x1d,0xe1,0x28,0x05,0x01,0xed,0x62,0x3d,0xa9,0x6e,0xea,0x5b,0x95,0x09,0xe0,0x04,0x46,0xff,0xdc,0x34,0xf6,0xf7,0x63,0xb1,0x76,0xb8,0x3c,0x03,0xef,0x36,0x0f,0x82,0x1b,0x5b,0x6f,0xe2,0x86,0xd9,0x10,0x01,0xe6,0x73,0x75,0x0d,0x50,0x30,0x11,0x68},{0x27,0xb6,0x3b,0x78,0x79,0xf3,0x22,0x78,0x8f,0x0c,0x14,0x8b,0x3f,0x68,0xc2,0xab,0x9f,0x9f,0x05,0x70,0x7e,0xee,0x4b,0x1b,0x6b,0xfc,0x04,0x72,0xca,0xf1,0x9a,0xba,0xe3,0x65,0x9d,0xdb,0x01,0x33,0xc5,0xdb,0xf6,0x87,0xe4,0x73,0x5a,0x0f,0x94,0xa9,0x2e,0xfe,0x8f,0x3e,0xd1,0x0a,0x6d,0xa1,0x21,0x2a,0x92,0x8c,0x4b,0x43,0x13,0x2f},{0xa3,0xa8,0x3b,0xb4,0x4f,0x8a,0xac,0xab,0x8a,0x4c,0x39,0x7e,0xb8,0x2f,0xb1,0x01,0x2e,0xbe,0x0e,0x7d,0x28,0x8a,0x18,0x4a,0xda,0x58,0x1a,0xfb,0x95,0x97,0xf3,0x63,0x58,0xbe,0x8c,0x30,0x13,0x9b,0xba,0x9f,0x4e,0xac,0x8d,0x95,0xf2,0x07,0xbb,0x85,0xa1,0x41,0x4c,0x33,0xe3,0x58,0x8e,0x5c,0xa1,0x05,0x45,0xab,0x5c,0x0c,0xe4,0x02,0xc3,0xa0,0xa0,0x72,0xdb,0x9a,0x9d,0xbf,0x13,0x29,0x94,0x70,0x8b,0xe4,0xe8,0xdb,0x0e,0x0b,0xd0,0xa0,0x25,0xad,0x71,0xa0,0x27,0x9c,0x1d,0x77,0xb0,0x98,0xa8,0x03},{0xe1,0x84,0xa5,0xea,0xa5,0xd8,0x1b,0x29,0xce,0xd7,0xa3,0x72,0xa7,0xc9,0xa5,0xea,0xf1,0x02,0xf3,0x0c,0xb0,0x65,0x12,0xbc,0xa4,0xf2,0x5d,0x69,0x00,0xa4,0x7f,0x5a,0x52,0x09,0xb6,0x7b,0x30,0xf2,0x99,0x03,0x39,0x9d,0xee,0x6f,0xb5,0xf7,0x9e,0x7a,0x97,0x8b,0x81,0x03,0x8c,0xdd,0x35,0xfc,0x1f,0x0a,0xc6,0xa4,0x60,0x7b,0xc8,0x0a,0xc3,0xa0,0xa0,0x72,0xdb,0x9a,0x9d,0xbf,0x13,0x29,0x94,0x70,0x8b,0xe4,0xe8,0xdb,0x0e,0x0b,0xd0,0xa0,0x25,0xad,0x71,0xa0,0x27,0x9c,0x1d,0x77,0xb0,0x98,0xa8,0x03}}, - {{0x67,0xe9,0x62,0x76,0x3a,0x90,0x9b,0x6b,0x19,0x1d,0x65,0xb2,0x2a,0x2f,0xf7,0x50,0xaa,0x54,0xa5,0xbb,0x53,0xb5,0xf9,0xee,0x0c,0x04,0x3a,0x3c,0x29,0x4b,0x66,0x3e,0x7b,0xb6,0xaa,0xd2,0x10,0x89,0xcc,0x89,0x2c,0x47,0xbe,0x23,0xd6,0x52,0x81,0x5d,0xc8,0xbc,0x49,0xd6,0x6a,0xcd,0x62,0x99,0x30,0xff,0x16,0xa5,0x50,0x44,0xd8,0x7a},{0xd6,0xcd,0xfe,0xd4,0x44,0x4a,0x9e,0x90,0x44,0x73,0x8a,0xff,0xbb,0x82,0x08,0xb6,0x7f,0xf2,0x87,0xcb,0xa5,0x0b,0x56,0xd3,0x9e,0x91,0xb8,0x52,0x6b,0x25,0xa6,0x5d,0x50,0xaf,0x9b,0xd5,0xfb,0x9f,0x7e,0x2d,0x57,0xdf,0x30,0x78,0x8d,0x1a,0xc3,0xac,0x9c,0x5a,0xbf,0xab,0x5a,0x0d,0xc9,0xb6,0x4b,0x18,0xd4,0xe7,0x55,0x40,0xde,0x7e},{0xc2,0xa9,0x7e,0x5c,0x26,0xf4,0x7d,0xce,0x9e,0x73,0xae,0x50,0xde,0xe7,0xa6,0xf9,0x8b,0x57,0xf9,0x7a,0x4c,0x38,0x82,0xf6,0x30,0x80,0x12,0xf7,0xf6,0x66,0x80,0x46,0x4d,0x41,0x53,0x63,0xd9,0x65,0x90,0xe7,0xee,0x24,0x07,0xb0,0x4f,0xeb,0x3e,0x8e,0x83,0x21,0xa3,0x40,0x03,0xc0,0x64,0x52,0xc6,0xb2,0x12,0x9d,0x8d,0x86,0xdd,0x19},{0xe2,0xd5,0x49,0x5e,0x2a,0x6e,0x4e,0xd9,0x31,0x26,0x53,0x13,0x98,0x5e,0x2f,0x23,0xea,0xa0,0x30,0xee,0xef,0x62,0x2b,0xdc,0x93,0x65,0x90,0xad,0x9a,0xf1,0x74,0x12,0xf5,0x24,0x33,0xcc,0xc3,0xda,0x42,0x54,0xa6,0x6c,0x86,0x99,0xb9,0xb5,0xf7,0x07,0x90,0xd8,0x85,0x7f,0x69,0xfb,0x19,0x2a,0x2c,0xc0,0x11,0x81,0x64,0x37,0x38,0x07},{0xc7,0xb3,0xf5,0xe4,0x4b,0x55,0xcf,0xd8,0x2b,0x72,0xde,0x62,0xfc,0x66,0xea,0x82,0xee,0x2e,0xe5,0x4f,0x66,0xba,0x19,0x63,0x01,0x0b,0x2d,0x89,0xb4,0xaa,0x76,0xb3,0x7e,0xc5,0xbe,0xdd,0x57,0x90,0x5e,0xff,0x5b,0x9a,0x71,0xe1,0x47,0xf9,0xec,0xe5,0xf0,0x19,0x89,0x17,0x65,0x3e,0x56,0x4a,0x98,0xb2,0x3c,0x3b,0xf0,0x14,0x13,0x1b},{0xc0,0x72,0x26,0x96,0x6b,0xf5,0x50,0xa1,0x65,0xcd,0xfe,0x92,0xa5,0x5a,0xb3,0x56,0x27,0x5b,0x2f,0x4a,0x8f,0x67,0xaa,0xf4,0xa1,0x6e,0x3c,0x66,0xcc,0xb7,0x71,0x70,0xff,0x70,0x1f,0x9e,0x09,0xae,0x31,0xcb,0x2a,0xd5,0x8a,0x38,0xa9,0xaf,0xbc,0x94,0xa2,0xa8,0xe9,0x77,0x1c,0xc3,0xfa,0xd1,0x45,0xd2,0xe2,0xff,0x7d,0xf2,0x44,0x00,0xa0,0xc3,0xc1,0xdd,0xa0,0x4c,0xfb,0xed,0x1a,0xbd,0x0c,0x05,0x3b,0xa9,0xc8,0x98,0xb0,0x7d,0x6a,0x77,0xcb,0x08,0x70,0x64,0x31,0x9d,0x9c,0x7b,0x40,0x9e,0xbb,0xf4},{0xbc,0x88,0x9d,0x36,0xae,0xbc,0x92,0x47,0x63,0x85,0x41,0xe3,0x1e,0x1c,0x39,0xf5,0xd3,0xc2,0x0a,0x7d,0x18,0x7a,0x8f,0xd3,0x0c,0x37,0x50,0x28,0x35,0x93,0x77,0x4b,0xcb,0xba,0x35,0x4e,0x94,0x48,0xe4,0x0c,0xa7,0x36,0x4f,0x74,0x2b,0xf9,0xb5,0xb5,0xeb,0x91,0x50,0x3c,0x67,0x9b,0x4d,0x25,0xd4,0x0e,0x0d,0xb9,0x5b,0x77,0xf3,0x0e,0xa0,0xc3,0xc1,0xdd,0xa0,0x4c,0xfb,0xed,0x1a,0xbd,0x0c,0x05,0x3b,0xa9,0xc8,0x98,0xb0,0x7d,0x6a,0x77,0xcb,0x08,0x70,0x64,0x31,0x9d,0x9c,0x7b,0x40,0x9e,0xbb,0xf4}}, - {{0x44,0xdd,0x62,0x9e,0x0f,0xee,0x20,0x11,0x37,0xfc,0xd0,0x5c,0xe4,0xe1,0x0a,0xb8,0xc2,0xe0,0x9c,0x2c,0x3e,0x1b,0x31,0x1c,0xdb,0xa3,0x84,0x9a,0xb7,0x4e,0x40,0x74,0x21,0xfd,0xfc,0x65,0xbd,0x38,0x8a,0x55,0x6f,0x1e,0xc3,0x14,0xfc,0x66,0x04,0x7b,0xc4,0x61,0xb0,0xcb,0xfa,0xdd,0x50,0x45,0x4b,0x2e,0xf0,0x6d,0x0f,0x26,0x6d,0xbf},{0xe6,0xbc,0x35,0x73,0xb3,0x11,0x38,0xc6,0x31,0x82,0x96,0x80,0x1d,0xa9,0xd9,0x17,0x85,0x4e,0xad,0x0f,0x5c,0xb7,0xe8,0x78,0x62,0x2f,0x3c,0x10,0x0e,0xdc,0xf2,0x7e,0xf5,0x02,0x6d,0x1a,0x50,0xc2,0x50,0x7d,0x0d,0x14,0x77,0x77,0xfc,0xbe,0x23,0x02,0x81,0x0a,0xdc,0xa3,0x16,0xfd,0xab,0xb9,0x7c,0xb6,0x7e,0x8a,0xde,0x1f,0x22,0xeb},{0xab,0xf3,0xea,0x63,0xc0,0x25,0xa2,0xc7,0x6a,0xfe,0x91,0x4a,0x0a,0x91,0xdd,0x6d,0x6f,0x8c,0xf9,0xa8,0x1c,0x9f,0xb5,0xe5,0xd2,0xac,0xe6,0x51,0x9a,0xd3,0x87,0x17,0x82,0x12,0x0a,0x58,0x99,0x7f,0x81,0x2d,0x8d,0x27,0x2d,0x1b,0xb0,0x02,0x7e,0x0d,0xd6,0x18,0x89,0x5e,0x0c,0x2b,0x57,0xa6,0x56,0x35,0xff,0x71,0x4e,0xb0,0x49,0x38},{0x36,0xdf,0x1d,0x1c,0xf6,0xa7,0x4d,0x87,0x7e,0x2c,0x3f,0xb4,0xda,0xd7,0x80,0x71,0x0b,0xf3,0x2a,0x47,0x20,0xe6,0x9a,0x3d,0x17,0x9a,0x97,0xc9,0x4e,0x53,0xa6,0xe2,0x23,0xea,0x94,0x4d,0xf9,0xeb,0x2c,0x03,0x2c,0x88,0xa2,0xe6,0xc5,0x94,0xa5,0x6f,0xc3,0x98,0xa9,0x8b,0xa7,0x41,0x7d,0xd3,0x82,0x01,0x13,0xb6,0x0f,0x39,0x1e,0xd2},{0x08,0x28,0xc3,0x1c,0xec,0x21,0x3a,0xb4,0x4c,0xb1,0xfa,0xb9,0x0c,0xfe,0xc2,0x50,0xc5,0x99,0x62,0xa0,0x11,0x74,0xcf,0x05,0x1e,0x2b,0xdf,0x6d,0x22,0x8e,0x6e,0x55,0x19,0x21,0x9c,0xa1,0x98,0x56,0x45,0x90,0x40,0x3a,0x8e,0xad,0x76,0x4d,0xd3,0x95,0x27,0x67,0x4e,0x02,0x16,0xc3,0xfe,0x5a,0x79,0x4e,0x2d,0x6f,0xd0,0xe4,0x4f,0x62},{0x40,0x14,0xe1,0x88,0x3d,0xcc,0x51,0xcb,0x98,0x86,0x06,0x4d,0xe4,0x52,0x71,0xe2,0x2e,0x2b,0x80,0xfd,0x81,0x65,0xaf,0x93,0x31,0x87,0xe0,0xff,0x31,0xab,0xff,0x53,0x0e,0x2d,0xb1,0x47,0xe6,0x44,0xb7,0x29,0xab,0x0f,0x51,0x3a,0x53,0x84,0x36,0x58,0x8c,0x5f,0x7b,0x65,0x6a,0xb7,0x6f,0xdc,0xad,0xc1,0xa3,0xe4,0x21,0xfc,0x22,0x0e,0xc1,0x10,0xd1,0x7d,0x9f,0xd3,0x1e,0x33,0xb4,0xca,0xb9,0xff,0xd8,0x27,0xb8,0xca,0xde,0x49,0x6f,0xdc,0xf0,0xe8,0x70,0x36,0xdb,0x90,0x00,0x07,0x9e,0x77,0x39,0xfe},{0xc9,0x93,0x4b,0xe6,0x47,0x7e,0x1d,0x86,0x15,0x46,0xe8,0x27,0xf5,0x84,0x67,0x4e,0x42,0xe3,0x2b,0x8a,0x4e,0x90,0x7b,0x87,0xcc,0xdf,0xaa,0x04,0x06,0x05,0xe6,0x72,0xff,0x6f,0x44,0x1b,0x08,0xad,0x79,0x3e,0xb7,0xdd,0xd7,0x2c,0x73,0xf0,0xf0,0xc4,0x6e,0xb7,0x37,0xe1,0x02,0xf5,0x42,0xe7,0xef,0xa1,0xdd,0x50,0x9a,0xc5,0x8d,0x00,0xc1,0x10,0xd1,0x7d,0x9f,0xd3,0x1e,0x33,0xb4,0xca,0xb9,0xff,0xd8,0x27,0xb8,0xca,0xde,0x49,0x6f,0xdc,0xf0,0xe8,0x70,0x36,0xdb,0x90,0x00,0x07,0x9e,0x77,0x39,0xfe}}, - {{0x3e,0x0c,0x21,0xc4,0x3d,0x64,0x61,0xc1,0x9d,0xa1,0x83,0x10,0x74,0x1d,0x56,0x12,0xaf,0x29,0x5c,0x6c,0x12,0x48,0x0a,0xc7,0xe5,0x12,0xb6,0x42,0x6b,0x54,0xf4,0x42,0x0c,0x43,0x42,0x2e,0x78,0xc2,0xe7,0x26,0x09,0x41,0x4a,0x2f,0xa1,0xb0,0x1f,0xcd,0x63,0x76,0x1e,0xa1,0x6f,0xf6,0xe2,0xc2,0x08,0x89,0x0d,0x28,0xbf,0x1b,0x56,0x5b},{0x3e,0x2e,0xf2,0xcc,0x81,0xca,0xa7,0x5d,0x01,0xd2,0x82,0xfd,0x45,0xee,0xc0,0xf5,0x49,0x3b,0xe2,0xa4,0x2a,0x4d,0x5f,0x40,0x0d,0xbc,0xb9,0x3d,0x6e,0xda,0xe2,0x86,0xe1,0x23,0x8b,0x5f,0x0d,0xa2,0x35,0x15,0x1d,0x22,0x23,0xa5,0x69,0x56,0x34,0x78,0xb3,0xb3,0x55,0xef,0x63,0x8a,0x17,0x63,0xda,0xf0,0x64,0x99,0x8a,0x8a,0xba,0xd6},{0x68,0x79,0x36,0xa7,0x6b,0xe3,0x76,0x1c,0xe3,0x38,0x0b,0xa3,0x91,0xb6,0xb0,0x82,0x37,0xfa,0x52,0x74,0xf1,0xb5,0xd5,0xd9,0x07,0x06,0x9e,0xda,0x87,0x6b,0x0f,0x24,0x4f,0xbe,0xc9,0xff,0x03,0x41,0xaf,0x77,0x68,0xed,0xe7,0x71,0xba,0x2d,0xde,0x27,0xa1,0xbf,0xa8,0xa7,0x30,0x7c,0xcb,0x79,0x72,0x89,0x1a,0xdc,0xc1,0xe4,0xb2,0x9d},{0x94,0xa3,0x11,0xf4,0x44,0x80,0xd0,0xa3,0x47,0x93,0x36,0xe2,0xbd,0x04,0xe4,0x74,0x3d,0x00,0x60,0xad,0xd0,0x2d,0x86,0x66,0xa1,0x72,0x1a,0xb9,0x1c,0x14,0xa2,0x9b,0x4b,0x04,0x7d,0x5b,0xcd,0xf8,0x01,0x33,0xde,0x34,0x10,0x29,0xc4,0x72,0x56,0xff,0x11,0xcd,0xd8,0x61,0x2c,0xb6,0xb7,0xf4,0x24,0x8b,0x44,0xb4,0xe7,0x34,0x50,0xb8},{0x72,0xf6,0xd4,0xa3,0x24,0xf9,0xef,0xf4,0x55,0x8d,0x3c,0x07,0xca,0x10,0xdd,0x54,0x87,0x13,0x32,0x78,0x5c,0x64,0x10,0x08,0x62,0x7e,0xf4,0x34,0x0f,0x1c,0xcd,0xcc,0x3b,0x42,0xfe,0x60,0x41,0x70,0x2c,0x6b,0xd4,0x6c,0xf7,0xb8,0x24,0xf6,0xd7,0x07,0xb3,0x46,0xb0,0x7d,0x14,0x24,0x9b,0x72,0x79,0xf4,0x23,0x2a,0xec,0x02,0xe7,0x69},{0xe5,0xbe,0x84,0xc3,0x92,0x47,0x15,0xd3,0xac,0x06,0x44,0x72,0x41,0xeb,0xb6,0x5a,0x17,0x06,0x90,0xd9,0x55,0x3d,0xe4,0x87,0x7d,0x5a,0x11,0x9f,0x02,0x6d,0xd3,0x4e,0x71,0xd1,0x5e,0x16,0x9f,0xb2,0xc0,0x7f,0xcb,0x78,0x8b,0x89,0x11,0xae,0x43,0xe8,0x85,0xb7,0xf9,0xc8,0x48,0x5a,0xb2,0x96,0xaf,0x8f,0xab,0x71,0x84,0x9d,0x40,0x09,0x30,0xd4,0x32,0x6e,0xa2,0x77,0x97,0x71,0x37,0xce,0x22,0x6b,0xca,0xc9,0x79,0xef,0xc0,0xb2,0xb4,0x3d,0x30,0xbf,0x77,0xe9,0xc3,0x8d,0xec,0x15,0x04,0x08,0xfa,0x15},{0x4b,0xf3,0x7f,0xb2,0x78,0x75,0x45,0xd4,0xce,0x5e,0x3d,0xaf,0x92,0x63,0x3d,0x90,0xc0,0xa7,0x23,0x62,0x7f,0x37,0x58,0x8d,0x12,0xe0,0xb8,0x6c,0x46,0x38,0xaa,0xf7,0xe1,0x03,0x9e,0x1f,0x31,0xf9,0x5a,0xa4,0x59,0x0d,0xec,0xc5,0x1f,0x17,0x88,0x25,0xcc,0xed,0x69,0x2b,0x91,0x73,0x6a,0x3f,0xcb,0xe5,0x9c,0x1e,0x26,0x3e,0xec,0x0b,0x30,0xd4,0x32,0x6e,0xa2,0x77,0x97,0x71,0x37,0xce,0x22,0x6b,0xca,0xc9,0x79,0xef,0xc0,0xb2,0xb4,0x3d,0x30,0xbf,0x77,0xe9,0xc3,0x8d,0xec,0x15,0x04,0x08,0xfa,0x15}}, - {{0xc5,0x1d,0xcd,0x70,0xb2,0x9e,0x53,0x29,0x05,0x78,0x83,0x5d,0x56,0x30,0x89,0xee,0x02,0xd7,0xac,0x57,0x0a,0xd2,0xa0,0x9c,0x96,0x0c,0xbf,0xf2,0x30,0xbf,0x1a,0x2b,0xee,0x0e,0x9f,0x1e,0x1c,0x65,0x7d,0xb5,0x48,0xad,0x6f,0x51,0xa0,0x91,0x61,0xe4,0xe6,0x83,0x9f,0x58,0x7c,0x76,0x2b,0x52,0x94,0x87,0x3c,0x8d,0x36,0x4c,0x37,0x3c},{0x59,0x3b,0x0d,0x38,0xab,0x93,0xca,0xfb,0x67,0x44,0x30,0x96,0xec,0xbd,0x00,0x1d,0x93,0xd0,0xb3,0x3d,0x3c,0xd4,0x4e,0x3d,0xd8,0x29,0x93,0xb2,0xb3,0x77,0xfc,0x57,0x31,0x20,0xe3,0x90,0x0d,0xf4,0x91,0x2f,0x8b,0x43,0xce,0xfe,0x99,0x03,0x03,0xa2,0x90,0x8d,0xcf,0xa8,0xc0,0x21,0x00,0xca,0xcc,0xcb,0x4b,0x2f,0xa5,0x39,0xa8,0x0b},{0xca,0xf6,0xf9,0xbb,0x53,0xcb,0x97,0x76,0xb6,0x9c,0x2c,0x18,0x21,0x43,0x13,0x48,0x13,0xc9,0x0e,0xeb,0x40,0xea,0xce,0x1f,0x3a,0xe9,0xd2,0x9e,0x29,0xdb,0xe2,0x79,0xe2,0x1a,0x9f,0x84,0x9d,0xe4,0x55,0x82,0x17,0xeb,0x87,0xf6,0xc3,0xef,0xcd,0x54,0x14,0xee,0xc8,0x5b,0xd7,0x67,0x05,0xe2,0x34,0xa2,0x7e,0x81,0x83,0x21,0x7a,0x02},{0xc5,0x03,0xd9,0x75,0xdf,0x17,0x15,0xe3,0x5b,0x7b,0x4f,0x66,0x9c,0x15,0x4e,0x01,0xdf,0x3d,0x16,0xb6,0x52,0xcc,0xcf,0x28,0x40,0xdb,0x20,0xee,0x8b,0x69,0xb1,0x2b,0xc0,0x6e,0xe4,0xd2,0xf5,0xd1,0x49,0x3f,0xf3,0x0a,0x12,0xcd,0x13,0xbd,0x9d,0x3d,0x5b,0x28,0x5c,0xb0,0x0d,0x0e,0xb6,0xed,0xec,0x65,0xeb,0x25,0x28,0x2e,0x65,0x2f},{0xed,0xa7,0x05,0xc1,0xa6,0x81,0xf2,0x7a,0x69,0x68,0x17,0x8e,0xf7,0xc9,0x14,0x80,0x9f,0x81,0xfe,0x16,0xfd,0x81,0x93,0xb4,0x0b,0x05,0x5b,0x4e,0xef,0x6e,0x7a,0x67,0x9d,0x99,0x4c,0x17,0xcd,0x1c,0x16,0xfd,0x31,0x35,0xd5,0x3e,0xa3,0x00,0xbf,0xbe,0xda,0xd6,0xe2,0x37,0x9b,0x13,0x1b,0xca,0x29,0x90,0x4b,0xf2,0x09,0x57,0x2f,0xe9},{0xd7,0xba,0x23,0xd3,0xa0,0x6e,0x14,0x6a,0xf0,0x77,0xb7,0xe6,0xe3,0xc9,0x3b,0x38,0xbb,0xe7,0xbe,0x54,0x75,0xf8,0xb7,0x42,0x29,0xe2,0x83,0xde,0x20,0x22,0x41,0xcf,0x5f,0x6f,0x80,0x60,0xf3,0x44,0x04,0x21,0xd5,0x03,0x68,0x42,0xde,0x81,0xea,0xe8,0x7e,0x5b,0x80,0x0f,0x1b,0x2d,0x06,0xc7,0xce,0xe9,0x46,0xc7,0xf7,0xb3,0xa2,0x02,0x21,0xb5,0x4d,0xc2,0x36,0xea,0xe6,0x7b,0xb3,0x61,0xe6,0x18,0x40,0x5b,0xce,0x5b,0xc2,0xee,0xa5,0xde,0xe9,0xe6,0xe0,0xa8,0x58,0x58,0x03,0x34,0x26,0x27,0x65,0x2a},{0xfa,0x43,0xa6,0xc4,0x32,0xa1,0x2f,0xb6,0x37,0x05,0xf4,0xa4,0xa7,0x36,0xdd,0x1c,0x45,0x10,0x95,0x83,0x67,0x89,0x79,0x18,0x34,0xad,0xe7,0x57,0x7f,0x0d,0x48,0x9b,0x14,0xdf,0x5f,0xc8,0xd7,0x0f,0x78,0x47,0x88,0x20,0xff,0x7f,0xb1,0x21,0x27,0x14,0x58,0x32,0x12,0xfb,0x97,0xe0,0x81,0x0e,0x92,0xf4,0x5c,0x0e,0x44,0x48,0x4e,0x01,0x21,0xb5,0x4d,0xc2,0x36,0xea,0xe6,0x7b,0xb3,0x61,0xe6,0x18,0x40,0x5b,0xce,0x5b,0xc2,0xee,0xa5,0xde,0xe9,0xe6,0xe0,0xa8,0x58,0x58,0x03,0x34,0x26,0x27,0x65,0x2a}}, - {{0x1e,0x89,0x12,0xe8,0xab,0xca,0xeb,0x96,0x78,0x43,0x89,0x79,0x26,0x61,0x86,0x2e,0x37,0xd7,0x94,0xb5,0xb9,0xf7,0xc9,0xe7,0x04,0x6c,0x96,0x1c,0x54,0x0d,0xb0,0x6c,0xd3,0x68,0x9b,0x53,0xa7,0x56,0x34,0x1b,0x65,0xff,0xf9,0xee,0xf1,0xc6,0xfd,0x7e,0xa8,0x42,0x59,0x60,0x06,0x5f,0xc2,0x89,0x8b,0xfc,0xf8,0x6c,0x9a,0x0d,0xb1,0x36},{0x52,0x3d,0x83,0x25,0x0f,0x57,0x81,0x76,0x7b,0x21,0xf7,0x96,0xd6,0x1f,0xfe,0xd7,0x7c,0xc1,0x32,0xb5,0xbc,0x05,0x46,0xdb,0x6f,0x25,0xd8,0x7a,0x68,0xe2,0x01,0x81,0xf8,0x9a,0xc5,0x29,0x78,0x1c,0x01,0xc5,0x4d,0x61,0x4e,0x75,0xdf,0x9f,0xc3,0x22,0x96,0x7c,0xf9,0xa7,0xed,0x41,0x6f,0x64,0xfd,0xd4,0x61,0x58,0x0d,0x49,0xc9,0xa4},{0x4a,0xf7,0xda,0xef,0xe0,0x3b,0x33,0x19,0x79,0x02,0x7a,0xbb,0xd3,0x53,0xf4,0x8c,0x8a,0x16,0xfb,0xbd,0x35,0xd9,0x70,0xb2,0x0a,0x06,0x05,0x14,0xd0,0x9e,0xf6,0x13,0x44,0xbb,0xb7,0x93,0x86,0x1b,0x3c,0xb0,0x54,0xa7,0x48,0xc2,0xa7,0x10,0xda,0x65,0xb2,0xdb,0x0f,0x85,0x23,0x57,0x77,0x44,0x23,0x20,0x6d,0x2e,0xde,0x20,0x01,0xed},{0x9c,0xb8,0x68,0xeb,0xbb,0x8b,0xaf,0x81,0x9c,0x2f,0x90,0x4c,0xc2,0x62,0x17,0xfc,0xf2,0xa5,0xab,0x4c,0x2e,0x69,0xcb,0x82,0x5f,0x4c,0x3c,0x82,0xcd,0x6a,0xcb,0x15,0xa2,0xfc,0x50,0x54,0x5e,0x2e,0x83,0x52,0x48,0x29,0x51,0xcc,0x50,0xaa,0x27,0xa3,0xf3,0x71,0xdb,0x2c,0x1c,0xa9,0x8a,0xa5,0x95,0xab,0x3e,0x6f,0xcd,0xba,0x22,0x7c},{0xf7,0x5d,0xb5,0x20,0x65,0xfe,0xa9,0xe7,0x1f,0x8e,0xd6,0xc0,0xf2,0x3f,0x1b,0x8c,0x7a,0x02,0x54,0xd8,0xa7,0x0e,0x6f,0x68,0x94,0x81,0xff,0x30,0x0e,0x6d,0x1a,0x96,0x1b,0x86,0x07,0xaa,0xbf,0x37,0xc5,0x5e,0x26,0xa2,0xdf,0x0b,0xd0,0x7f,0x94,0x35,0x30,0xa4,0x9e,0x47,0xaf,0xad,0x9c,0xc9,0x02,0x21,0x55,0x94,0x04,0x13,0xff,0x64},{0x9c,0x8d,0x18,0x63,0x83,0xad,0x01,0xcc,0xbb,0xe6,0x00,0xda,0x15,0xce,0xc6,0x6e,0x7a,0x37,0x6a,0x81,0x44,0xb3,0xfc,0xb7,0xcd,0x05,0xee,0x4a,0x6f,0x29,0xe4,0x79,0x63,0x52,0x7e,0x14,0xc9,0x14,0x77,0xa8,0x19,0x94,0x03,0xc6,0x51,0x57,0xf1,0xcc,0x11,0x29,0xde,0x86,0x08,0xfe,0x41,0x02,0x71,0xb7,0xbf,0xd7,0xe7,0x83,0x3e,0x0c,0x9a,0x59,0x7e,0xe8,0x61,0x36,0x56,0x9a,0xbf,0x64,0xfd,0xf3,0xb7,0xb9,0x2f,0x9e,0x56,0x1f,0x57,0x45,0x2e,0x19,0x0f,0x6f,0x70,0x01,0xc2,0x48,0x05,0x23,0x9b,0x2f},{0xb5,0x4e,0xe7,0xcc,0x7b,0x66,0x7a,0xf8,0xec,0xcd,0x1b,0x0c,0x0f,0xec,0x04,0x27,0xa0,0x61,0xfd,0x12,0x2d,0xab,0xc9,0xc5,0x8e,0xee,0x36,0xc2,0xef,0x67,0xd5,0x87,0x95,0x6c,0x12,0xb7,0x12,0x81,0x55,0xe0,0x7b,0xdb,0x8f,0x67,0xea,0x04,0x55,0x91,0x9b,0x50,0x65,0x05,0xc1,0xf1,0x0b,0x04,0x91,0x66,0x3c,0x32,0x53,0x72,0x01,0x04,0x9a,0x59,0x7e,0xe8,0x61,0x36,0x56,0x9a,0xbf,0x64,0xfd,0xf3,0xb7,0xb9,0x2f,0x9e,0x56,0x1f,0x57,0x45,0x2e,0x19,0x0f,0x6f,0x70,0x01,0xc2,0x48,0x05,0x23,0x9b,0x2f}}, - {{0xc8,0x37,0x10,0xdc,0xdb,0xfc,0x51,0x91,0xae,0x37,0xa4,0xe0,0xcf,0xbb,0xdd,0x92,0x93,0x5f,0x6b,0xd6,0x81,0xbf,0x9b,0x24,0x5e,0x0d,0xf1,0xe4,0x04,0x89,0xd1,0x1b,0xb2,0x68,0x56,0x3a,0xdc,0x59,0xd0,0x8a,0x93,0x37,0x5d,0xa5,0x40,0x5e,0xfe,0xc9,0x41,0x0b,0x8a,0x50,0xd2,0xa0,0x94,0x86,0xf7,0x46,0x3b,0x7e,0x1d,0xea,0x2b,0xa8},{0x1b,0xe2,0xe6,0x48,0x86,0xa8,0x65,0xfd,0x2b,0xae,0xc7,0x7d,0x41,0xee,0xb2,0x80,0x33,0x1c,0x0a,0xdc,0x42,0xea,0x99,0xd0,0x1f,0x6d,0xc8,0x80,0x51,0x70,0xd4,0x19,0xae,0xfc,0x66,0x16,0xa2,0x53,0x27,0x19,0x7a,0xf2,0x9a,0x25,0x0c,0x39,0x8c,0xbf,0xe7,0xa3,0x7a,0xd6,0xa3,0x43,0x62,0xd2,0x4a,0xc2,0xf1,0x96,0x7e,0xe3,0x83,0x13},{0xf5,0xb1,0x2a,0xc5,0x4d,0xcc,0xdf,0x56,0xde,0x92,0x96,0x46,0x03,0x11,0xfc,0xa0,0xbc,0xa2,0x22,0xf7,0x25,0x74,0x2a,0x1f,0x27,0x34,0x18,0xe8,0x06,0xa4,0x77,0x26,0x1a,0x51,0x5e,0xfb,0x77,0xbc,0x55,0xb1,0xf8,0xa5,0x19,0x23,0x00,0x97,0xf7,0xbb,0xe4,0xcd,0x41,0x9e,0xd9,0x5e,0x0c,0x6b,0x1b,0x8a,0xba,0x52,0x93,0xbe,0x2c,0xf3},{0xb3,0x02,0xeb,0x44,0x3c,0x05,0xae,0x9c,0x94,0xa9,0x1f,0x72,0x41,0xbc,0x81,0x66,0x5f,0x50,0xc0,0x57,0xb4,0x44,0xf0,0xe1,0x2a,0xa9,0x88,0x69,0xa6,0x1c,0x05,0x85,0xda,0xc7,0xb2,0xe1,0x8c,0x2f,0x7c,0x49,0x37,0xa2,0xf2,0x56,0xab,0x12,0x9f,0x12,0x4b,0x1b,0x73,0x75,0x3f,0x30,0x0f,0x40,0xf1,0xf9,0x1d,0xa7,0x2c,0x98,0x8c,0x91},{0xcb,0xd3,0x39,0x60,0x56,0xe3,0xbd,0x65,0x86,0x1a,0x58,0x40,0xc0,0xa4,0xc4,0x8b,0xe5,0xf7,0x49,0x0a,0xf2,0x09,0x51,0x32,0x6e,0x06,0x5a,0x27,0x19,0x78,0x2e,0x3a,0x04,0xf9,0x34,0x80,0x49,0x39,0x93,0xcd,0x89,0x67,0x7b,0xc0,0x8d,0x9d,0x8d,0x4c,0x83,0x20,0x80,0xfc,0x00,0xf2,0x8a,0x8f,0xa4,0x4d,0x8e,0x8f,0x58,0x51,0x5b,0x71},{0x71,0x3f,0x90,0x41,0xb8,0x74,0xbc,0x7a,0x85,0xf5,0xab,0xca,0x7e,0xf2,0x70,0x41,0xbc,0x36,0xb5,0xc3,0x4e,0xf1,0x2b,0x17,0x35,0x40,0xdb,0x3c,0xdb,0xd2,0xec,0x0b,0x99,0xc1,0x43,0x17,0xad,0x38,0x45,0x2d,0x07,0x31,0xd7,0xb6,0x95,0x1c,0x89,0x25,0xe4,0x89,0x97,0xd3,0xcf,0x11,0x2f,0x63,0x31,0x51,0xa2,0x18,0xfc,0x12,0x04,0x0a,0xb0,0x33,0xce,0x0b,0x57,0xc0,0x8c,0x58,0x25,0xf8,0x9b,0x50,0x22,0x1c,0x5c,0x7b,0x02,0xc7,0xed,0xfc,0x98,0x8b,0xbd,0xd2,0x4e,0xfc,0x78,0x91,0x7f,0x4c,0x99,0x24},{0xfc,0x46,0xe4,0x85,0x0c,0x52,0x14,0xf8,0x8a,0xa4,0x97,0x17,0x10,0xb2,0x93,0xef,0xa0,0x66,0x3c,0xfd,0x61,0x42,0x24,0x30,0x70,0x4b,0xfd,0x0b,0x86,0xc8,0x97,0xd7,0x04,0xc2,0xa6,0x61,0x41,0xaf,0xcc,0x1d,0x52,0xc9,0xf3,0xca,0xe1,0x90,0x7c,0xbd,0xce,0xaf,0x30,0xc4,0xb4,0x7d,0x81,0x7e,0xbd,0xe2,0x09,0x70,0x1e,0x6b,0xb9,0x03,0xb0,0x33,0xce,0x0b,0x57,0xc0,0x8c,0x58,0x25,0xf8,0x9b,0x50,0x22,0x1c,0x5c,0x7b,0x02,0xc7,0xed,0xfc,0x98,0x8b,0xbd,0xd2,0x4e,0xfc,0x78,0x91,0x7f,0x4c,0x99,0x24}}, - {{0x5f,0x01,0x6d,0xec,0x82,0x02,0x96,0x47,0x74,0xd9,0x73,0x2e,0x2e,0x17,0x00,0xb6,0xe0,0xa4,0x13,0x17,0xae,0x7f,0x85,0xcb,0xff,0xe7,0x96,0x99,0xdb,0x9f,0xad,0x21,0x60,0xd9,0x12,0xdc,0x41,0x01,0x33,0x66,0x4c,0x24,0x8b,0x25,0x17,0xd7,0x22,0x14,0x12,0x4d,0xad,0x82,0x9a,0x85,0x69,0x5e,0x35,0x10,0xe0,0xd7,0x1a,0x82,0x88,0x14},{0xab,0x5f,0x2c,0x7d,0xa2,0xe5,0x67,0x5f,0xe4,0x92,0x03,0x93,0xd7,0x13,0xa1,0xfa,0x4a,0xb7,0x18,0x4a,0x8e,0x8c,0x78,0x9a,0x0c,0x60,0x02,0xe8,0x2d,0x50,0x05,0x0f,0x92,0xee,0x9f,0x81,0xde,0x6b,0x20,0xe4,0x9b,0x17,0x2e,0x99,0x0f,0x01,0x31,0xa7,0xc5,0xc4,0x53,0x70,0xda,0x03,0xc6,0xf7,0x22,0x87,0x98,0x87,0x19,0x36,0xa6,0x49},{0x93,0xab,0x22,0xc4,0x39,0x6c,0x97,0x80,0xd2,0xe2,0x36,0xfa,0x31,0x74,0x67,0xcc,0x50,0x1b,0x95,0xbe,0x77,0xe0,0xd1,0x00,0x74,0x04,0xe1,0x4d,0xca,0x44,0x35,0x72,0x74,0x69,0x82,0x23,0x56,0x9b,0xcc,0x34,0x5a,0xcb,0xa2,0xa3,0x31,0x12,0x4a,0x84,0x4c,0xe9,0x37,0x3a,0x58,0xf8,0x79,0x65,0x4a,0x66,0x79,0x82,0xf4,0x5d,0x75,0xc3},{0x2d,0x5d,0xac,0x4f,0xb5,0x00,0x68,0x3b,0x5f,0x2e,0xdd,0xcb,0x14,0x4a,0x7f,0xad,0x12,0x45,0x91,0xd1,0x84,0xd8,0x14,0xff,0xcb,0x64,0x43,0x6d,0x65,0xe7,0x19,0x68,0x2b,0x5e,0x53,0x05,0x74,0x66,0xed,0xac,0x2f,0x5a,0x8f,0x70,0x96,0xab,0x29,0xf3,0x9a,0x59,0xa2,0xe2,0xef,0xd3,0xc9,0xd7,0x53,0xf8,0xf5,0xa3,0xd6,0xf4,0x34,0xf8},{0x1d,0x14,0xf3,0xfd,0xb0,0x66,0x20,0xff,0xfc,0x79,0x47,0xc7,0x4c,0xe9,0x45,0x67,0xf5,0x97,0x14,0xea,0x7c,0x63,0xc5,0x3f,0x0b,0x46,0xe0,0x88,0xd6,0x9b,0x67,0x71,0xba,0xa6,0x15,0x28,0x94,0x54,0x83,0x68,0x00,0x3a,0x33,0xa6,0x1a,0x05,0x6a,0x68,0x72,0x98,0x48,0x71,0xea,0x5b,0x47,0xf5,0x80,0x46,0xa9,0x57,0x84,0xec,0xad,0xfc},{0xa3,0x1d,0x87,0xd3,0x28,0x62,0xc6,0xf7,0xdb,0xfb,0xfa,0xfc,0xf3,0x27,0x5c,0x31,0xd3,0x32,0x26,0x0e,0x0f,0x41,0x49,0xec,0x05,0x16,0xf7,0xa5,0x63,0xb3,0xbc,0xe5,0x0d,0x1e,0x6f,0x97,0x4f,0x68,0x40,0xc0,0xd4,0x6c,0x4f,0x9e,0x25,0xd0,0xab,0x8d,0x2a,0xb9,0x3e,0x06,0x4d,0x9d,0x3d,0x2d,0x79,0x8d,0x93,0xdc,0xfc,0x6f,0x0b,0x04,0x48,0x7c,0x19,0x5c,0xa9,0xc8,0x44,0xe5,0xf6,0x4f,0x51,0xd8,0x72,0x63,0x41,0xda,0x62,0xac,0x78,0x73,0xb3,0x3e,0xc8,0xb2,0xf1,0x3f,0x89,0xf2,0x0e,0x95,0xdf,0xed},{0xfd,0x69,0xb1,0x9a,0xdb,0xae,0x95,0x87,0xe2,0xc6,0x8a,0x97,0x0c,0xee,0xc4,0x22,0x60,0x4e,0x96,0xa9,0x72,0xb9,0x6f,0x86,0x97,0xa8,0xdf,0x83,0xc5,0x18,0x18,0x6e,0xc9,0x43,0x30,0x7e,0x5b,0xcf,0x37,0x0f,0xc1,0xd7,0xe5,0xab,0xb1,0x31,0xe0,0x97,0xc7,0x53,0xb7,0xfd,0xd7,0xdf,0x00,0x43,0x0e,0x41,0x62,0x80,0x0b,0xe3,0xe0,0x06,0x48,0x7c,0x19,0x5c,0xa9,0xc8,0x44,0xe5,0xf6,0x4f,0x51,0xd8,0x72,0x63,0x41,0xda,0x62,0xac,0x78,0x73,0xb3,0x3e,0xc8,0xb2,0xf1,0x3f,0x89,0xf2,0x0e,0x95,0xdf,0xed}}, - {{0x98,0x29,0xf7,0x57,0xfd,0xbd,0x44,0x3f,0xd9,0x90,0x98,0x19,0x97,0xf2,0x60,0x27,0xfd,0x08,0xfc,0x8a,0xc6,0xaf,0x87,0x22,0x7f,0x74,0x4a,0x80,0xaf,0x72,0x00,0x01,0x70,0x9b,0x47,0x2a,0xd2,0x8e,0x41,0x0a,0xea,0x6a,0xdf,0xb7,0x61,0x54,0x89,0x5e,0x01,0x9f,0x76,0x64,0x29,0xee,0x8d,0x85,0x20,0xff,0x30,0x58,0xc2,0xa3,0x2a,0x56},{0xea,0x69,0x8e,0x6b,0x8e,0xdd,0x55,0x22,0x45,0x61,0xd4,0x92,0x66,0x8e,0x96,0xaf,0x7e,0x40,0x28,0x72,0xc4,0x46,0xe7,0x88,0xd4,0x6c,0x74,0xb7,0x48,0x7f,0xe8,0xe1,0x5e,0xa5,0x85,0x62,0x8f,0xd6,0xfc,0x27,0x0a,0xb2,0x4b,0x38,0x94,0x59,0x52,0x0d,0x6a,0x4d,0xe5,0x61,0xce,0x0d,0x44,0x03,0xa6,0x2a,0xc2,0xd4,0xd4,0xe2,0x71,0xe3},{0x40,0xf0,0x82,0xf0,0x8d,0xaa,0xad,0xa9,0x9f,0x9b,0x85,0x02,0xcf,0x57,0x15,0x41,0x13,0x59,0xf2,0xba,0xdd,0xbf,0x93,0xe5,0x40,0x2e,0xaf,0xdd,0x43,0x52,0xc8,0x7f,0x40,0xad,0x91,0x5b,0x58,0xd1,0xa1,0xe8,0x6f,0x77,0xc3,0x41,0x35,0x5e,0xf7,0x03,0xba,0xe4,0xed,0x2c,0x28,0x59,0xd6,0x48,0xfe,0x50,0xcc,0xf9,0x80,0xd1,0x49,0xd1},{0xd7,0xa5,0xd9,0x13,0xdf,0x7d,0xf6,0xc6,0x25,0x0f,0x52,0xc2,0x57,0x61,0x20,0xf2,0xf0,0xdb,0x47,0x49,0x56,0xaf,0x89,0x11,0xa7,0x8d,0x09,0x3a,0xfe,0x45,0x43,0xef,0x9f,0x0c,0x42,0xaf,0xa8,0xcc,0x60,0x48,0xc0,0x1c,0x7c,0xbe,0x01,0xe2,0x88,0xcc,0x6c,0x3e,0x97,0x91,0xf3,0xd9,0xb2,0xb2,0x09,0x7e,0x35,0xb1,0x78,0xb4,0x03,0xf6},{0x08,0xc4,0x1a,0x3a,0xc3,0xe3,0x26,0xbd,0x8d,0xee,0x5d,0xf0,0xba,0xb6,0x65,0xff,0x77,0xc0,0x99,0xd1,0xca,0xdc,0xf5,0x4b,0x50,0x50,0x0a,0x9e,0x13,0x33,0x76,0x86,0x9b,0x39,0x79,0x78,0x73,0x5c,0x2f,0x69,0xa9,0x9e,0x0b,0xeb,0x11,0x1e,0x12,0xaa,0xc1,0x09,0x83,0x0f,0xca,0xcb,0x95,0x10,0xde,0x85,0xe3,0x75,0x62,0x4a,0xc2,0x4c},{0x68,0x78,0x6c,0xce,0x2f,0x72,0x80,0xfe,0x83,0x88,0x63,0x37,0xa7,0xa1,0x5a,0x0b,0x84,0x8a,0xda,0x28,0x84,0xf1,0x6a,0x63,0x24,0x1c,0x72,0xda,0x84,0xee,0x1d,0xe0,0x77,0xf0,0xf6,0xce,0x7e,0x79,0x0a,0x55,0x03,0x01,0x13,0x0f,0xf7,0x6b,0x45,0xe7,0xcb,0xfd,0xb0,0x37,0x93,0x4b,0x40,0x69,0xe0,0x77,0x67,0x72,0x65,0xee,0x35,0x08,0x00,0xc0,0x07,0x10,0xd8,0x6e,0x55,0x83,0x5a,0xbc,0xfa,0x67,0x80,0x8f,0xfa,0x21,0x3e,0x56,0x53,0x5b,0xbc,0x9d,0xff,0x16,0xd9,0x57,0xcf,0x2b,0x78,0x06,0x5a,0x89},{0xdf,0x32,0x1a,0x01,0x84,0xe5,0xb8,0x2c,0x70,0x6c,0xeb,0xd1,0xf0,0xb4,0x9b,0x32,0xc8,0xd0,0x81,0xc4,0xea,0xb2,0x7c,0x32,0x1a,0x02,0x61,0xf2,0xd9,0x4d,0xe5,0x85,0xad,0xfc,0xc6,0x70,0xee,0x85,0x77,0x07,0x9b,0x5d,0x5f,0x88,0xef,0xb6,0xd8,0xdf,0x2b,0xa2,0x4d,0x90,0x11,0x2d,0x38,0x3f,0xa8,0x84,0xf0,0x76,0xdd,0x31,0xd0,0x09,0x00,0xc0,0x07,0x10,0xd8,0x6e,0x55,0x83,0x5a,0xbc,0xfa,0x67,0x80,0x8f,0xfa,0x21,0x3e,0x56,0x53,0x5b,0xbc,0x9d,0xff,0x16,0xd9,0x57,0xcf,0x2b,0x78,0x06,0x5a,0x89}}, - {{0x25,0x87,0x1e,0x6f,0xe8,0xd0,0xde,0x1d,0xd5,0xf2,0xd3,0x5b,0xff,0x9e,0x67,0x99,0x60,0xb4,0x0e,0xb7,0x98,0x1b,0x2a,0x3a,0x9c,0xec,0xc1,0xe1,0x2e,0x2b,0xc0,0x3e,0x3c,0xfb,0x64,0x91,0x72,0xc6,0x7e,0x57,0x47,0x00,0x97,0xbf,0x8e,0x0e,0xbf,0xad,0xd9,0x28,0x86,0x7c,0xfd,0x41,0x91,0xae,0x2d,0xee,0xc0,0xb2,0x32,0x7d,0x99,0x7d},{0x63,0xc1,0xf9,0x61,0x9c,0x9e,0x1a,0xd7,0xca,0xa3,0x71,0xd6,0x34,0x3d,0xa7,0x08,0x36,0x0c,0xec,0x37,0x35,0x94,0x1a,0x45,0xa9,0xfa,0xf2,0xb5,0x25,0x92,0xbf,0xd1,0x1e,0xca,0xdd,0x5a,0x23,0xad,0x9e,0x45,0xc3,0x66,0xcb,0x8f,0xda,0xa3,0xd1,0xe6,0x27,0x38,0x11,0x54,0x67,0x31,0x03,0x64,0x35,0xe0,0x68,0x0b,0x93,0xee,0x81,0x17},{0x8b,0x01,0xe9,0x99,0x54,0x54,0x73,0x15,0x0b,0xac,0x38,0x7b,0xe9,0xe3,0x17,0x4f,0x02,0x3e,0xe3,0x8e,0xda,0x41,0xa0,0x9d,0x10,0xe0,0xda,0x11,0xfe,0xec,0x2f,0x42,0xe7,0xc8,0xb3,0xde,0x2f,0x7b,0xfd,0xdf,0x7c,0x34,0x3b,0x5e,0xac,0x22,0x8c,0x99,0x3d,0xa1,0xa9,0xd9,0x81,0xb6,0x51,0xc8,0xaf,0x3e,0x75,0xed,0x45,0xcf,0xf7,0xb9},{0xaf,0xe9,0x9c,0x16,0x4a,0x8f,0x3b,0x0f,0xef,0x71,0x2f,0xaa,0x8d,0x7d,0xce,0xed,0xea,0x31,0x93,0xaf,0x2c,0x75,0xc6,0xfa,0xda,0x3e,0xa6,0xea,0x2a,0x3e,0x7b,0x72,0xb6,0xf8,0xd7,0x9a,0x88,0xcb,0x0b,0x81,0x97,0x24,0x29,0x3b,0x11,0x23,0x69,0xc2,0xff,0x98,0x39,0x25,0x99,0xae,0xe1,0x07,0x3e,0x97,0xde,0x10,0x21,0x23,0x7a,0x2d},{0xbe,0x2f,0xb9,0x4c,0x41,0x5a,0x9a,0xf6,0xfb,0xf8,0x26,0x9d,0x81,0x7f,0x39,0x91,0xaf,0x5b,0xf1,0xd7,0x93,0x0a,0xdf,0x18,0x19,0x4a,0x80,0x74,0x14,0x98,0x2b,0xf2,0x3b,0x25,0xc5,0xe8,0xfc,0x07,0x3f,0x5d,0xa1,0x39,0x27,0x4e,0x1c,0xd2,0x7a,0xfe,0x3e,0x7b,0x03,0x35,0x15,0x9e,0x35,0x2b,0xd0,0xbe,0x67,0x48,0x42,0xdd,0xa4,0xdd},{0xbd,0xcd,0xd7,0xbf,0xb1,0x0a,0xdb,0x9f,0x85,0x42,0xba,0xf4,0xc8,0xff,0xb0,0xe1,0x9a,0x18,0x6d,0x1a,0xe0,0x37,0xc1,0xa2,0xe1,0x1c,0x38,0x55,0x14,0xbf,0x64,0x67,0x84,0x47,0xb6,0x0a,0xf6,0x93,0xf1,0x10,0xab,0x09,0xf0,0x60,0x84,0xe2,0x4e,0x4b,0x5e,0xa2,0xd2,0xd1,0x19,0x22,0xd7,0xc4,0x85,0x13,0x23,0xa3,0x6a,0xb6,0x75,0x0f,0x43,0xe6,0xde,0x7b,0x67,0x2a,0x73,0x77,0x9e,0xb4,0x94,0x6c,0xc3,0x9a,0x67,0x51,0xcf,0xe9,0x47,0x46,0x0e,0x3a,0x12,0x7d,0x7c,0x66,0x73,0x6c,0xd5,0x4a,0x21,0x4d},{0x89,0x7e,0xd0,0xbf,0x2e,0x9f,0x0c,0xff,0x6e,0x56,0x25,0x9b,0x79,0x99,0x52,0x27,0xc2,0x3a,0xaa,0xf0,0x47,0x6d,0xed,0x05,0xa1,0xeb,0x9c,0x92,0x28,0x7f,0x1b,0xc8,0x1c,0x57,0x76,0xab,0x05,0xe3,0xd3,0xb7,0xa3,0xf5,0xac,0xa8,0x21,0x33,0x7c,0xb7,0xe7,0xc2,0xd0,0x25,0x6f,0xdf,0x34,0xd1,0xb0,0x34,0x41,0x46,0x30,0x9c,0x76,0x07,0x43,0xe6,0xde,0x7b,0x67,0x2a,0x73,0x77,0x9e,0xb4,0x94,0x6c,0xc3,0x9a,0x67,0x51,0xcf,0xe9,0x47,0x46,0x0e,0x3a,0x12,0x7d,0x7c,0x66,0x73,0x6c,0xd5,0x4a,0x21,0x4d}} + { { 0xa1, 0xfc, 0x7a, 0xb4, 0x6d, 0xdf, 0x7d, 0xcf, 0xe7, 0xec, 0x75, 0xe5, 0xfa, 0xdd, 0x11, 0xcb, 0xcc, 0x37, 0xf8, 0x84, 0x5d, 0x1c, 0x92, 0x4e, 0x09, 0x89, 0x65, 0xfc, 0xd8, 0xe9, 0x5a, 0x30, + 0xda, 0xe4, 0x86, 0xa3, 0x35, 0xb4, 0x19, 0x0c, 0xbc, 0x7b, 0xcb, 0x3e, 0xb9, 0x4c, 0xbd, 0x16, 0xe8, 0x3d, 0x13, 0x2b, 0xc9, 0xc3, 0x39, 0xea, 0xf1, 0x42, 0xe7, 0x6f, 0x69, 0x78, 0x9a, 0xb7 }, + { 0xe5, 0xf3, 0x7b, 0xd4, 0x0e, 0xc9, 0xdc, 0x77, 0x50, 0x86, 0xdc, 0xf4, 0x2e, 0xbc, 0xdb, 0x27, 0xf0, 0x73, 0xd4, 0x58, 0x73, 0xc4, 0x4b, 0x71, 0x8b, 0x3c, 0xc5, 0x4f, 0xa8, 0x7c, 0xa4, 0x84, + 0xd9, 0x96, 0x23, 0x73, 0xb4, 0x03, 0x16, 0xbf, 0x1e, 0xa1, 0x2d, 0xd8, 0xc4, 0x8a, 0xe7, 0x82, 0x10, 0xda, 0xc9, 0xe5, 0x45, 0x9b, 0x01, 0xdc, 0x73, 0xa6, 0xc9, 0x17, 0xa8, 0x15, 0x31, 0x6d }, + { 0x3e, 0x49, 0xa4, 0x0e, 0x3a, 0xaf, 0xa3, 0x07, 0x3d, 0xf7, 0x2a, 0xec, 0x43, 0xb1, 0xd4, 0x09, 0x1a, 0xcb, 0x8e, 0x92, 0xf9, 0x65, 0x95, 0x04, 0x6d, 0x2d, 0x9b, 0x34, 0xa3, 0xbf, 0x51, 0x00, + 0xe2, 0xee, 0x23, 0xf5, 0x28, 0x0a, 0xa9, 0xb1, 0x57, 0x0b, 0x96, 0x56, 0x62, 0xba, 0x12, 0x94, 0xaf, 0xc6, 0x5f, 0xb5, 0x61, 0x43, 0x0f, 0xde, 0x0b, 0xab, 0xfa, 0x4f, 0xfe, 0xc5, 0xe7, 0x18 }, + { 0x00, 0x4d, 0x41, 0x8d, 0xe4, 0x69, 0x23, 0xae, 0x98, 0xc4, 0x3e, 0x77, 0x0f, 0x1d, 0x94, 0x5d, 0x29, 0x3e, 0x94, 0x5a, 0x38, 0x39, 0x20, 0x0f, 0xd3, 0x6f, 0x76, 0xa2, 0x29, 0x02, 0x03, 0xcb, + 0x0b, 0x7f, 0x4f, 0x1a, 0x29, 0x51, 0x13, 0x33, 0x7c, 0x99, 0xb3, 0x81, 0x82, 0x39, 0x44, 0x05, 0x97, 0xfb, 0x0d, 0xf2, 0x93, 0xa2, 0x40, 0x94, 0xf4, 0xff, 0x5d, 0x09, 0x61, 0xe4, 0x5f, 0x76 }, + { 0xab, 0xce, 0xd2, 0x24, 0xe8, 0x93, 0xb0, 0xe7, 0x72, 0x14, 0xdc, 0xbb, 0x7d, 0x0f, 0xd8, 0x94, 0x16, 0x9e, 0xb5, 0x7f, 0xd7, 0x19, 0x5f, 0x3e, 0x2d, 0x45, 0xd5, 0xf7, 0x90, 0x0b, 0x3e, 0x05, + 0x18, 0x2e, 0x2b, 0xf4, 0xfa, 0xd4, 0xec, 0x62, 0x4a, 0x4f, 0x48, 0x50, 0xaf, 0x1c, 0xe8, 0x9f, 0x1a, 0xe1, 0x3d, 0x70, 0x49, 0x00, 0xa7, 0xe3, 0x5b, 0x1e, 0xa1, 0x9b, 0x68, 0x1e, 0xa1, 0x73 }, + { 0xed, 0xb6, 0xd0, 0xf0, 0x06, 0x6e, 0x33, 0x9c, 0x86, 0xfb, 0xe8, 0xc3, 0x6c, 0x8d, 0xde, 0xdd, 0xa6, 0xa0, 0x2d, 0xb9, 0x07, 0x29, 0xa3, 0x13, 0xbb, 0xa4, 0xba, 0xec, 0x48, 0xc8, 0xf4, 0x56, + 0x82, 0x79, 0xe2, 0xb1, 0xd3, 0x3d, 0x83, 0x9f, 0x10, 0xe8, 0x52, 0xe6, 0x8b, 0x1c, 0x33, 0x9e, 0x2b, 0xd2, 0xdb, 0x62, 0x1c, 0x56, 0xfd, 0x50, 0x40, 0x77, 0x81, 0xab, 0x21, 0x67, 0x3e, 0x09, + 0x4f, 0xf2, 0x51, 0xac, 0x7d, 0xe7, 0xd1, 0x5d, 0x4b, 0xe2, 0x08, 0xc6, 0x3f, 0x6a, 0x4d, 0xc8, 0x5d, 0x74, 0xf6, 0x3b, 0xec, 0x8e, 0xc6, 0x0c, 0x32, 0x27, 0x2f, 0x9c, 0x09, 0x48, 0x59, 0x10 }, + { 0x23, 0x0f, 0xa3, 0xe2, 0x69, 0xce, 0xb9, 0xb9, 0xd1, 0x1c, 0x4e, 0xab, 0x63, 0xc9, 0x2e, 0x1e, 0x7e, 0xa2, 0xa2, 0xa0, 0x49, 0x2e, 0x78, 0xe4, 0x8a, 0x02, 0x3b, 0xa7, 0xab, 0x1f, 0xd4, 0xce, + 0x05, 0xe2, 0x80, 0x09, 0x09, 0x3c, 0x61, 0xc7, 0x10, 0x3a, 0x9c, 0xf4, 0x95, 0xac, 0x89, 0x6f, 0x23, 0xb3, 0x09, 0xe2, 0x24, 0x3f, 0xf6, 0x96, 0x02, 0x36, 0x41, 0x16, 0x32, 0xe1, 0x66, 0x05, + 0x4f, 0xf2, 0x51, 0xac, 0x7d, 0xe7, 0xd1, 0x5d, 0x4b, 0xe2, 0x08, 0xc6, 0x3f, 0x6a, 0x4d, 0xc8, 0x5d, 0x74, 0xf6, 0x3b, 0xec, 0x8e, 0xc6, 0x0c, 0x32, 0x27, 0x2f, 0x9c, 0x09, 0x48, 0x59, 0x10 } }, + { { 0xfd, 0x81, 0x14, 0xf1, 0x67, 0x07, 0x44, 0xbb, 0x93, 0x84, 0xa2, 0xdc, 0x36, 0xdc, 0xcc, 0xb3, 0x9e, 0x82, 0xd4, 0x8b, 0x42, 0x56, 0xfb, 0xf2, 0x6e, 0x83, 0x3b, 0x16, 0x2c, 0x29, 0xfb, 0x39, + 0x29, 0x48, 0x85, 0xe3, 0xe3, 0xf7, 0xe7, 0x80, 0x49, 0xd3, 0x01, 0x30, 0x5a, 0x2c, 0x3f, 0x4c, 0xea, 0x13, 0xeb, 0xda, 0xf4, 0x56, 0x75, 0x8d, 0x50, 0x1e, 0x19, 0x2d, 0x29, 0x2b, 0xfb, 0xdb }, + { 0x85, 0x34, 0x4d, 0xf7, 0x39, 0xbf, 0x98, 0x79, 0x8c, 0x98, 0xeb, 0x8d, 0x61, 0x27, 0xec, 0x87, 0x56, 0xcd, 0xd0, 0xa6, 0x55, 0x77, 0xee, 0xf0, 0x20, 0xd0, 0x59, 0x39, 0x95, 0xab, 0x29, 0x82, + 0x8e, 0x61, 0xf8, 0xad, 0xed, 0xb6, 0x27, 0xc3, 0xd8, 0x16, 0xce, 0x67, 0x78, 0xe2, 0x04, 0x4b, 0x0c, 0x2d, 0x2f, 0xc3, 0x24, 0x72, 0xbc, 0x53, 0xbd, 0xfe, 0x39, 0x23, 0xd4, 0xaf, 0x27, 0x84 }, + { 0x11, 0xbe, 0x5f, 0x5a, 0x73, 0xe7, 0x42, 0xef, 0xff, 0x3c, 0x47, 0x6a, 0x0e, 0x6b, 0x9e, 0x96, 0x21, 0xa3, 0xdf, 0x49, 0xe9, 0x3f, 0x40, 0xfc, 0xab, 0xb3, 0x66, 0xd3, 0x3d, 0xfa, 0x02, 0x29, + 0xf3, 0x43, 0x45, 0x3c, 0x70, 0xa3, 0x5d, 0x39, 0xf7, 0xc0, 0x6a, 0xcd, 0xfa, 0x1d, 0xbe, 0x3b, 0x91, 0x41, 0xe4, 0xb0, 0x60, 0xc0, 0x22, 0xf7, 0x2c, 0x11, 0x2b, 0x1c, 0x5f, 0x24, 0xef, 0x53 }, + { 0xfd, 0x3f, 0x09, 0x06, 0xc9, 0x39, 0x8d, 0x48, 0xfa, 0x6b, 0xc9, 0x80, 0xbf, 0xf6, 0xd6, 0x76, 0xb3, 0x62, 0x70, 0x88, 0x4f, 0xde, 0xde, 0xb9, 0xb4, 0xf0, 0xce, 0xf3, 0x74, 0x0d, 0xea, 0x00, + 0x9e, 0x9c, 0x29, 0xe1, 0xa2, 0x1b, 0xbd, 0xb5, 0x83, 0xcc, 0x12, 0xd8, 0x48, 0x08, 0x5b, 0xe5, 0xd6, 0xf9, 0x11, 0x5c, 0xe0, 0xd9, 0xc3, 0x3c, 0x26, 0xbd, 0x69, 0x9f, 0x5c, 0x6f, 0x0c, 0x6f }, + { 0xca, 0xd4, 0x76, 0x32, 0x8b, 0xbe, 0x0c, 0x65, 0x75, 0x43, 0x73, 0xc2, 0xf2, 0xfd, 0x7f, 0xeb, 0xe4, 0x62, 0xc5, 0x0d, 0x0f, 0xf9, 0x01, 0xc8, 0xb9, 0xfa, 0xca, 0xb4, 0x12, 0x1c, 0xb4, 0xac, + 0x0e, 0x5f, 0x18, 0xfc, 0x0c, 0x7f, 0x2a, 0x55, 0xc5, 0xfd, 0x4d, 0x83, 0xb2, 0x02, 0x31, 0x6a, 0x3f, 0x14, 0xee, 0x9d, 0x11, 0xa8, 0x06, 0xad, 0xeb, 0x93, 0x19, 0x79, 0xb1, 0xf2, 0x78, 0x05 }, + { 0x85, 0xe6, 0xe2, 0xf2, 0x96, 0xe7, 0xa2, 0x8b, 0x7e, 0x36, 0xbd, 0x7b, 0xf4, 0x28, 0x6a, 0xd7, 0xbc, 0x2a, 0x6a, 0x59, 0xfd, 0xc0, 0xc8, 0x3d, 0x50, 0x0f, 0x0c, 0x2b, 0x12, 0x3a, 0x75, 0xc7, + 0x56, 0xbb, 0x7f, 0x7d, 0x4e, 0xd4, 0x03, 0xb8, 0x7b, 0xde, 0xde, 0x99, 0x65, 0x9e, 0xc4, 0xa6, 0x6e, 0xfe, 0x00, 0x88, 0xeb, 0x9d, 0xa4, 0xa9, 0x9d, 0x37, 0xc9, 0x4a, 0xcf, 0x69, 0xc4, 0x01, + 0xba, 0xa8, 0xce, 0xeb, 0x72, 0xcb, 0x64, 0x8b, 0x9f, 0xc1, 0x1f, 0x9a, 0x9e, 0x99, 0xcc, 0x39, 0xec, 0xd9, 0xbb, 0xd9, 0xce, 0xc2, 0x74, 0x6f, 0xd0, 0x2a, 0xb9, 0xc6, 0xe3, 0xf5, 0xe7, 0xf4 }, + { 0xb1, 0x39, 0x50, 0xb1, 0x1a, 0x08, 0x42, 0x2b, 0xdd, 0x6d, 0x20, 0x9f, 0x0f, 0x37, 0xba, 0x69, 0x97, 0x21, 0x30, 0x7a, 0x71, 0x2f, 0xce, 0x98, 0x09, 0x04, 0xa2, 0x98, 0x6a, 0xed, 0x02, 0x1d, + 0x5d, 0x30, 0x8f, 0x03, 0x47, 0x6b, 0x89, 0xfd, 0xf7, 0x1a, 0xca, 0x46, 0x6f, 0x51, 0x69, 0x9a, 0x2b, 0x18, 0x77, 0xe4, 0xad, 0x0d, 0x7a, 0x66, 0xd2, 0x2c, 0x28, 0xa0, 0xd3, 0x0a, 0x99, 0x0d, + 0xba, 0xa8, 0xce, 0xeb, 0x72, 0xcb, 0x64, 0x8b, 0x9f, 0xc1, 0x1f, 0x9a, 0x9e, 0x99, 0xcc, 0x39, 0xec, 0xd9, 0xbb, 0xd9, 0xce, 0xc2, 0x74, 0x6f, 0xd0, 0x2a, 0xb9, 0xc6, 0xe3, 0xf5, 0xe7, 0xf4 } }, + { { 0x02, 0x3a, 0x7e, 0x0c, 0x6d, 0x96, 0x3c, 0x5d, 0x44, 0x56, 0x5d, 0xc1, 0x49, 0x94, 0x35, 0x12, 0x9d, 0xff, 0x8a, 0x5d, 0x91, 0x74, 0xa8, 0x15, 0xee, 0x5d, 0x1e, 0x72, 0xbe, 0x86, 0x15, 0x68, + 0xe7, 0x36, 0xa2, 0x4a, 0xb8, 0xa2, 0xa4, 0x4c, 0xd8, 0x95, 0xe3, 0xc7, 0xbb, 0x32, 0x21, 0x90, 0x64, 0x52, 0x32, 0xeb, 0x26, 0xd3, 0x4f, 0xf0, 0x8e, 0x27, 0x40, 0xea, 0xed, 0xdb, 0xf5, 0xc4 }, + { 0x76, 0x99, 0x64, 0x70, 0xf4, 0x50, 0xc8, 0xcc, 0x4a, 0x5a, 0xa5, 0x0f, 0xeb, 0x2d, 0xc7, 0x0e, 0x73, 0xd0, 0x65, 0x7d, 0xc3, 0xce, 0x73, 0x03, 0x20, 0x2f, 0xad, 0x65, 0xfd, 0x12, 0xe4, 0x7f, + 0xfd, 0x45, 0x3a, 0x6e, 0xc5, 0x9a, 0x06, 0x67, 0x0e, 0xa6, 0x7b, 0x21, 0x49, 0x2d, 0x01, 0x1b, 0x8e, 0x03, 0x6e, 0x10, 0x08, 0x0c, 0x68, 0xd9, 0x60, 0x47, 0xa4, 0xe2, 0x52, 0xfd, 0x3c, 0xf4 }, + { 0xa3, 0xe2, 0x5f, 0x16, 0x39, 0x78, 0x96, 0xf7, 0x47, 0x6f, 0x93, 0x5d, 0x27, 0x7b, 0x58, 0xe0, 0xc5, 0xdb, 0x71, 0x7d, 0xa9, 0x6f, 0xf8, 0x8b, 0x69, 0xdd, 0x50, 0xea, 0x91, 0x0d, 0x66, 0x77, + 0xaf, 0x8f, 0xd5, 0x9f, 0x8a, 0x26, 0x69, 0x4c, 0x64, 0x37, 0x62, 0x81, 0x6f, 0x05, 0x9a, 0x08, 0x0d, 0xe1, 0x69, 0x24, 0x77, 0x3f, 0x50, 0xb2, 0x49, 0x4d, 0x93, 0xef, 0x2e, 0x87, 0xff, 0xde }, + { 0xb3, 0x32, 0xe2, 0x67, 0x79, 0x32, 0x5f, 0x64, 0x47, 0x49, 0x1c, 0xd3, 0x8f, 0x95, 0x44, 0xfd, 0x4c, 0x7e, 0xbf, 0x6b, 0xb7, 0xaf, 0x2c, 0xdd, 0x8f, 0xa5, 0xd8, 0x2f, 0xbf, 0xa0, 0x8a, 0x6b, + 0x58, 0x25, 0xc9, 0x12, 0x23, 0x6f, 0xe6, 0x05, 0xa8, 0xd0, 0x68, 0x6e, 0x0c, 0xee, 0x70, 0xe4, 0xa3, 0x86, 0x51, 0x04, 0x6d, 0xca, 0xd5, 0xed, 0xcf, 0x74, 0x1d, 0x60, 0x9e, 0x86, 0x2d, 0x05 }, + { 0x91, 0xf4, 0x5f, 0x4a, 0xcb, 0xd8, 0xfd, 0x5f, 0xb9, 0x3d, 0x04, 0xb8, 0xec, 0x35, 0x85, 0x4f, 0x58, 0x20, 0xd1, 0x1f, 0x47, 0xc4, 0xf4, 0xcb, 0x21, 0x4e, 0x9a, 0xf1, 0x6e, 0xbf, 0xe3, 0xd3, + 0x62, 0xe3, 0x82, 0xf6, 0xba, 0xa8, 0xdf, 0x92, 0xe2, 0x3c, 0xe5, 0xf0, 0x16, 0x8a, 0xeb, 0xa4, 0xbb, 0xc7, 0x81, 0xaf, 0x15, 0x19, 0x87, 0x5f, 0xb7, 0xe0, 0x4c, 0x12, 0xff, 0x2c, 0xa9, 0xc8 }, + { 0xaf, 0x85, 0xe0, 0x36, 0x43, 0xdf, 0x41, 0x17, 0xda, 0xde, 0x5e, 0xb6, 0x33, 0xd0, 0xce, 0x62, 0x70, 0x5f, 0x85, 0x24, 0x6c, 0x3e, 0x1b, 0xe1, 0x52, 0xc1, 0x9b, 0x1c, 0xcd, 0x61, 0x80, 0x9c, + 0xa0, 0xe8, 0x18, 0xee, 0x40, 0x91, 0x93, 0x82, 0xdb, 0x33, 0x44, 0xff, 0xd4, 0xf6, 0x6f, 0x5d, 0xf0, 0x0e, 0x92, 0x92, 0x81, 0x55, 0x46, 0x06, 0xac, 0x58, 0x81, 0x3b, 0x04, 0xc7, 0xf7, 0x0d, + 0xd2, 0x0c, 0x08, 0x6d, 0x46, 0xdb, 0x43, 0x28, 0x31, 0xd8, 0xcd, 0x87, 0x50, 0xbb, 0xd3, 0x07, 0xf5, 0x72, 0x0b, 0x15, 0x7c, 0x16, 0xab, 0x03, 0xd9, 0x4b, 0x07, 0x38, 0x97, 0xe8, 0xd6, 0xb5 }, + { 0x93, 0xff, 0x6d, 0xc3, 0x62, 0xf7, 0xcc, 0x20, 0x95, 0xc2, 0x2f, 0x7d, 0x1d, 0x9b, 0xd1, 0x63, 0xfc, 0x61, 0x47, 0xb3, 0x22, 0x0f, 0xca, 0xb0, 0x16, 0xcf, 0x29, 0x53, 0x46, 0x97, 0xb1, 0x36, + 0x46, 0xac, 0x48, 0x13, 0x92, 0xe4, 0x46, 0x68, 0xcf, 0x09, 0x4e, 0xfa, 0x59, 0x45, 0x24, 0x08, 0xdb, 0xb4, 0x6f, 0x20, 0x55, 0x12, 0xd9, 0x75, 0x9d, 0x8e, 0x0b, 0xf8, 0x63, 0xe0, 0xf9, 0x01, + 0xd2, 0x0c, 0x08, 0x6d, 0x46, 0xdb, 0x43, 0x28, 0x31, 0xd8, 0xcd, 0x87, 0x50, 0xbb, 0xd3, 0x07, 0xf5, 0x72, 0x0b, 0x15, 0x7c, 0x16, 0xab, 0x03, 0xd9, 0x4b, 0x07, 0x38, 0x97, 0xe8, 0xd6, 0xb5 } }, + { { 0x14, 0x35, 0xa6, 0x7d, 0xc1, 0xb5, 0x71, 0xca, 0x42, 0x50, 0x90, 0xa7, 0x72, 0x85, 0xbe, 0x78, 0x7a, 0x5f, 0x83, 0x1e, 0xbe, 0xef, 0x6a, 0xbe, 0x48, 0xc5, 0x68, 0x14, 0x0c, 0xf7, 0x44, 0x5c, + 0x2e, 0xfd, 0x1b, 0xcc, 0xee, 0x09, 0x23, 0x82, 0x31, 0xad, 0xaf, 0x4b, 0x73, 0x9c, 0xf2, 0x88, 0x3c, 0xf3, 0xb5, 0x43, 0x8b, 0x53, 0xf9, 0xac, 0x17, 0x86, 0x1c, 0xc2, 0x53, 0x43, 0xec, 0x03 }, + { 0x7b, 0x36, 0x6c, 0xcc, 0xb5, 0xb2, 0x23, 0x3d, 0x7c, 0xe5, 0xe7, 0xcf, 0x06, 0xe2, 0x32, 0x0b, 0xc5, 0x3b, 0x7f, 0x86, 0x40, 0xfc, 0xaf, 0xba, 0x94, 0xe0, 0x88, 0x58, 0x5b, 0xac, 0xe8, 0xc3, + 0xe8, 0xc3, 0xdf, 0xc4, 0x45, 0x29, 0xe8, 0xf0, 0x1c, 0x10, 0x0d, 0x50, 0x81, 0x29, 0x30, 0xa8, 0x27, 0xb5, 0x3e, 0xb8, 0x25, 0xf1, 0x17, 0x30, 0xc6, 0x05, 0xe3, 0x3e, 0x45, 0x38, 0xa8, 0x3c }, + { 0xce, 0xd9, 0x45, 0x28, 0xb0, 0xce, 0xa5, 0x47, 0xa8, 0x29, 0x32, 0x76, 0x99, 0x73, 0x8d, 0x74, 0xf9, 0xed, 0x0a, 0xd0, 0xf1, 0xd8, 0x7e, 0x44, 0x63, 0x9e, 0x9a, 0xcf, 0x7c, 0x35, 0x8a, 0x29, + 0xbb, 0x71, 0x66, 0x8d, 0xa7, 0xfc, 0x05, 0x3d, 0xd4, 0x4b, 0x65, 0x20, 0xf5, 0xa4, 0x64, 0xd8, 0x9d, 0x16, 0x80, 0x9c, 0xb2, 0x3c, 0x3e, 0xd4, 0x9d, 0x09, 0x88, 0x8e, 0xbb, 0x58, 0xf8, 0x77 }, + { 0xe1, 0x29, 0xb3, 0x16, 0xe6, 0xa0, 0xdb, 0x64, 0x08, 0x36, 0xdc, 0x33, 0xad, 0x8b, 0x30, 0x26, 0x17, 0x56, 0xd7, 0x34, 0x17, 0xd1, 0xdd, 0x23, 0x38, 0x58, 0x25, 0x01, 0x42, 0x5a, 0x9d, 0x18, + 0x3e, 0xac, 0x31, 0xfa, 0x43, 0x28, 0xc4, 0x65, 0xfb, 0x30, 0x2f, 0x8c, 0x16, 0x52, 0x32, 0x1b, 0x19, 0xb7, 0x31, 0xf6, 0x67, 0xa7, 0xd8, 0xed, 0x9a, 0xa3, 0x95, 0x01, 0xd7, 0xb9, 0xe7, 0xcc }, + { 0x81, 0x2d, 0x11, 0xa9, 0x11, 0xf1, 0x22, 0xe2, 0x67, 0x70, 0xc4, 0xba, 0x34, 0xa1, 0x75, 0x8c, 0xf6, 0x0c, 0x63, 0xe7, 0x01, 0x3c, 0x64, 0x6c, 0xe8, 0xd0, 0xf8, 0x8e, 0x88, 0xdf, 0x5c, 0x61, + 0x68, 0x5d, 0x1f, 0xeb, 0x83, 0x1f, 0x40, 0xb8, 0xa8, 0x56, 0x57, 0x26, 0x81, 0x2c, 0xa3, 0x0e, 0x48, 0x4c, 0x45, 0x4d, 0x0d, 0x3d, 0x6e, 0x99, 0x52, 0xbd, 0x0b, 0xd8, 0x05, 0xc5, 0xf9, 0x61 }, + { 0x92, 0x45, 0xbe, 0xe6, 0xb4, 0x7a, 0xfa, 0x28, 0xd4, 0x5b, 0x6b, 0x17, 0xc6, 0x13, 0x61, 0x5d, 0x5f, 0xd7, 0x90, 0xbb, 0x89, 0x35, 0x7a, 0x02, 0x50, 0x57, 0x56, 0x5f, 0x19, 0xb5, 0xb6, 0xc5, + 0x77, 0x1e, 0x1b, 0xc0, 0xd7, 0x7a, 0x29, 0xbd, 0xe7, 0x24, 0x01, 0x2d, 0x37, 0xc0, 0x38, 0x6f, 0xc8, 0x35, 0xa1, 0x1b, 0xe0, 0xea, 0x16, 0xad, 0xbc, 0xdc, 0xd4, 0x8d, 0x4e, 0x71, 0xdb, 0x05, + 0x9e, 0xb5, 0x53, 0x6b, 0x5c, 0xf1, 0x7d, 0x15, 0x8b, 0xd7, 0xc7, 0x8b, 0x89, 0x9d, 0xfd, 0x28, 0x7c, 0xa1, 0x31, 0xe2, 0xf0, 0x2c, 0x3a, 0x8d, 0x0e, 0x23, 0x85, 0x4e, 0xf0, 0xd1, 0xc0, 0x83 }, + { 0x7b, 0x88, 0xeb, 0x45, 0x1c, 0x7f, 0xfd, 0xbe, 0xba, 0xac, 0x53, 0x28, 0x59, 0xe8, 0xad, 0x28, 0xf1, 0x97, 0x2d, 0x6c, 0x31, 0xa6, 0xae, 0x47, 0x10, 0x69, 0x68, 0x55, 0xa6, 0x9c, 0x03, 0x62, + 0xb7, 0x2f, 0x31, 0x46, 0x2a, 0x2b, 0x98, 0xdd, 0xe9, 0xf9, 0xfe, 0x77, 0x71, 0x41, 0x54, 0xf8, 0x59, 0x02, 0x7a, 0xe3, 0x45, 0x67, 0xb6, 0xf7, 0x94, 0x31, 0x3e, 0x62, 0x62, 0x2a, 0xf9, 0x0a, + 0x9e, 0xb5, 0x53, 0x6b, 0x5c, 0xf1, 0x7d, 0x15, 0x8b, 0xd7, 0xc7, 0x8b, 0x89, 0x9d, 0xfd, 0x28, 0x7c, 0xa1, 0x31, 0xe2, 0xf0, 0x2c, 0x3a, 0x8d, 0x0e, 0x23, 0x85, 0x4e, 0xf0, 0xd1, 0xc0, 0x83 } }, + { { 0x27, 0x4d, 0x84, 0x08, 0x95, 0x84, 0xc8, 0xeb, 0x1c, 0x9a, 0x0f, 0xca, 0x09, 0x6f, 0x48, 0x8b, 0x2b, 0x06, 0xa0, 0xae, 0xf2, 0xe3, 0x8a, 0xfe, 0xd7, 0x52, 0x4b, 0xf2, 0xc6, 0x7c, 0xc1, 0x55, + 0x87, 0x2e, 0x5a, 0xb4, 0xc2, 0x43, 0x0a, 0x0d, 0xd0, 0x00, 0xa8, 0xe1, 0x46, 0x68, 0x79, 0xd8, 0x8c, 0x01, 0x36, 0xb7, 0x5a, 0x61, 0x04, 0xe9, 0x7e, 0xbb, 0xc9, 0xee, 0xaa, 0x12, 0x13, 0xda }, + { 0x78, 0x66, 0xd0, 0xa2, 0x50, 0x82, 0x8d, 0xb0, 0xa0, 0x20, 0xac, 0xa4, 0xb6, 0xa0, 0x31, 0xf7, 0x7d, 0x93, 0x37, 0x67, 0xbb, 0x60, 0xa2, 0x1e, 0x36, 0xce, 0x3d, 0x48, 0x1d, 0x79, 0x99, 0xa5, + 0x19, 0xd8, 0x89, 0x1b, 0xcb, 0x14, 0x87, 0xb7, 0x62, 0xfd, 0xd2, 0xef, 0xbb, 0x13, 0x41, 0x4d, 0xf1, 0x77, 0x5c, 0x7f, 0x6c, 0x3b, 0x94, 0x7d, 0xb4, 0xba, 0x87, 0x3e, 0xc8, 0xe1, 0x3c, 0x0a }, + { 0xd9, 0x9e, 0x14, 0x89, 0xd6, 0xf8, 0x49, 0xa2, 0xe2, 0x19, 0xfe, 0x94, 0xaa, 0xf7, 0x35, 0xf9, 0x4a, 0xf8, 0xf3, 0x18, 0x68, 0x96, 0x47, 0xc6, 0x23, 0x7c, 0xb0, 0x53, 0xcb, 0xd8, 0x90, 0x31, + 0xb7, 0x50, 0x0e, 0x06, 0xc3, 0x84, 0x75, 0xf1, 0xac, 0x16, 0x4d, 0xc1, 0xbe, 0xf1, 0x80, 0x33, 0x47, 0x56, 0x6f, 0x33, 0x94, 0x5c, 0x81, 0x03, 0x4c, 0x2f, 0x6d, 0xac, 0x73, 0xba, 0x91, 0x3c }, + { 0x2f, 0xa9, 0xb6, 0xe8, 0x73, 0xe2, 0xef, 0x6d, 0x6d, 0xd7, 0x2e, 0xa0, 0x51, 0x61, 0x24, 0x81, 0x8c, 0xa8, 0x47, 0x40, 0xe1, 0xc7, 0x75, 0x79, 0xc8, 0xec, 0xb2, 0x23, 0x41, 0xad, 0x61, 0x3b, + 0xea, 0x8a, 0xdf, 0x63, 0xed, 0xe1, 0x8e, 0x50, 0x70, 0x6e, 0x86, 0xed, 0xb0, 0xba, 0x27, 0x48, 0x8e, 0xb9, 0x63, 0x39, 0x78, 0x58, 0x4f, 0x1e, 0xbc, 0x45, 0xf3, 0xf2, 0x3a, 0x73, 0x9b, 0x8c }, + { 0xad, 0x42, 0xc5, 0x84, 0xca, 0xe1, 0xe1, 0x23, 0x2a, 0x73, 0x15, 0x3c, 0x9a, 0xfe, 0x85, 0x8d, 0xa3, 0x2c, 0xcf, 0x46, 0x8d, 0x7f, 0x1c, 0x61, 0xd7, 0x0e, 0xb1, 0xa6, 0xb4, 0xae, 0xab, 0x63, + 0xc4, 0x0e, 0xf2, 0xa0, 0x5d, 0xa6, 0xf3, 0x5d, 0x35, 0x41, 0xea, 0x03, 0x91, 0xb1, 0x3a, 0x07, 0xe6, 0xed, 0x6c, 0x8c, 0xcb, 0x75, 0x27, 0xf1, 0x26, 0x58, 0xf0, 0x62, 0x57, 0xe4, 0x33, 0x00 }, + { 0x1f, 0xed, 0x53, 0xc6, 0xef, 0x38, 0x26, 0xa4, 0x18, 0x88, 0x8f, 0x5c, 0x49, 0x1c, 0x15, 0x7d, 0x77, 0x90, 0x06, 0x39, 0xe0, 0x7c, 0x25, 0xed, 0x79, 0x05, 0x66, 0xe0, 0x5e, 0x94, 0xe3, 0x46, + 0x6f, 0x96, 0xd8, 0xc1, 0x11, 0xa4, 0x11, 0x6f, 0x78, 0x42, 0x8e, 0x89, 0xc7, 0xc3, 0xed, 0xd2, 0x9e, 0x68, 0x47, 0x79, 0x89, 0x23, 0x70, 0x14, 0x21, 0x60, 0x2d, 0xfe, 0x37, 0x4b, 0xc8, 0x0a, + 0x16, 0x73, 0x7c, 0xc4, 0x55, 0x3f, 0x25, 0x04, 0x08, 0x75, 0x74, 0x68, 0xbc, 0xe4, 0x3a, 0xae, 0x4c, 0x0e, 0xd2, 0x85, 0xa1, 0xbc, 0x81, 0xc0, 0xc9, 0xfe, 0x9a, 0x44, 0x7b, 0x83, 0xdf, 0xc7 }, + { 0x27, 0x77, 0x97, 0x84, 0x0f, 0x2d, 0x8d, 0x33, 0xb8, 0x4e, 0xdb, 0x8b, 0xea, 0x58, 0x52, 0x88, 0x95, 0x88, 0x55, 0x5f, 0xb8, 0xc4, 0xc9, 0xd6, 0x1f, 0x1e, 0xee, 0x60, 0xb5, 0xeb, 0x78, 0x72, + 0xb5, 0xe5, 0x22, 0x2b, 0x7f, 0x5e, 0xc7, 0x9b, 0x29, 0x55, 0x8e, 0x2a, 0xfc, 0x65, 0x55, 0x4a, 0x02, 0xad, 0x64, 0x06, 0xd4, 0x25, 0xe1, 0x96, 0x6f, 0xee, 0x96, 0xcd, 0x29, 0xc6, 0x64, 0x00, + 0x16, 0x73, 0x7c, 0xc4, 0x55, 0x3f, 0x25, 0x04, 0x08, 0x75, 0x74, 0x68, 0xbc, 0xe4, 0x3a, 0xae, 0x4c, 0x0e, 0xd2, 0x85, 0xa1, 0xbc, 0x81, 0xc0, 0xc9, 0xfe, 0x9a, 0x44, 0x7b, 0x83, 0xdf, 0xc7 } }, + { { 0x5e, 0xc5, 0x5b, 0x9c, 0xdb, 0x14, 0x05, 0x18, 0x6b, 0xe2, 0x1d, 0x16, 0x77, 0x22, 0x0e, 0xd2, 0xe4, 0x57, 0x82, 0x6e, 0x5b, 0xc5, 0x6a, 0xb9, 0x34, 0x20, 0xdb, 0x72, 0xe2, 0xe1, 0xeb, 0x1b, + 0x34, 0x00, 0x04, 0xbf, 0x83, 0xf6, 0x4f, 0x12, 0x45, 0x08, 0xf0, 0x95, 0x2a, 0xdc, 0x3a, 0x14, 0xb3, 0x29, 0x0b, 0x99, 0xcd, 0x73, 0x31, 0xbd, 0x04, 0xbb, 0x49, 0x1c, 0xde, 0xcf, 0x09, 0x9e }, + { 0x15, 0x80, 0x3e, 0x2a, 0xfb, 0xc0, 0x8d, 0x62, 0x19, 0x27, 0x83, 0x04, 0xcc, 0xf5, 0xd1, 0xbb, 0x40, 0x41, 0xbe, 0x93, 0x59, 0x6e, 0x27, 0x6d, 0x95, 0x24, 0x0a, 0x07, 0x27, 0x86, 0x10, 0x75, + 0xf7, 0x0a, 0x11, 0xfc, 0x53, 0xd0, 0x4c, 0x15, 0xf8, 0x6e, 0x22, 0x3f, 0xeb, 0x12, 0x97, 0x8a, 0x3d, 0x69, 0xd8, 0x96, 0xc9, 0x53, 0x10, 0x9c, 0x02, 0x95, 0xe4, 0xd3, 0x1a, 0xd5, 0x43, 0x82 }, + { 0x40, 0x09, 0x2c, 0x17, 0x7e, 0xba, 0xce, 0x1f, 0xfc, 0xc1, 0x8e, 0xc3, 0x1c, 0xa2, 0x34, 0x52, 0x78, 0x16, 0x23, 0x71, 0x82, 0x40, 0xf8, 0x6d, 0x67, 0x65, 0x67, 0x50, 0x53, 0xd9, 0xc8, 0x5e, + 0x7e, 0x8a, 0x98, 0xa3, 0xc6, 0x2a, 0x4d, 0x27, 0xf3, 0xb9, 0xbb, 0xae, 0x43, 0x29, 0x6e, 0x02, 0x1c, 0xe9, 0x01, 0xd6, 0xcd, 0xd8, 0x91, 0x44, 0x95, 0x2b, 0x9e, 0xa5, 0x4f, 0xd0, 0x00, 0xb9 }, + { 0x3a, 0xe8, 0x3d, 0xb3, 0x32, 0xdc, 0xc2, 0xc8, 0xe3, 0x36, 0x2f, 0xc9, 0x30, 0x3a, 0xc0, 0x76, 0x56, 0xd3, 0x0b, 0x06, 0xbe, 0x8f, 0xe7, 0xf1, 0x66, 0x61, 0x25, 0x42, 0x28, 0xdc, 0x08, 0x81, + 0x84, 0x3a, 0x57, 0x96, 0x27, 0xa6, 0xcf, 0xd6, 0x8f, 0x35, 0xa2, 0xc3, 0x76, 0x86, 0x4f, 0xcf, 0x5f, 0xa1, 0x85, 0x28, 0x4f, 0x4a, 0x3a, 0xbb, 0x5c, 0x25, 0x4b, 0xcc, 0x46, 0xfe, 0xf2, 0x04 }, + { 0x62, 0xc8, 0xa2, 0x0a, 0x59, 0xb8, 0x97, 0xd2, 0x68, 0x94, 0x00, 0x3b, 0x01, 0xac, 0x91, 0x6e, 0x97, 0x8e, 0x08, 0xe3, 0xfe, 0x9f, 0x9e, 0x9f, 0x4b, 0xcc, 0x5d, 0x1d, 0xb9, 0xbf, 0x07, 0x83, + 0xfe, 0x51, 0x2a, 0xdf, 0x79, 0x2e, 0x07, 0xc9, 0x98, 0x9b, 0xbe, 0xb6, 0xe4, 0x0a, 0x20, 0x44, 0x86, 0xea, 0xb1, 0x61, 0x58, 0x11, 0x32, 0x8e, 0x7b, 0xb9, 0x67, 0x2d, 0xf0, 0x78, 0xb2, 0x93 }, + { 0x1a, 0x65, 0xb3, 0x6f, 0xa2, 0x45, 0x29, 0x53, 0xd7, 0x23, 0x4d, 0xff, 0x8e, 0xe9, 0xb9, 0xef, 0x16, 0xa0, 0xdd, 0x48, 0xdf, 0x70, 0xd2, 0xe1, 0x56, 0xca, 0xd1, 0xd0, 0x4a, 0x9d, 0x63, 0x92, + 0x2b, 0xfd, 0x7b, 0x87, 0x39, 0x3c, 0x12, 0xc7, 0xe5, 0x91, 0x31, 0x95, 0x78, 0xc4, 0x58, 0x95, 0x89, 0x6e, 0x2c, 0x90, 0xb4, 0x0b, 0xb2, 0xfe, 0x52, 0xc0, 0x86, 0xc4, 0x2e, 0x56, 0x97, 0x0c, + 0x20, 0xf2, 0xbc, 0x6a, 0x9b, 0x89, 0xfb, 0xe9, 0x85, 0x95, 0xd6, 0x22, 0x5e, 0x4d, 0x6d, 0x83, 0x9d, 0xf4, 0xbe, 0x66, 0x05, 0x32, 0xb6, 0xe2, 0xf1, 0x96, 0x42, 0xa4, 0xc8, 0x8c, 0x1b, 0xec }, + { 0x43, 0x85, 0xff, 0xb9, 0xcf, 0x04, 0x83, 0x40, 0x70, 0x3a, 0x9c, 0x48, 0xb4, 0xc2, 0x99, 0x3b, 0xa0, 0x39, 0xf1, 0x39, 0x58, 0x7f, 0xd2, 0x49, 0x94, 0x3c, 0xc3, 0xe1, 0xb6, 0x56, 0x38, 0x55, + 0x6f, 0xb5, 0x1a, 0x90, 0xa2, 0x04, 0x2f, 0x19, 0xf8, 0xb1, 0x65, 0x5a, 0xad, 0xcd, 0x1c, 0x56, 0x42, 0x38, 0xc2, 0x52, 0x09, 0xd6, 0x41, 0x98, 0x5d, 0x5f, 0xa5, 0xe7, 0xc2, 0x55, 0xa1, 0x09, + 0x20, 0xf2, 0xbc, 0x6a, 0x9b, 0x89, 0xfb, 0xe9, 0x85, 0x95, 0xd6, 0x22, 0x5e, 0x4d, 0x6d, 0x83, 0x9d, 0xf4, 0xbe, 0x66, 0x05, 0x32, 0xb6, 0xe2, 0xf1, 0x96, 0x42, 0xa4, 0xc8, 0x8c, 0x1b, 0xec } }, + { { 0xf2, 0x4a, 0x96, 0x57, 0xc3, 0x2f, 0xe6, 0x9f, 0xed, 0x7f, 0xcc, 0xe9, 0xea, 0xbe, 0xd2, 0x23, 0x4e, 0x47, 0x13, 0xd9, 0x53, 0x19, 0x31, 0x14, 0x0a, 0xd3, 0x9b, 0x95, 0xa7, 0x9c, 0x88, 0x5e, + 0x08, 0xb2, 0x16, 0xda, 0x45, 0x61, 0x1d, 0x6b, 0xdf, 0xb1, 0x14, 0x0c, 0x66, 0xfd, 0x3a, 0xbe, 0x25, 0xdc, 0xfd, 0xcd, 0xcc, 0x5e, 0x28, 0x77, 0x5a, 0xa9, 0x8b, 0x84, 0x77, 0x26, 0x9d, 0xa6 }, + { 0xea, 0xde, 0x4d, 0xab, 0x09, 0x02, 0xbf, 0x90, 0xf8, 0xae, 0x8b, 0x50, 0x01, 0xb2, 0x9d, 0x7c, 0x0a, 0x3b, 0x60, 0xda, 0x34, 0xa9, 0xbb, 0x4d, 0xa5, 0x53, 0x18, 0x65, 0xec, 0xaa, 0xc9, 0x29, + 0xb2, 0xf7, 0x74, 0x14, 0x63, 0x5f, 0x88, 0xcf, 0x4e, 0x70, 0x1b, 0x11, 0x64, 0x73, 0x15, 0x6b, 0x5a, 0x8c, 0xb8, 0x4e, 0x0f, 0x83, 0xae, 0x4b, 0x5c, 0x52, 0x1c, 0x6a, 0x0f, 0x54, 0x77, 0xc8 }, + { 0xae, 0xff, 0x55, 0xbf, 0x78, 0xb5, 0xde, 0x33, 0xeb, 0x87, 0xea, 0x13, 0x7d, 0x36, 0x22, 0x06, 0x32, 0xc4, 0x7e, 0xca, 0x65, 0x37, 0xcc, 0x83, 0x0e, 0xda, 0x54, 0xb3, 0xd2, 0xe6, 0xe7, 0x7f, + 0xe1, 0x90, 0x11, 0x25, 0x16, 0x83, 0x25, 0x43, 0xb4, 0x38, 0x06, 0xbb, 0x6c, 0x62, 0x7d, 0x84, 0x1f, 0xf3, 0x7b, 0xeb, 0xae, 0x50, 0xd8, 0xfb, 0xb9, 0xf2, 0xf9, 0xc3, 0x6f, 0x59, 0xb7, 0xb0 }, + { 0x95, 0x15, 0x83, 0x19, 0x56, 0x9c, 0x11, 0xd8, 0x31, 0x87, 0x1d, 0xe3, 0x3f, 0x07, 0x89, 0xb2, 0xcb, 0x81, 0xf0, 0xeb, 0x0b, 0x1e, 0x74, 0x08, 0xa2, 0x4a, 0x0e, 0x82, 0xc6, 0x45, 0x8c, 0x32, + 0xb4, 0x8f, 0xfd, 0x76, 0xeb, 0x5e, 0xc7, 0x62, 0xdc, 0xcb, 0xee, 0xad, 0xcf, 0xcf, 0xea, 0x33, 0x9d, 0xb0, 0x02, 0x64, 0x66, 0x77, 0x14, 0x97, 0x0c, 0x6e, 0x79, 0xe8, 0x58, 0x32, 0x0f, 0xe6 }, + { 0xcb, 0x2f, 0xaf, 0x53, 0xd8, 0x41, 0x48, 0x41, 0x6f, 0x36, 0x78, 0x80, 0x83, 0x5c, 0x0d, 0x4c, 0x1b, 0xf4, 0x39, 0xe0, 0x34, 0x4f, 0xc2, 0xb2, 0x4e, 0xf0, 0xac, 0xc2, 0xf8, 0x15, 0x7a, 0x81, + 0x9f, 0x46, 0x2b, 0xe3, 0xb9, 0x39, 0x05, 0x89, 0xa2, 0xda, 0x1a, 0x63, 0x51, 0xb4, 0x78, 0x0f, 0xfe, 0x2f, 0x9d, 0xce, 0x99, 0x38, 0xa9, 0x7e, 0xcb, 0x80, 0x57, 0x9f, 0xa2, 0x28, 0x0f, 0x6a }, + { 0x1b, 0xec, 0x67, 0x50, 0xd1, 0x28, 0x65, 0x55, 0xb8, 0xde, 0x3b, 0x2e, 0x1e, 0x33, 0xd8, 0x1b, 0xba, 0x2e, 0x78, 0x6a, 0xb8, 0x0b, 0x8c, 0xa0, 0x55, 0x34, 0x25, 0x90, 0x9a, 0xe2, 0xf5, 0xaa, + 0x95, 0x0c, 0x6f, 0x2a, 0xb0, 0x92, 0x1d, 0x48, 0x5b, 0x56, 0x8c, 0x82, 0x8f, 0xa7, 0x15, 0x75, 0x26, 0x61, 0x85, 0xc8, 0x7d, 0xda, 0xf5, 0x2a, 0xf3, 0x3c, 0x34, 0xc1, 0x20, 0x67, 0xbb, 0x04, + 0xec, 0x7c, 0xe2, 0xcb, 0x31, 0xcf, 0x23, 0xda, 0x5d, 0x8a, 0x05, 0x00, 0x9b, 0x23, 0x34, 0xd0, 0xed, 0x56, 0x10, 0x0a, 0x90, 0x6b, 0x73, 0x26, 0x6b, 0xf0, 0xd7, 0xbc, 0xd8, 0xc7, 0x89, 0xc8 }, + { 0x90, 0x43, 0x54, 0x87, 0x44, 0x00, 0x07, 0xca, 0xa8, 0x2b, 0xec, 0x55, 0xa0, 0xd2, 0x8c, 0x07, 0x03, 0xaa, 0x61, 0x1a, 0x7d, 0x0f, 0x90, 0x13, 0x67, 0x99, 0x46, 0x20, 0xcd, 0x70, 0xcb, 0xa7, + 0x96, 0xdf, 0x0c, 0x13, 0xc4, 0x41, 0x11, 0xd6, 0xc3, 0x33, 0x02, 0x96, 0x4f, 0x1d, 0xbd, 0x06, 0xa9, 0xa1, 0x31, 0x0a, 0xc3, 0xdf, 0x6d, 0x52, 0x6c, 0xc6, 0xbe, 0xc5, 0xb6, 0x2a, 0xb1, 0x0f, + 0xec, 0x7c, 0xe2, 0xcb, 0x31, 0xcf, 0x23, 0xda, 0x5d, 0x8a, 0x05, 0x00, 0x9b, 0x23, 0x34, 0xd0, 0xed, 0x56, 0x10, 0x0a, 0x90, 0x6b, 0x73, 0x26, 0x6b, 0xf0, 0xd7, 0xbc, 0xd8, 0xc7, 0x89, 0xc8 } }, + { { 0x4f, 0x3a, 0xdd, 0x0f, 0xcf, 0x7f, 0x27, 0xda, 0x27, 0xc4, 0xa6, 0x2b, 0x6b, 0xd1, 0x9f, 0x59, 0x73, 0x5f, 0xd4, 0xb7, 0xf0, 0x86, 0x16, 0xc9, 0xdd, 0xa6, 0xf9, 0x9b, 0x17, 0xb2, 0xb9, 0x71, + 0xe7, 0x4c, 0xa1, 0x17, 0x79, 0xe0, 0xcc, 0xae, 0x10, 0xec, 0x28, 0x3a, 0x09, 0xf2, 0x8b, 0x34, 0x9c, 0xac, 0x16, 0x2a, 0xa9, 0x21, 0xe8, 0xa7, 0x18, 0xc0, 0xc4, 0x9f, 0x30, 0xa0, 0x25, 0x62 }, + { 0x23, 0x4c, 0xd4, 0xae, 0x52, 0x30, 0xf6, 0x64, 0xb9, 0xe1, 0x47, 0xca, 0xf8, 0xf3, 0x3a, 0x6b, 0x8b, 0xf3, 0x29, 0xe2, 0x9b, 0x5d, 0xbb, 0x0a, 0x60, 0x52, 0x03, 0x40, 0x53, 0x5c, 0x9e, 0x35, + 0x03, 0xd4, 0xec, 0xd7, 0x67, 0xf4, 0x92, 0xd2, 0x98, 0x96, 0xf2, 0xa7, 0xf4, 0x25, 0x6a, 0x80, 0x9c, 0x75, 0xc6, 0xf2, 0x1f, 0x67, 0x11, 0x00, 0x0d, 0xda, 0x1e, 0xb2, 0x58, 0xa7, 0x8c, 0x39 }, + { 0x55, 0x1b, 0x80, 0xbb, 0xf3, 0xc5, 0x1a, 0x84, 0x34, 0xf5, 0x0a, 0x8a, 0x8a, 0xe1, 0x8c, 0xea, 0xa6, 0xfb, 0xd0, 0x26, 0xc9, 0xa2, 0x30, 0x37, 0x3e, 0xba, 0x98, 0xfe, 0x81, 0x8a, 0x52, 0x37, + 0x0b, 0x74, 0x4e, 0x3d, 0x26, 0x8f, 0x82, 0x4b, 0xc0, 0x6a, 0x01, 0x10, 0x91, 0x8f, 0x89, 0xb5, 0x62, 0x3f, 0x1e, 0x70, 0xcc, 0x25, 0x77, 0x39, 0x74, 0x88, 0xdd, 0xbc, 0xbe, 0x72, 0x08, 0x63 }, + { 0xe2, 0x9a, 0x46, 0xd2, 0x74, 0xdc, 0x0f, 0x8a, 0xa3, 0xbd, 0x20, 0xb7, 0xc7, 0xd9, 0x83, 0x4b, 0x58, 0xa6, 0xe3, 0xbd, 0xc5, 0x00, 0xb6, 0x18, 0x04, 0x25, 0x81, 0xbd, 0x99, 0xb3, 0xb1, 0x2a, + 0x7a, 0x68, 0x6d, 0xe1, 0x3e, 0x23, 0x8d, 0x29, 0x9e, 0x7a, 0x30, 0x56, 0x4c, 0x22, 0xb6, 0xf4, 0x7d, 0x7d, 0x4f, 0xfd, 0x76, 0xa5, 0x9d, 0x05, 0x41, 0x7c, 0x7a, 0x2d, 0x7b, 0xbe, 0xcf, 0x73 }, + { 0x7b, 0xae, 0x11, 0x86, 0x8a, 0x38, 0xbd, 0x56, 0x3c, 0xf3, 0x3c, 0x9c, 0x49, 0xa4, 0x68, 0x0f, 0x2b, 0xdf, 0xf2, 0xa1, 0xbc, 0xc2, 0xed, 0x08, 0x09, 0x96, 0xd0, 0x7e, 0x9b, 0xe3, 0x0a, 0x72, + 0x13, 0x03, 0xd4, 0x35, 0x0a, 0x94, 0x60, 0x09, 0x4a, 0xaa, 0xca, 0x35, 0x8e, 0xed, 0x12, 0xdd, 0x26, 0x8f, 0xf8, 0xa9, 0xa2, 0x8a, 0x7f, 0xac, 0xf3, 0x09, 0xc7, 0x22, 0xc5, 0x73, 0xec, 0xa0 }, + { 0xe9, 0xc5, 0x57, 0x0d, 0x85, 0xbf, 0x10, 0xe2, 0xd1, 0xf5, 0xd7, 0x22, 0xe9, 0x6a, 0x67, 0x8d, 0xd3, 0x9f, 0x1a, 0xef, 0x7f, 0xc0, 0x2b, 0xe1, 0xfd, 0x2c, 0xc2, 0x5f, 0x39, 0xf9, 0x34, 0xd0, + 0x87, 0x94, 0x41, 0x8a, 0x65, 0xa5, 0x20, 0x48, 0xa4, 0x20, 0x5f, 0x7a, 0xc7, 0x37, 0x00, 0x60, 0x59, 0x84, 0x2a, 0x1d, 0xff, 0x02, 0xc3, 0xe8, 0x20, 0xaa, 0x39, 0x13, 0xac, 0xf3, 0xd7, 0x05, + 0xbd, 0xef, 0x11, 0x66, 0x71, 0xb8, 0x9f, 0x1e, 0xe5, 0xee, 0x2e, 0x37, 0xfb, 0x34, 0xed, 0xc5, 0xa4, 0x40, 0x6e, 0x38, 0x31, 0x0a, 0x1c, 0xaf, 0x0d, 0xd3, 0x98, 0xac, 0x12, 0x40, 0xea, 0x9c }, + { 0xc6, 0xcd, 0x7a, 0xbd, 0x14, 0xdb, 0xe4, 0xed, 0xbf, 0x46, 0x70, 0x23, 0xbd, 0xdb, 0xc3, 0xce, 0x60, 0xd5, 0x6b, 0x17, 0x4c, 0x23, 0xfa, 0x78, 0x05, 0xcc, 0x18, 0xed, 0x42, 0x03, 0xa5, 0xb7, + 0xdf, 0x28, 0x0e, 0xd4, 0x5d, 0x31, 0xd8, 0xb9, 0xdc, 0xe9, 0xf6, 0x26, 0xc5, 0xe1, 0xb3, 0x80, 0x0d, 0x62, 0xaf, 0x2d, 0xbd, 0xd6, 0xe4, 0xbb, 0x16, 0x82, 0xc8, 0x13, 0x2a, 0x6f, 0xb9, 0x06, + 0xbd, 0xef, 0x11, 0x66, 0x71, 0xb8, 0x9f, 0x1e, 0xe5, 0xee, 0x2e, 0x37, 0xfb, 0x34, 0xed, 0xc5, 0xa4, 0x40, 0x6e, 0x38, 0x31, 0x0a, 0x1c, 0xaf, 0x0d, 0xd3, 0x98, 0xac, 0x12, 0x40, 0xea, 0x9c } }, + { { 0x6f, 0x46, 0xcd, 0x96, 0xc4, 0x13, 0xf4, 0x11, 0x62, 0x49, 0x8c, 0x5c, 0x78, 0x27, 0xef, 0xc8, 0xb9, 0xe2, 0x7d, 0xf1, 0x0d, 0x37, 0xf2, 0xfe, 0x85, 0x35, 0x82, 0x60, 0x23, 0xb6, 0x7b, 0x17, + 0xd2, 0x91, 0xef, 0x01, 0x9e, 0x99, 0x35, 0xab, 0xc7, 0xfb, 0xa1, 0xa3, 0x13, 0x44, 0x3f, 0x3c, 0x16, 0xcb, 0xd8, 0xf0, 0xbf, 0x9e, 0x65, 0x4d, 0x07, 0xe0, 0xfd, 0x8e, 0x32, 0x61, 0x95, 0xd5 }, + { 0xb7, 0x81, 0x16, 0x2f, 0xcb, 0xa4, 0x30, 0x4e, 0x6d, 0xf5, 0xf0, 0x3f, 0xfe, 0xd9, 0x81, 0x20, 0xa6, 0x0e, 0x2b, 0xa8, 0xc5, 0xed, 0x0d, 0x9a, 0x28, 0x9c, 0xe3, 0xa9, 0xb7, 0xbf, 0x87, 0x0f, + 0xa5, 0xf9, 0x33, 0xe7, 0xa6, 0x7f, 0x9b, 0xac, 0xb6, 0xcc, 0xaf, 0xfc, 0xa7, 0x4a, 0x4d, 0x36, 0x39, 0xa9, 0xb6, 0xf5, 0x09, 0xde, 0x8d, 0x37, 0x11, 0x07, 0xd1, 0x8a, 0xf5, 0x7b, 0x66, 0xe1 }, + { 0xcc, 0xe0, 0x07, 0x62, 0xbe, 0x10, 0x8c, 0x3a, 0xa2, 0x96, 0x5d, 0x11, 0xc7, 0xd5, 0x50, 0xc3, 0xbb, 0x55, 0x21, 0xc5, 0x40, 0x27, 0x7d, 0xdb, 0xad, 0xd2, 0x61, 0x2a, 0x42, 0x5f, 0x94, 0x23, + 0x77, 0x83, 0x3a, 0x99, 0xe8, 0xda, 0x79, 0x8c, 0x1e, 0xa8, 0x44, 0x04, 0xec, 0xf5, 0xd1, 0x55, 0x1e, 0x58, 0xf1, 0x6e, 0x4d, 0x27, 0xa4, 0x91, 0xec, 0x59, 0xc8, 0x17, 0x36, 0x58, 0x2a, 0x1f }, + { 0x6d, 0xf8, 0x73, 0xa3, 0x38, 0x61, 0x1d, 0x95, 0x09, 0xde, 0xe5, 0x26, 0x1b, 0x15, 0x16, 0xfb, 0xf5, 0x16, 0xa8, 0xf3, 0x9e, 0x3a, 0x6b, 0xb5, 0x8c, 0xee, 0xa8, 0x66, 0x79, 0xc3, 0x9e, 0xb4, + 0xe1, 0xc2, 0x85, 0x0e, 0x86, 0x10, 0x5a, 0x4e, 0x8b, 0x4c, 0x0a, 0x7a, 0xd8, 0x8a, 0x48, 0xf4, 0xa0, 0x79, 0x37, 0xe3, 0xa5, 0x90, 0x05, 0x5e, 0xbd, 0xa1, 0xf6, 0x09, 0x58, 0x9c, 0x6f, 0x09 }, + { 0x66, 0x47, 0x6d, 0x60, 0x06, 0x2d, 0x90, 0x8f, 0xae, 0x6c, 0x01, 0xe9, 0xb0, 0xf9, 0x6b, 0xa5, 0x4a, 0xe1, 0xdb, 0xd3, 0x64, 0x42, 0x37, 0x5c, 0x11, 0x40, 0x7a, 0xce, 0x4e, 0x83, 0xc3, 0x2c, + 0x2e, 0xd2, 0x67, 0x76, 0xfb, 0x8c, 0x5d, 0xab, 0xe8, 0xb8, 0xd6, 0x2b, 0xf8, 0x86, 0xff, 0x96, 0xf3, 0xa8, 0x0e, 0x2b, 0x1a, 0x68, 0xf5, 0xe4, 0xee, 0x49, 0xa6, 0x8c, 0x41, 0x1f, 0x97, 0xbf }, + { 0x81, 0x92, 0x4e, 0xc6, 0xab, 0x00, 0xdd, 0xf9, 0xf9, 0xb7, 0xe0, 0x0a, 0xa9, 0x3f, 0x0a, 0xf9, 0x32, 0x73, 0xf6, 0x22, 0xec, 0x95, 0xd9, 0x20, 0x8a, 0x3f, 0xeb, 0x0d, 0xc7, 0x79, 0x6f, 0xb3, + 0x85, 0xf4, 0xe1, 0x11, 0xe1, 0xcc, 0xaa, 0x1b, 0xfd, 0xf3, 0x43, 0xff, 0x66, 0x73, 0x0f, 0x09, 0xcc, 0xa4, 0x6c, 0xb8, 0x2a, 0x0f, 0x53, 0x58, 0x63, 0x32, 0x06, 0xd9, 0x6b, 0x1a, 0x14, 0x04, + 0x85, 0x3f, 0x2f, 0x2b, 0x05, 0xfb, 0xed, 0xe9, 0x08, 0x0d, 0x21, 0x49, 0xc9, 0x79, 0xdf, 0x6f, 0x77, 0x89, 0xd7, 0x74, 0x09, 0x57, 0x1a, 0xd2, 0xa7, 0x43, 0xbf, 0x08, 0x8e, 0x98, 0xbc, 0x2f }, + { 0xe3, 0xb1, 0xc4, 0x81, 0xe6, 0xec, 0x07, 0x58, 0xa4, 0xcb, 0x7e, 0xd5, 0xae, 0x9d, 0x43, 0xf1, 0xb7, 0xe2, 0x0a, 0x1f, 0xd5, 0xe8, 0x14, 0xba, 0x22, 0xff, 0xb7, 0x20, 0x76, 0x08, 0xdc, 0x9a, + 0x44, 0x4c, 0x1c, 0xcd, 0x38, 0x4d, 0xb5, 0xd8, 0xa9, 0x1b, 0x9d, 0xbb, 0x13, 0x5a, 0x6c, 0xe9, 0x5d, 0xa4, 0x42, 0x0e, 0xde, 0x9a, 0x47, 0x8a, 0x2a, 0x97, 0x42, 0x86, 0x87, 0x98, 0x3f, 0x04, + 0x85, 0x3f, 0x2f, 0x2b, 0x05, 0xfb, 0xed, 0xe9, 0x08, 0x0d, 0x21, 0x49, 0xc9, 0x79, 0xdf, 0x6f, 0x77, 0x89, 0xd7, 0x74, 0x09, 0x57, 0x1a, 0xd2, 0xa7, 0x43, 0xbf, 0x08, 0x8e, 0x98, 0xbc, 0x2f } }, + { { 0xff, 0xe3, 0x69, 0x7b, 0x62, 0x45, 0x40, 0x5f, 0x1c, 0x49, 0x65, 0xd6, 0xae, 0x24, 0x16, 0x84, 0xfa, 0x69, 0x6c, 0x1f, 0x6c, 0x65, 0xee, 0x52, 0xe9, 0x6c, 0x54, 0xc7, 0x31, 0x9b, 0xc2, 0x74, + 0x4f, 0xc0, 0x16, 0xb8, 0xf8, 0x75, 0x5f, 0x45, 0xb5, 0xf3, 0xa0, 0xd9, 0xbe, 0x25, 0x82, 0xbd, 0x3c, 0x03, 0xe0, 0x14, 0x15, 0x6a, 0xd5, 0x64, 0x08, 0x65, 0x13, 0x33, 0xc2, 0xab, 0xe0, 0x45 }, + { 0x6f, 0x5a, 0x90, 0x80, 0x25, 0x13, 0xc2, 0xa7, 0xfe, 0x1c, 0xa1, 0x07, 0x81, 0x4b, 0x09, 0xd3, 0xbd, 0xda, 0x55, 0xa8, 0xaa, 0x62, 0x19, 0x03, 0xe9, 0x9f, 0x77, 0xef, 0xff, 0xd4, 0x5e, 0x53, + 0xbc, 0x9d, 0x71, 0xb8, 0xc4, 0xc2, 0x85, 0xb9, 0xb4, 0x3d, 0x95, 0xb8, 0xfd, 0x44, 0xb7, 0xc8, 0x6f, 0x93, 0x15, 0x04, 0x16, 0x7e, 0x01, 0xf2, 0x09, 0x23, 0x96, 0x69, 0xe5, 0x65, 0x52, 0x34 }, + { 0xaf, 0xfe, 0x4f, 0x34, 0x4e, 0xfe, 0x51, 0xa5, 0xb2, 0xd8, 0x31, 0x74, 0x7b, 0xae, 0xfb, 0xb9, 0x33, 0xc1, 0xdc, 0x66, 0xe6, 0x95, 0x9e, 0xce, 0x77, 0x7d, 0x55, 0x3c, 0xa6, 0x6c, 0x09, 0x23, + 0x5a, 0x1a, 0x5e, 0x1a, 0x41, 0xd3, 0xad, 0x5f, 0x86, 0xd0, 0x14, 0xf5, 0xe0, 0xda, 0xf1, 0xce, 0x19, 0x90, 0x45, 0x0c, 0x4c, 0xb1, 0xd3, 0xc8, 0x4c, 0xdb, 0x7e, 0x49, 0xf5, 0xac, 0xde, 0xff }, + { 0x1b, 0x9b, 0x6b, 0x30, 0xd3, 0x19, 0x37, 0x83, 0xad, 0x05, 0xca, 0xba, 0x22, 0x85, 0x33, 0x7f, 0x55, 0x60, 0xe3, 0x14, 0x8c, 0x39, 0x87, 0xd1, 0x4c, 0x21, 0x27, 0xa0, 0xae, 0x4a, 0x56, 0x15, + 0x50, 0x6c, 0x99, 0xca, 0xff, 0xde, 0x10, 0xc6, 0x9f, 0x6c, 0x70, 0xd1, 0x66, 0xb4, 0x87, 0xd8, 0xfc, 0x46, 0xf2, 0xcf, 0x0c, 0xd8, 0xc3, 0x14, 0x5d, 0x27, 0xbd, 0xed, 0x32, 0x36, 0x7c, 0xed }, + { 0x64, 0x6b, 0x74, 0xc7, 0x60, 0x36, 0xc5, 0xe4, 0xb6, 0xde, 0x02, 0x1a, 0x09, 0xaf, 0x65, 0xb1, 0x94, 0xa3, 0xf4, 0x95, 0xf5, 0xb0, 0xef, 0x86, 0xb5, 0x13, 0x26, 0x0b, 0xe8, 0xc5, 0x5c, 0x77, + 0xf5, 0xe6, 0xb6, 0x10, 0x36, 0x87, 0xa3, 0xd2, 0x7c, 0x17, 0x2c, 0xb9, 0xb0, 0x90, 0x9e, 0x8c, 0x0a, 0x7d, 0x73, 0xb2, 0x29, 0xeb, 0xa7, 0x85, 0xd7, 0x04, 0x14, 0xf9, 0x77, 0xb7, 0xf4, 0x89 }, + { 0x7f, 0x1c, 0x5a, 0x57, 0x14, 0xf6, 0x30, 0x07, 0xf9, 0xfe, 0x42, 0x98, 0xcb, 0x3d, 0xac, 0x04, 0x30, 0x0d, 0xc6, 0xd0, 0x4f, 0x8a, 0xbc, 0xdd, 0x3e, 0xc3, 0xb7, 0x74, 0xc8, 0x3b, 0x1a, 0xcc, + 0x6a, 0x54, 0x9e, 0xb9, 0xbe, 0xf0, 0x7c, 0x35, 0x35, 0x1a, 0x50, 0x4c, 0xc2, 0x38, 0x41, 0x46, 0xc8, 0xc4, 0x81, 0x2b, 0x26, 0x56, 0x6f, 0x8a, 0x9f, 0x74, 0x87, 0xe0, 0x01, 0x82, 0xe2, 0x09, + 0xf3, 0x9a, 0xc5, 0x33, 0x5a, 0x7d, 0xb6, 0xbb, 0xff, 0x20, 0x4d, 0xc1, 0x99, 0x3d, 0xcc, 0x5a, 0xc7, 0xd1, 0xbe, 0x4c, 0xcf, 0xc8, 0x09, 0x79, 0x15, 0x5e, 0x0c, 0xc6, 0x26, 0x36, 0xe6, 0xd9 }, + { 0x4d, 0x2f, 0x08, 0x84, 0x32, 0xcf, 0xe0, 0x3b, 0xa8, 0x3e, 0xa5, 0xf8, 0x3a, 0xe8, 0xa9, 0x04, 0x5a, 0x74, 0x67, 0xcb, 0x41, 0x22, 0xc5, 0xc4, 0x9a, 0xa5, 0xc1, 0xa7, 0x94, 0x8b, 0xa5, 0x35, + 0x00, 0x00, 0x1a, 0xaf, 0xfb, 0xed, 0x40, 0xb8, 0x2b, 0x28, 0xf1, 0xb1, 0x02, 0xd3, 0x8b, 0xc0, 0x32, 0x4a, 0xa5, 0x0a, 0xa4, 0xc3, 0xbf, 0xb3, 0xf5, 0xb7, 0x65, 0x8e, 0x88, 0xdf, 0xd0, 0x0e, + 0xf3, 0x9a, 0xc5, 0x33, 0x5a, 0x7d, 0xb6, 0xbb, 0xff, 0x20, 0x4d, 0xc1, 0x99, 0x3d, 0xcc, 0x5a, 0xc7, 0xd1, 0xbe, 0x4c, 0xcf, 0xc8, 0x09, 0x79, 0x15, 0x5e, 0x0c, 0xc6, 0x26, 0x36, 0xe6, 0xd9 } }, + { { 0xc8, 0x8e, 0x1c, 0xea, 0x02, 0x6a, 0xfd, 0x88, 0x8b, 0xa9, 0x9d, 0xdd, 0xba, 0xea, 0x77, 0x30, 0x88, 0x1a, 0x93, 0x49, 0xda, 0x05, 0x18, 0xbb, 0x4a, 0x6a, 0x11, 0xc4, 0x48, 0x72, 0x77, 0x1f, + 0x6e, 0x2b, 0x9a, 0xe3, 0x27, 0xbe, 0xe1, 0x75, 0x32, 0x30, 0xa6, 0x12, 0x26, 0x44, 0xbf, 0xb2, 0xa5, 0x51, 0x0b, 0x48, 0x3a, 0xea, 0xc5, 0xd4, 0x24, 0x3f, 0x4e, 0xe8, 0xe5, 0xc3, 0xfb, 0xc2 }, + { 0xcb, 0x56, 0x3c, 0x00, 0x28, 0x15, 0x72, 0x16, 0x23, 0x4e, 0x2e, 0x2c, 0x8c, 0xe8, 0x7c, 0x44, 0x82, 0x2a, 0xe0, 0x57, 0xa3, 0x0a, 0xc4, 0x42, 0xb5, 0x07, 0xe1, 0x1b, 0x78, 0x8b, 0x3d, 0x4d, + 0xcb, 0xe4, 0x56, 0x72, 0x0b, 0x85, 0x52, 0xd8, 0x55, 0xe2, 0xcd, 0x38, 0xd2, 0x83, 0xb6, 0x05, 0xd2, 0x9f, 0x63, 0x9e, 0x7f, 0xca, 0xe5, 0x95, 0x36, 0x61, 0x9b, 0xca, 0x09, 0x27, 0x53, 0x82 }, + { 0x24, 0x67, 0x10, 0xd6, 0x8a, 0x1a, 0x8e, 0xb8, 0x53, 0xef, 0xb7, 0x67, 0x2a, 0xfd, 0xb8, 0xd6, 0xe3, 0xf7, 0x41, 0x95, 0x8c, 0x50, 0xca, 0x1d, 0x21, 0x21, 0x41, 0xd1, 0xef, 0x2d, 0x9b, 0x53, + 0xa9, 0x42, 0xcd, 0xda, 0x6d, 0x12, 0x1b, 0xbd, 0x0a, 0xe1, 0x4d, 0x95, 0xc6, 0xaa, 0x40, 0xfd, 0x98, 0xfb, 0x26, 0x21, 0x5e, 0xaf, 0x8e, 0x6b, 0xc9, 0x36, 0x2c, 0x66, 0x31, 0x24, 0x45, 0x87 }, + { 0x5e, 0xf9, 0x1d, 0x10, 0xb5, 0x79, 0x1f, 0x80, 0x85, 0x90, 0xc3, 0x7f, 0x2b, 0x73, 0xbf, 0x83, 0x0b, 0x5d, 0x46, 0xae, 0x79, 0xef, 0x09, 0x71, 0x29, 0xfb, 0x83, 0xde, 0x1f, 0xe2, 0xdb, 0x1b, + 0xa2, 0x22, 0xee, 0x50, 0x21, 0x9d, 0x9c, 0x35, 0x14, 0x48, 0x13, 0xa5, 0xd1, 0x68, 0xf4, 0x61, 0x1f, 0xd7, 0xe2, 0xd6, 0x42, 0x1c, 0xdc, 0x58, 0xec, 0x8b, 0x03, 0x6b, 0xdf, 0x64, 0x06, 0x30 }, + { 0xf9, 0xa6, 0x88, 0x74, 0x07, 0x19, 0x15, 0x38, 0xaf, 0xac, 0x07, 0x10, 0xe0, 0xd9, 0x22, 0xf3, 0x78, 0xb0, 0xbf, 0x60, 0xa3, 0x0f, 0xea, 0x0f, 0xa8, 0x64, 0xa9, 0xa3, 0x82, 0xe1, 0x4c, 0x29, + 0x36, 0x22, 0x6d, 0x43, 0x9c, 0xde, 0x22, 0xbf, 0xc6, 0x85, 0xf7, 0xe9, 0xe0, 0x79, 0x80, 0xfe, 0x9d, 0xd6, 0x24, 0xbd, 0x29, 0xa4, 0x8c, 0x35, 0x21, 0x87, 0x45, 0x7f, 0x88, 0xd9, 0x9a, 0x9d }, + { 0x49, 0x43, 0x19, 0x14, 0xcc, 0x4a, 0x11, 0x01, 0x05, 0xd1, 0x4e, 0x39, 0x6d, 0xb0, 0x22, 0x65, 0x32, 0x6e, 0x67, 0x04, 0x50, 0x85, 0x53, 0x42, 0x90, 0x2c, 0xc0, 0x63, 0x2f, 0xbd, 0x15, 0x90, + 0x1b, 0x3f, 0x03, 0x90, 0x16, 0x7f, 0x7b, 0x49, 0x74, 0xd0, 0x3d, 0x81, 0x80, 0x1e, 0x9e, 0x2e, 0xa9, 0x13, 0x6a, 0x10, 0x14, 0xc1, 0xfd, 0xf9, 0x25, 0x3a, 0x1d, 0x52, 0x93, 0x0a, 0x77, 0x03, + 0xa2, 0xdd, 0xce, 0x9f, 0x2a, 0x35, 0xc9, 0x93, 0x7c, 0xa2, 0x2c, 0xf6, 0x38, 0x73, 0xb3, 0xab, 0x7f, 0x55, 0xb6, 0x62, 0xa2, 0x8d, 0x6a, 0x3e, 0x88, 0x04, 0x9b, 0xa2, 0x19, 0x64, 0x55, 0x01 }, + { 0x22, 0x03, 0x49, 0x58, 0x76, 0x3c, 0x85, 0x45, 0x5e, 0x73, 0x78, 0x8f, 0x65, 0xc9, 0x50, 0xf8, 0xd7, 0x16, 0x92, 0xa4, 0xd1, 0x79, 0xce, 0xf3, 0x00, 0x34, 0x38, 0xb8, 0xcc, 0x96, 0x9f, 0xa6, + 0x87, 0x28, 0xcb, 0x19, 0x28, 0xad, 0x83, 0xb5, 0x09, 0x96, 0x54, 0xe8, 0x2a, 0xb9, 0x9b, 0xff, 0x60, 0x85, 0x31, 0x28, 0x62, 0x36, 0xd2, 0x0e, 0xad, 0x2a, 0xe1, 0x84, 0x80, 0xeb, 0x6f, 0x00, + 0xa2, 0xdd, 0xce, 0x9f, 0x2a, 0x35, 0xc9, 0x93, 0x7c, 0xa2, 0x2c, 0xf6, 0x38, 0x73, 0xb3, 0xab, 0x7f, 0x55, 0xb6, 0x62, 0xa2, 0x8d, 0x6a, 0x3e, 0x88, 0x04, 0x9b, 0xa2, 0x19, 0x64, 0x55, 0x01 } }, + { { 0xeb, 0x18, 0x95, 0x94, 0x5f, 0x15, 0x8c, 0xb8, 0x4d, 0x6e, 0x7d, 0xc0, 0x96, 0x6c, 0x52, 0xa2, 0x5f, 0x43, 0x67, 0xc2, 0x3a, 0x10, 0x5b, 0xf1, 0x8f, 0x21, 0x89, 0x06, 0x77, 0xe9, 0xab, 0x2e, + 0xcd, 0x17, 0x9c, 0x9a, 0xd7, 0x89, 0x7e, 0x53, 0x58, 0x60, 0x9b, 0xce, 0x90, 0xd9, 0x13, 0x2d, 0x78, 0xc4, 0x2c, 0x1c, 0x4c, 0xe8, 0x23, 0x70, 0xff, 0xa0, 0x42, 0x98, 0x25, 0x40, 0xd6, 0xd8 }, + { 0xb6, 0xfb, 0xdd, 0x5d, 0x35, 0xf2, 0x2b, 0x89, 0xda, 0x8e, 0x90, 0xee, 0x03, 0x4e, 0x75, 0xdb, 0x4c, 0x45, 0xc8, 0x00, 0xde, 0x06, 0x27, 0xde, 0x44, 0xb5, 0x5b, 0xc7, 0x56, 0xc3, 0xf5, 0xbb, + 0xee, 0xa6, 0x21, 0xd4, 0xd9, 0xb9, 0x24, 0x9c, 0x4c, 0xbc, 0x23, 0xe5, 0xeb, 0x05, 0xb6, 0xd0, 0xd0, 0xbf, 0x49, 0x95, 0x01, 0xb4, 0x97, 0xad, 0xb5, 0x71, 0x8d, 0x4b, 0x32, 0xd0, 0xdd, 0x1a }, + { 0xfd, 0x11, 0xd7, 0xe4, 0x46, 0xcd, 0xd8, 0x44, 0x89, 0x0a, 0xe7, 0x44, 0x59, 0xe9, 0xcf, 0x9f, 0xd6, 0xf1, 0x74, 0x56, 0x04, 0x78, 0xfa, 0x29, 0x46, 0x8a, 0x8d, 0x1b, 0xbe, 0x41, 0x92, 0x1c, + 0x8d, 0x74, 0x01, 0x1b, 0xc1, 0xf8, 0x26, 0xf4, 0xc2, 0x68, 0xc3, 0x23, 0x8c, 0x68, 0x7c, 0x0a, 0xad, 0xdd, 0x50, 0x10, 0xcf, 0xdb, 0x78, 0xc5, 0x79, 0x28, 0x37, 0x63, 0x92, 0x1a, 0x1d, 0xea }, + { 0xd2, 0x2a, 0xf0, 0x66, 0x15, 0x8b, 0xcb, 0x83, 0xcf, 0x34, 0xa1, 0x33, 0x6b, 0xd5, 0xa8, 0x98, 0x3b, 0xd7, 0x09, 0x0d, 0x70, 0xa5, 0x8a, 0xc0, 0x73, 0xcf, 0xde, 0x59, 0xd5, 0x13, 0x41, 0xd2, + 0x43, 0x8b, 0xb4, 0xc3, 0x5b, 0x6f, 0xf1, 0xed, 0x47, 0x76, 0xe6, 0x5e, 0xb8, 0x2a, 0x7e, 0x20, 0x91, 0xa0, 0x9d, 0xc1, 0xa2, 0x0a, 0x6d, 0x97, 0x7d, 0xeb, 0xe3, 0x64, 0x5f, 0x86, 0xff, 0x3e }, + { 0x45, 0xd8, 0xdc, 0xe4, 0x3a, 0x3a, 0x44, 0xdc, 0x7f, 0xa8, 0x92, 0x11, 0x1b, 0x4f, 0xfa, 0xcf, 0x21, 0xff, 0xfb, 0x20, 0xb0, 0x02, 0x6d, 0x0e, 0x1c, 0xde, 0xe8, 0x51, 0xd8, 0x2c, 0x72, 0x0e, + 0xbf, 0xf6, 0x9a, 0xd3, 0xd3, 0xfe, 0xfa, 0x98, 0x4e, 0xc2, 0xf0, 0x16, 0xda, 0x39, 0x93, 0xc4, 0xe0, 0x33, 0x9a, 0x43, 0xe8, 0x7a, 0xc5, 0x0f, 0x0b, 0xa4, 0x45, 0xf0, 0x5e, 0x7a, 0xa9, 0x42 }, + { 0xdb, 0x4e, 0x17, 0x76, 0x8b, 0x3c, 0x98, 0x7f, 0x58, 0x76, 0x97, 0xc9, 0x3f, 0x99, 0x01, 0x05, 0x42, 0x7e, 0xfd, 0x83, 0x99, 0xaa, 0x19, 0xb5, 0x72, 0x4c, 0x69, 0xed, 0x6e, 0x21, 0x79, 0x6e, + 0x3b, 0x71, 0xe5, 0xab, 0x23, 0x84, 0xe7, 0xfe, 0x58, 0x2b, 0x0d, 0x1e, 0x75, 0x7c, 0x29, 0xb3, 0x2d, 0x66, 0xc2, 0x45, 0x88, 0xac, 0x86, 0x29, 0xe4, 0xaa, 0x9e, 0x71, 0xa1, 0x88, 0xf9, 0x06, + 0xda, 0xa3, 0xdd, 0x7b, 0x6c, 0xd9, 0xc9, 0x73, 0xe9, 0x56, 0xd1, 0xee, 0x5b, 0xf9, 0xae, 0xc0, 0x29, 0xbe, 0x20, 0x6c, 0xc7, 0xf9, 0xc5, 0x2d, 0x6d, 0xad, 0x8f, 0x49, 0xf8, 0x17, 0xdb, 0x7a }, + { 0xb8, 0xb7, 0xec, 0xeb, 0x3e, 0x40, 0x77, 0x6c, 0xab, 0x10, 0xfe, 0x9f, 0xd1, 0x40, 0xfe, 0xd2, 0x88, 0x8e, 0xb0, 0x55, 0xae, 0x75, 0xb1, 0xcc, 0x9d, 0x6c, 0x11, 0x28, 0x95, 0x38, 0x9f, 0xb9, + 0x59, 0xe2, 0x29, 0xc3, 0xbc, 0x09, 0x16, 0x1f, 0x17, 0x9e, 0x15, 0x78, 0x09, 0x61, 0x07, 0x9e, 0xad, 0x67, 0x98, 0xa9, 0x24, 0xff, 0xf9, 0x4b, 0xa2, 0x76, 0x09, 0xa0, 0xd7, 0x1b, 0xed, 0x05, + 0xda, 0xa3, 0xdd, 0x7b, 0x6c, 0xd9, 0xc9, 0x73, 0xe9, 0x56, 0xd1, 0xee, 0x5b, 0xf9, 0xae, 0xc0, 0x29, 0xbe, 0x20, 0x6c, 0xc7, 0xf9, 0xc5, 0x2d, 0x6d, 0xad, 0x8f, 0x49, 0xf8, 0x17, 0xdb, 0x7a } }, + { { 0xc3, 0x92, 0x4d, 0x01, 0x9c, 0xea, 0x5a, 0x8d, 0xbd, 0x5c, 0x12, 0x58, 0x6d, 0x03, 0x26, 0xbf, 0xa4, 0xdd, 0xf7, 0x26, 0xa4, 0x0d, 0x22, 0xe0, 0xbd, 0xcc, 0x6f, 0x30, 0x9e, 0xf9, 0x4c, 0x1f, + 0x03, 0x52, 0xab, 0x38, 0xe9, 0x9c, 0x08, 0x9c, 0x09, 0xe5, 0x87, 0x5c, 0x24, 0x1a, 0xe2, 0x75, 0xcb, 0x18, 0x8a, 0x63, 0x50, 0xd1, 0x23, 0x45, 0x49, 0x93, 0x40, 0x2c, 0x09, 0xd4, 0xac, 0x39 }, + { 0xd4, 0xe7, 0xb7, 0x05, 0xfd, 0xd6, 0xf3, 0x57, 0xfb, 0xc2, 0x2f, 0x2c, 0x71, 0x80, 0xf5, 0xc3, 0xa6, 0x0a, 0x23, 0x9d, 0x1d, 0xa8, 0x68, 0x10, 0x8a, 0xfa, 0x68, 0x9d, 0x2b, 0xcf, 0x96, 0xa9, + 0xe6, 0x0e, 0x07, 0x32, 0x23, 0x09, 0x87, 0x16, 0xc5, 0xbb, 0x76, 0x22, 0xfc, 0xb4, 0x59, 0x6d, 0x67, 0xfd, 0x29, 0x51, 0x95, 0x4c, 0xe2, 0x8c, 0x18, 0xab, 0xda, 0x84, 0xc3, 0x62, 0x80, 0x14 }, + { 0xc9, 0xa1, 0xfe, 0xc3, 0x48, 0x0d, 0xee, 0x54, 0x44, 0xff, 0x9c, 0x46, 0x04, 0x0e, 0x74, 0xda, 0xa4, 0x6a, 0x56, 0x02, 0x5f, 0x76, 0x0e, 0xb5, 0xc1, 0xc9, 0xe9, 0xb2, 0x6e, 0x07, 0x49, 0x0c, + 0xf7, 0x4b, 0xee, 0xd6, 0x0a, 0xad, 0x94, 0x03, 0x58, 0x2d, 0x60, 0x95, 0xf8, 0x16, 0x7b, 0x49, 0x0b, 0x01, 0x66, 0x3e, 0x17, 0x01, 0xe5, 0x54, 0x7d, 0xd7, 0xbb, 0x10, 0xd1, 0xad, 0xad, 0x79 }, + { 0xb2, 0xd8, 0x10, 0x29, 0xeb, 0xb8, 0x4e, 0x2b, 0x39, 0x85, 0x5c, 0xb3, 0xdc, 0xf5, 0x87, 0xca, 0xca, 0x9c, 0x7a, 0x8c, 0x2b, 0x08, 0xe8, 0x25, 0xe2, 0xcf, 0x70, 0xe2, 0xe6, 0xfb, 0xdb, 0x0c, + 0xc3, 0x0d, 0x71, 0x11, 0x83, 0x65, 0xf2, 0x71, 0x08, 0x1b, 0x32, 0x6e, 0x6c, 0x51, 0x50, 0xf1, 0xf6, 0x4b, 0x54, 0x63, 0x16, 0x7f, 0xfd, 0x80, 0x05, 0x61, 0x63, 0xf1, 0x80, 0x6a, 0x0b, 0xfd }, + { 0xa7, 0x4b, 0x75, 0x38, 0x90, 0x64, 0x96, 0x7b, 0xda, 0x5e, 0x08, 0x9b, 0x80, 0xc4, 0x72, 0x3f, 0x73, 0xb2, 0xdb, 0xd3, 0x4a, 0xed, 0xa4, 0xdc, 0x5c, 0x79, 0xe5, 0x0f, 0x7a, 0xd3, 0x0c, 0xac, + 0xf9, 0x99, 0x5c, 0x1a, 0x0f, 0xb3, 0x1a, 0x0f, 0x5c, 0xc3, 0x9e, 0x1a, 0x2b, 0xfa, 0xc3, 0xf0, 0x40, 0xe5, 0x5f, 0x36, 0xd2, 0x98, 0x31, 0xa1, 0xaf, 0x18, 0x5f, 0xae, 0x92, 0xf3, 0x9e, 0xc0 }, + { 0xf9, 0xbf, 0x52, 0xe6, 0xd3, 0xe1, 0x5d, 0xd3, 0x30, 0xf3, 0xa1, 0x0c, 0xc8, 0x5a, 0x97, 0x55, 0xab, 0x67, 0x67, 0xd0, 0x00, 0x62, 0x7b, 0x80, 0x70, 0xbf, 0x24, 0xd0, 0x09, 0x8b, 0x07, 0x77, + 0xeb, 0x3e, 0xf0, 0x5d, 0xdf, 0x7b, 0xa9, 0x7d, 0xa4, 0x6a, 0x0d, 0xf1, 0xac, 0x83, 0x7d, 0x64, 0xb5, 0xf4, 0xc6, 0xc4, 0x12, 0x0c, 0x55, 0x9f, 0x67, 0xbb, 0xd5, 0xe3, 0xd3, 0xdb, 0x17, 0x0f, + 0x90, 0x2f, 0x8f, 0xc9, 0xfd, 0x4e, 0x6c, 0x8b, 0xe6, 0x99, 0xfa, 0xda, 0x8f, 0x1f, 0xe6, 0xc3, 0xeb, 0xd8, 0x14, 0x20, 0xcc, 0x3c, 0x1c, 0x23, 0x77, 0x28, 0x9b, 0x22, 0x9a, 0x5a, 0x0c, 0x43 }, + { 0xa2, 0x78, 0x37, 0xc9, 0x63, 0xe1, 0x31, 0x36, 0xc2, 0x58, 0xac, 0xca, 0xbb, 0xa2, 0x84, 0xaa, 0xb3, 0x82, 0xe2, 0x19, 0xb7, 0x14, 0x96, 0x27, 0x77, 0xfa, 0xa1, 0x02, 0xaa, 0xff, 0x55, 0x82, + 0xba, 0xc0, 0x38, 0x1a, 0x69, 0x35, 0x48, 0x87, 0xc2, 0xeb, 0x48, 0x08, 0xea, 0xc5, 0x6b, 0xfc, 0x84, 0x60, 0x4e, 0xce, 0xd7, 0xd2, 0x86, 0x8b, 0x76, 0xf3, 0x46, 0xe1, 0x87, 0x1f, 0xff, 0x09, + 0x90, 0x2f, 0x8f, 0xc9, 0xfd, 0x4e, 0x6c, 0x8b, 0xe6, 0x99, 0xfa, 0xda, 0x8f, 0x1f, 0xe6, 0xc3, 0xeb, 0xd8, 0x14, 0x20, 0xcc, 0x3c, 0x1c, 0x23, 0x77, 0x28, 0x9b, 0x22, 0x9a, 0x5a, 0x0c, 0x43 } }, + { { 0x0e, 0xa6, 0x0c, 0xef, 0x12, 0xd6, 0x7d, 0x71, 0xd4, 0x88, 0x73, 0x86, 0x9a, 0x88, 0x8f, 0x5b, 0xd1, 0xb6, 0x12, 0xc4, 0x93, 0x8b, 0x5f, 0xee, 0xdd, 0x9c, 0x2a, 0x7f, 0x4d, 0xfd, 0xba, 0x00, + 0x09, 0x45, 0x77, 0xd2, 0xcf, 0xcd, 0x3a, 0x6f, 0x27, 0x44, 0xe2, 0x55, 0x3e, 0x79, 0x88, 0x4d, 0x5f, 0x38, 0x34, 0xe8, 0xe7, 0xc6, 0x3a, 0xde, 0xef, 0x99, 0x15, 0xea, 0x88, 0x79, 0xd7, 0xca }, + { 0xa0, 0x9a, 0x0a, 0x3a, 0x42, 0x35, 0x54, 0x78, 0xb9, 0x82, 0x52, 0xb4, 0xc8, 0x5c, 0x4a, 0x03, 0xa1, 0xb9, 0x27, 0xcc, 0x99, 0xec, 0x03, 0xdf, 0xdd, 0x6e, 0xde, 0xef, 0x8f, 0x7f, 0xdc, 0x5a, + 0xc3, 0xcb, 0x0e, 0xa2, 0x7e, 0x93, 0xe6, 0xdd, 0xbd, 0xf1, 0x1b, 0x03, 0x29, 0x63, 0x72, 0x11, 0x72, 0x3d, 0x24, 0x6f, 0xdf, 0x8e, 0xed, 0xa4, 0xe2, 0x2a, 0x4c, 0x00, 0xe2, 0xc4, 0x55, 0x1b }, + { 0xb2, 0xf1, 0xff, 0xf6, 0x3a, 0x26, 0xe1, 0x74, 0x52, 0xba, 0xee, 0x28, 0xb6, 0x56, 0x90, 0x59, 0xde, 0x92, 0x5f, 0x84, 0xd1, 0x87, 0xe2, 0x64, 0xce, 0xdc, 0x94, 0x3c, 0xb4, 0xf8, 0x01, 0x0a, + 0x86, 0x2f, 0xfe, 0x79, 0x03, 0x72, 0xfc, 0x26, 0x21, 0xc3, 0x1e, 0xec, 0x63, 0x29, 0x64, 0xcb, 0x5f, 0xcc, 0xb6, 0x78, 0xf7, 0xc8, 0xd1, 0xf8, 0x5c, 0xc4, 0x4b, 0xc0, 0xc3, 0x75, 0x3e, 0x46 }, + { 0x03, 0x4b, 0xb9, 0xd1, 0x50, 0xa3, 0x79, 0xbe, 0x74, 0xa3, 0xb5, 0xd8, 0x28, 0x1b, 0x6d, 0x72, 0x68, 0x0a, 0x9b, 0x19, 0xc9, 0x13, 0xc4, 0x04, 0x94, 0x0a, 0xcb, 0x72, 0xff, 0x7d, 0xb6, 0x9a, + 0x1c, 0xfd, 0xe4, 0xa3, 0x75, 0x13, 0x57, 0x36, 0xfe, 0x4a, 0xf6, 0xbc, 0xca, 0xd9, 0x34, 0x9b, 0xef, 0x90, 0x02, 0xd9, 0xbd, 0xdd, 0x6f, 0x22, 0x54, 0x36, 0xb2, 0x3f, 0x22, 0x65, 0xef, 0xe7 }, + { 0x04, 0xd4, 0x43, 0xe8, 0x8c, 0xc4, 0xfb, 0xe5, 0x55, 0xd0, 0xa4, 0xea, 0x20, 0xf8, 0xe1, 0x8f, 0xc2, 0xbc, 0x1f, 0x55, 0xf1, 0x8d, 0xda, 0xc0, 0x85, 0xa4, 0xef, 0x36, 0x97, 0x22, 0x8b, 0x8e, + 0x77, 0x4c, 0x1a, 0xa4, 0xa0, 0x6f, 0xe1, 0xdc, 0x32, 0x47, 0xc4, 0x3a, 0xd8, 0x8a, 0xbd, 0x19, 0x30, 0x1c, 0x96, 0x7a, 0xb2, 0x23, 0x7c, 0x16, 0x03, 0xa7, 0x4f, 0xfd, 0xa6, 0x50, 0xd9, 0xf7 }, + { 0xdf, 0xc2, 0x59, 0xd2, 0xa9, 0x9b, 0x1e, 0xca, 0xf0, 0x39, 0x2f, 0xf8, 0xc2, 0xf3, 0x91, 0x55, 0x1b, 0xba, 0x81, 0x3a, 0x67, 0x1a, 0xd4, 0xf4, 0xb0, 0x9f, 0xb6, 0x18, 0x38, 0x65, 0x3e, 0x67, + 0xa0, 0x37, 0xc2, 0x9a, 0xc7, 0xee, 0x72, 0x8e, 0x13, 0x64, 0xd1, 0x0a, 0xda, 0xbd, 0x8d, 0xa4, 0x28, 0x55, 0x3a, 0x2c, 0x78, 0x41, 0xc6, 0xfc, 0x1c, 0x0f, 0xf8, 0xd7, 0x5f, 0xe6, 0xde, 0x0b, + 0xd5, 0xc0, 0xaa, 0x2c, 0x5c, 0xac, 0x46, 0xeb, 0xa4, 0x35, 0x2a, 0xab, 0x00, 0x2e, 0xc0, 0x8b, 0x42, 0x65, 0x2f, 0x2f, 0x13, 0x84, 0x60, 0x15, 0xa3, 0x69, 0xee, 0xab, 0x0e, 0x50, 0xbf, 0x5f }, + { 0xc1, 0xb0, 0xac, 0x4c, 0xfa, 0x62, 0x52, 0x22, 0xae, 0x8c, 0x94, 0x38, 0xd9, 0x6e, 0x10, 0x94, 0xe7, 0xaa, 0xc0, 0x92, 0x93, 0x06, 0x55, 0xf9, 0x2e, 0xd9, 0x10, 0x4d, 0xcb, 0x82, 0x19, 0x1f, + 0x27, 0x16, 0x81, 0xdd, 0xea, 0x7a, 0xa8, 0xce, 0x5a, 0xdd, 0x37, 0x77, 0x24, 0x57, 0xfb, 0x40, 0x3d, 0x1b, 0x48, 0x88, 0xda, 0xce, 0xe8, 0xd2, 0xed, 0xe0, 0x6e, 0x29, 0xeb, 0xdb, 0x95, 0x09, + 0xd5, 0xc0, 0xaa, 0x2c, 0x5c, 0xac, 0x46, 0xeb, 0xa4, 0x35, 0x2a, 0xab, 0x00, 0x2e, 0xc0, 0x8b, 0x42, 0x65, 0x2f, 0x2f, 0x13, 0x84, 0x60, 0x15, 0xa3, 0x69, 0xee, 0xab, 0x0e, 0x50, 0xbf, 0x5f } }, + { { 0x3a, 0x79, 0x39, 0x60, 0xe9, 0x93, 0xad, 0x78, 0xf9, 0x0b, 0x99, 0x64, 0x71, 0x76, 0xad, 0xdc, 0x63, 0xa3, 0x38, 0xbf, 0x0a, 0x36, 0x22, 0xcf, 0x4f, 0x84, 0x3e, 0x34, 0xaf, 0x0b, 0xd4, 0x5c, + 0xc0, 0xa4, 0x01, 0x7c, 0x07, 0xc3, 0xb4, 0xcb, 0xdb, 0x39, 0xdd, 0x39, 0xc7, 0x5c, 0xbd, 0xcf, 0x61, 0x8b, 0x72, 0x74, 0xd6, 0x85, 0xdc, 0x5c, 0x08, 0x93, 0x6d, 0xe6, 0xf1, 0xeb, 0xb9, 0x7c }, + { 0x71, 0x12, 0x20, 0xbb, 0x37, 0xa6, 0xd8, 0x71, 0xf7, 0x58, 0xaa, 0xbd, 0x30, 0xfb, 0xac, 0x94, 0x62, 0x45, 0xf0, 0x1a, 0xc3, 0x4a, 0x07, 0x78, 0x6d, 0x17, 0xf5, 0x8d, 0x69, 0x3d, 0x2e, 0x15, + 0x96, 0x48, 0x1a, 0xb0, 0x7e, 0xdd, 0xf5, 0x2d, 0xe1, 0x56, 0xfc, 0xe9, 0x26, 0x91, 0x51, 0xfe, 0x5e, 0x2a, 0xdc, 0x23, 0x89, 0x09, 0x14, 0xe6, 0x17, 0xa9, 0x14, 0x8c, 0x8c, 0xe8, 0xe3, 0x71 }, + { 0xe4, 0xd0, 0xa7, 0x5a, 0xce, 0x93, 0x1d, 0x55, 0xa2, 0x3d, 0xdd, 0x7e, 0x10, 0x66, 0x6d, 0xc6, 0x5c, 0x87, 0x9f, 0x7a, 0x52, 0x5e, 0x76, 0x3f, 0x09, 0x9e, 0xe5, 0x8e, 0x60, 0x39, 0x5e, 0x3c, + 0x28, 0x31, 0xa4, 0x12, 0x39, 0xfd, 0xba, 0xda, 0xc8, 0x59, 0xdd, 0x5b, 0x26, 0x78, 0x8f, 0x33, 0xd2, 0xc8, 0x22, 0x77, 0x49, 0xcf, 0x34, 0x61, 0xbe, 0x7a, 0xa6, 0x31, 0xbe, 0xe5, 0xab, 0xc2 }, + { 0x60, 0xf5, 0x52, 0xbd, 0xb1, 0x9e, 0x06, 0xa3, 0x94, 0xad, 0xe0, 0x82, 0x33, 0x7c, 0x41, 0x17, 0x5b, 0x8a, 0xbc, 0x7c, 0xce, 0xd1, 0x7e, 0xfd, 0x39, 0x17, 0xfd, 0x90, 0x5a, 0x53, 0x89, 0x27, + 0x9f, 0x27, 0x7a, 0x08, 0xb2, 0x66, 0xda, 0xb5, 0xbf, 0x3b, 0x80, 0xe2, 0x1a, 0x30, 0x80, 0x45, 0x13, 0xf3, 0x4b, 0x0c, 0x4a, 0xe9, 0x0a, 0x6e, 0xf2, 0x3e, 0xa3, 0x70, 0x3d, 0x89, 0xd3, 0xb2 }, + { 0x23, 0x41, 0x08, 0x8d, 0xa8, 0x0b, 0x6a, 0xe0, 0x65, 0xb1, 0x42, 0x50, 0x49, 0xdd, 0xd3, 0xe8, 0x89, 0x13, 0x7a, 0x04, 0xf0, 0xd6, 0x2f, 0x6e, 0x73, 0xcd, 0xdc, 0x10, 0xbb, 0x02, 0x6b, 0xa2, + 0x25, 0x58, 0xa3, 0x08, 0x37, 0x7c, 0x8b, 0x1f, 0x4a, 0x81, 0x38, 0x88, 0xbd, 0xf4, 0x4f, 0x24, 0xe8, 0xd6, 0x9f, 0x2f, 0x13, 0xeb, 0x79, 0x60, 0x80, 0x90, 0x52, 0x6b, 0x8e, 0xed, 0xcb, 0x77 }, + { 0x5b, 0x88, 0x63, 0xaf, 0xf9, 0xe2, 0x44, 0x23, 0xc8, 0x02, 0xe0, 0x22, 0x15, 0x3d, 0x2a, 0xb7, 0x40, 0x76, 0xe8, 0x95, 0xfd, 0xa9, 0xe3, 0x85, 0x94, 0xa3, 0xbb, 0xce, 0x61, 0x19, 0x0d, 0xe2, + 0x95, 0xdf, 0x81, 0x11, 0x53, 0x77, 0xcd, 0xf2, 0xd8, 0x4f, 0xbf, 0x19, 0x6a, 0x3d, 0x4b, 0xda, 0xa4, 0x56, 0xa4, 0xcd, 0x9d, 0x4f, 0x52, 0x53, 0x7d, 0xd8, 0xac, 0xe0, 0xfb, 0x9a, 0x71, 0x0c, + 0x59, 0xf9, 0x0b, 0x03, 0xf1, 0x7b, 0xaf, 0x33, 0xc3, 0xe5, 0x1e, 0x8d, 0x4f, 0xbe, 0x21, 0xed, 0x6b, 0x15, 0xdd, 0xd2, 0xeb, 0x7c, 0xe4, 0x59, 0x6c, 0xf9, 0x91, 0xc1, 0x3a, 0x3a, 0xb6, 0x2b }, + { 0x5e, 0x54, 0xe5, 0x1b, 0x3d, 0x2c, 0x00, 0x80, 0xdd, 0xe4, 0x10, 0x50, 0x98, 0xb6, 0x0e, 0x3a, 0xf7, 0xde, 0x67, 0x2c, 0x8e, 0x7b, 0xb4, 0x73, 0x0b, 0xc7, 0x12, 0xb0, 0x66, 0x6b, 0x3b, 0x99, + 0xd9, 0x33, 0x78, 0x5f, 0x45, 0xe5, 0xec, 0x15, 0x02, 0xfa, 0x8b, 0x86, 0xfd, 0xe0, 0xb7, 0x84, 0x72, 0xf2, 0x68, 0x5c, 0xd6, 0x2e, 0x37, 0xe9, 0x49, 0x32, 0x2f, 0xcd, 0xcd, 0x1e, 0x99, 0x0f, + 0x59, 0xf9, 0x0b, 0x03, 0xf1, 0x7b, 0xaf, 0x33, 0xc3, 0xe5, 0x1e, 0x8d, 0x4f, 0xbe, 0x21, 0xed, 0x6b, 0x15, 0xdd, 0xd2, 0xeb, 0x7c, 0xe4, 0x59, 0x6c, 0xf9, 0x91, 0xc1, 0x3a, 0x3a, 0xb6, 0x2b } }, + { { 0xfc, 0xb9, 0x4e, 0x4e, 0x11, 0xfe, 0xe1, 0xc5, 0xc7, 0x49, 0x54, 0xd2, 0x2f, 0x13, 0x34, 0x7c, 0x91, 0x7d, 0x98, 0x43, 0xe4, 0xb7, 0x48, 0xea, 0xe8, 0x26, 0xcb, 0x26, 0x1f, 0xe4, 0x99, 0x10, + 0xb9, 0x34, 0xc2, 0xac, 0xa3, 0x2c, 0xbd, 0x9e, 0x80, 0xd4, 0x12, 0x3b, 0xb3, 0xf0, 0x01, 0xae, 0x91, 0x9f, 0xba, 0x77, 0x32, 0x4d, 0x9d, 0xac, 0x1f, 0x8d, 0xad, 0xa7, 0x46, 0x44, 0x85, 0xfb }, + { 0x65, 0x05, 0x0b, 0xd2, 0x41, 0xd3, 0x58, 0x2a, 0x14, 0xbc, 0x7b, 0x15, 0x4a, 0x6a, 0x6a, 0x18, 0x71, 0x09, 0x25, 0x33, 0xac, 0x73, 0x53, 0xab, 0xd9, 0x0d, 0x8d, 0xdf, 0x95, 0x59, 0x7e, 0x02, + 0x4c, 0x03, 0x11, 0x5c, 0xdc, 0x80, 0x19, 0xd5, 0x13, 0x66, 0x7f, 0xf7, 0xd7, 0x23, 0x18, 0x40, 0x84, 0x16, 0x6b, 0x52, 0x82, 0x96, 0x05, 0x1b, 0xfa, 0xcb, 0x4b, 0x77, 0x00, 0x12, 0xa0, 0x28 }, + { 0x13, 0xe0, 0x16, 0x1e, 0x24, 0x24, 0xe9, 0xde, 0x9c, 0x86, 0xa9, 0xcf, 0x02, 0x96, 0xdf, 0x8c, 0x64, 0xcb, 0x3d, 0x7d, 0x8a, 0x2a, 0x73, 0x18, 0x20, 0xc8, 0xb0, 0xac, 0x10, 0xa0, 0x52, 0x0c, + 0x6c, 0x17, 0xd9, 0xbd, 0x3c, 0x3e, 0xe5, 0x0c, 0x4a, 0xdb, 0x59, 0xcc, 0x59, 0x15, 0x08, 0x1e, 0xfe, 0xaa, 0xe3, 0xd6, 0xa1, 0x37, 0xd6, 0xd5, 0x6d, 0x8e, 0xcd, 0x57, 0xa9, 0x81, 0xb3, 0x43 }, + { 0x46, 0x28, 0x2b, 0xa0, 0xe5, 0xe3, 0xf0, 0x72, 0xa7, 0xbc, 0x8d, 0xec, 0x45, 0x31, 0x6e, 0xdb, 0xb2, 0x4b, 0x20, 0xbf, 0x64, 0x74, 0x26, 0x70, 0x9b, 0xd6, 0xd3, 0x7f, 0x9f, 0xc1, 0x59, 0x03, + 0x2d, 0xda, 0x6f, 0xaa, 0x7c, 0x92, 0xc6, 0xe0, 0xe8, 0xaa, 0x1e, 0x26, 0xf0, 0x1e, 0xcc, 0xef, 0x6d, 0x87, 0x04, 0x3c, 0xed, 0x52, 0x15, 0xb3, 0x9f, 0x01, 0x4e, 0xe3, 0x3c, 0xb6, 0xbb, 0xac }, + { 0x86, 0x1a, 0x25, 0x8e, 0x41, 0x85, 0xf9, 0xba, 0x98, 0x15, 0xb1, 0xec, 0x50, 0xb4, 0xd0, 0xab, 0x55, 0x54, 0xbb, 0x3b, 0x61, 0xfc, 0x54, 0xf3, 0x09, 0xea, 0xaa, 0x6e, 0xbf, 0x03, 0xc3, 0x58, + 0x1d, 0x24, 0xb5, 0xd5, 0x45, 0x5a, 0x7a, 0x14, 0xc3, 0x6a, 0xa9, 0xd8, 0x6f, 0x41, 0xc3, 0xb4, 0x9a, 0x05, 0x71, 0xbc, 0x23, 0x67, 0xc2, 0xa8, 0xf5, 0x7b, 0x69, 0xa5, 0xe1, 0x7a, 0x35, 0x1d }, + { 0x3b, 0xf5, 0xa8, 0xc0, 0x2a, 0x7d, 0x85, 0x88, 0xd4, 0xf4, 0x26, 0xd3, 0xf4, 0xe3, 0x52, 0x35, 0x37, 0x06, 0x1e, 0x71, 0xc2, 0x3b, 0x7b, 0xeb, 0xf0, 0x07, 0x30, 0x6b, 0x37, 0x31, 0xb9, 0x27, + 0xd8, 0x0b, 0x17, 0xae, 0xff, 0xd4, 0x7c, 0x59, 0xd7, 0x2d, 0xea, 0xcb, 0x92, 0x2f, 0x93, 0xc7, 0xd7, 0xc3, 0xaf, 0x75, 0x73, 0x6a, 0x3f, 0x89, 0xe5, 0x13, 0x0c, 0x28, 0x47, 0xf4, 0xa4, 0x07, + 0xfb, 0xd9, 0x77, 0xb4, 0x1e, 0xb2, 0x70, 0xca, 0x85, 0x22, 0x58, 0xc6, 0x0b, 0x19, 0xc2, 0xa5, 0xba, 0xc3, 0xc9, 0xb6, 0x4a, 0xdb, 0x7d, 0x4d, 0x66, 0xde, 0xeb, 0x8c, 0x1a, 0x23, 0xb8, 0x4c }, + { 0x8c, 0x57, 0x0e, 0x9f, 0x0a, 0xb2, 0xf4, 0x07, 0xdd, 0x7b, 0x46, 0xf8, 0xa0, 0xb1, 0x33, 0x4c, 0x2b, 0x1e, 0x1a, 0xe0, 0x28, 0x17, 0x14, 0xba, 0x14, 0x06, 0x40, 0x1f, 0x30, 0x0a, 0x19, 0xcd, + 0xe7, 0xca, 0xfb, 0xdb, 0xb9, 0x76, 0xf8, 0x8a, 0x81, 0x3d, 0x03, 0x86, 0x7e, 0x66, 0x75, 0x1d, 0xec, 0xff, 0x6b, 0xa7, 0xea, 0x4c, 0x8c, 0x60, 0xd2, 0x1f, 0x72, 0x11, 0x4c, 0x5d, 0xeb, 0x01, + 0xfb, 0xd9, 0x77, 0xb4, 0x1e, 0xb2, 0x70, 0xca, 0x85, 0x22, 0x58, 0xc6, 0x0b, 0x19, 0xc2, 0xa5, 0xba, 0xc3, 0xc9, 0xb6, 0x4a, 0xdb, 0x7d, 0x4d, 0x66, 0xde, 0xeb, 0x8c, 0x1a, 0x23, 0xb8, 0x4c } }, + { { 0x05, 0x64, 0x16, 0x53, 0xbb, 0xb2, 0x6e, 0x81, 0xfc, 0xe6, 0xec, 0xc8, 0x0c, 0xc1, 0x75, 0x59, 0x23, 0xe2, 0x4b, 0xd8, 0x6a, 0x70, 0x34, 0x50, 0x37, 0xc6, 0xc2, 0xbd, 0x27, 0xfd, 0xad, 0x4c, + 0xee, 0xe4, 0xf7, 0xfc, 0x91, 0x05, 0x48, 0x3c, 0xd4, 0x09, 0x78, 0x00, 0xce, 0x15, 0x37, 0xdc, 0xe7, 0xce, 0x48, 0x09, 0x3e, 0x7f, 0x01, 0x9b, 0x03, 0xc8, 0x2f, 0x9b, 0xe6, 0x42, 0xe1, 0x71 }, + { 0x64, 0xbf, 0x63, 0x91, 0xe5, 0x3e, 0x90, 0x89, 0x96, 0xea, 0x59, 0x51, 0x60, 0x7b, 0x5f, 0xfe, 0x0f, 0x76, 0x86, 0x19, 0x45, 0x82, 0xd9, 0x5e, 0x1a, 0xd1, 0xf6, 0x04, 0xc6, 0xaa, 0x71, 0xda, + 0x80, 0xed, 0x75, 0x51, 0xc8, 0x9a, 0x27, 0x09, 0xc3, 0x50, 0xe4, 0x14, 0xa1, 0xc3, 0xf8, 0x3a, 0x6c, 0x84, 0xff, 0x87, 0xd5, 0xf0, 0xb0, 0x3c, 0x5a, 0x57, 0x14, 0x90, 0xc7, 0x31, 0xf8, 0x47 }, + { 0x88, 0x7d, 0xcc, 0x81, 0x2b, 0xbb, 0x7e, 0x96, 0xbe, 0x78, 0xe1, 0xb1, 0xf2, 0xed, 0x6f, 0xd8, 0xff, 0xbd, 0x7f, 0x8e, 0xe5, 0xeb, 0x7f, 0x7b, 0xca, 0xaf, 0x9b, 0x08, 0x1a, 0x77, 0x69, 0x1d, + 0xc2, 0xa4, 0x7c, 0x4d, 0xa6, 0x74, 0x8e, 0x33, 0x24, 0xff, 0x43, 0xe1, 0x8c, 0x59, 0xae, 0x5f, 0x95, 0xa4, 0x35, 0x9e, 0x61, 0xb8, 0xcc, 0x4c, 0x87, 0xb9, 0x76, 0x53, 0x20, 0xa3, 0xf3, 0xf5 }, + { 0x13, 0x2a, 0xcc, 0x07, 0xb1, 0x5f, 0xc7, 0xf1, 0x08, 0x0e, 0x7d, 0x7e, 0x26, 0x56, 0xd8, 0x16, 0x9c, 0xae, 0xac, 0xc4, 0xf5, 0x9c, 0x15, 0x67, 0xae, 0xc4, 0xcc, 0x3f, 0xc0, 0xaf, 0x53, 0x28, + 0x1f, 0x65, 0x14, 0xe5, 0x7f, 0x0c, 0xf5, 0x7a, 0xe3, 0x93, 0xc1, 0xa3, 0xd1, 0x4a, 0x09, 0x7d, 0x24, 0xab, 0x22, 0xc4, 0xc4, 0xce, 0x85, 0x37, 0x86, 0xa8, 0x9c, 0x39, 0x33, 0xba, 0x1b, 0x83 }, + { 0x6d, 0x3e, 0x92, 0x5a, 0xa8, 0xfa, 0xe6, 0x71, 0x98, 0xa8, 0x82, 0x38, 0xcc, 0xed, 0xd6, 0x92, 0x7e, 0x3e, 0xcb, 0xb2, 0x82, 0x92, 0x7a, 0x56, 0x9e, 0xd6, 0x29, 0x45, 0x42, 0x04, 0x76, 0x82, + 0xa5, 0xfc, 0xd9, 0x0c, 0x12, 0x4c, 0x98, 0x04, 0x2a, 0x3a, 0x98, 0x01, 0xb8, 0x62, 0xe8, 0xe6, 0x7c, 0x51, 0xe3, 0x7d, 0x97, 0xf5, 0x45, 0xb4, 0x13, 0xdf, 0x15, 0x68, 0xc3, 0x00, 0x75, 0x40 }, + { 0x7e, 0x89, 0x3d, 0x7c, 0x78, 0x36, 0x3c, 0x85, 0xda, 0xb6, 0x9b, 0x6d, 0xbc, 0x52, 0x7d, 0xc6, 0xaa, 0xfd, 0x90, 0x62, 0xe4, 0xc4, 0x1a, 0x5a, 0x2e, 0xa1, 0x57, 0xd7, 0xda, 0x57, 0xf4, 0x58, + 0xc5, 0x23, 0x61, 0x21, 0xe1, 0x93, 0xfa, 0x06, 0x22, 0xed, 0x41, 0x66, 0x24, 0x47, 0xb9, 0xed, 0xc8, 0x84, 0x25, 0x28, 0x39, 0xec, 0xfb, 0x29, 0xa1, 0xcd, 0xe1, 0x9d, 0x02, 0x48, 0x6f, 0x0a, + 0xe2, 0x9f, 0x98, 0xfd, 0x3d, 0x18, 0xa1, 0x24, 0x9c, 0xc6, 0x75, 0xb8, 0x99, 0x76, 0x2a, 0xa4, 0x9e, 0xb1, 0x97, 0x2d, 0x1c, 0x99, 0x65, 0x5f, 0x1f, 0xda, 0x14, 0x4f, 0x10, 0x49, 0xf1, 0x7a }, + { 0x2c, 0xec, 0x27, 0x63, 0xd2, 0x77, 0x14, 0x2d, 0x01, 0x18, 0x10, 0xe0, 0x23, 0x1b, 0xa2, 0x25, 0x61, 0xd4, 0x52, 0xd9, 0x90, 0xde, 0x97, 0x7e, 0xb8, 0xfa, 0x38, 0x25, 0xf2, 0x91, 0x07, 0x3e, + 0xc4, 0xa9, 0x3e, 0xb5, 0x67, 0x02, 0x28, 0x94, 0x5c, 0x34, 0xa1, 0x0a, 0x5c, 0x54, 0x53, 0xd9, 0xb4, 0xc4, 0x5a, 0x8e, 0x57, 0x18, 0xc3, 0x35, 0xea, 0x47, 0x75, 0xe0, 0x44, 0x01, 0x71, 0x09, + 0xe2, 0x9f, 0x98, 0xfd, 0x3d, 0x18, 0xa1, 0x24, 0x9c, 0xc6, 0x75, 0xb8, 0x99, 0x76, 0x2a, 0xa4, 0x9e, 0xb1, 0x97, 0x2d, 0x1c, 0x99, 0x65, 0x5f, 0x1f, 0xda, 0x14, 0x4f, 0x10, 0x49, 0xf1, 0x7a } }, + { { 0x41, 0x10, 0xd9, 0x7f, 0xb8, 0x83, 0x9e, 0x42, 0x43, 0x7a, 0xb0, 0x6d, 0xa6, 0xcf, 0xa5, 0x7a, 0x50, 0x93, 0x2d, 0x13, 0x94, 0x37, 0xa8, 0x92, 0x26, 0x1f, 0xad, 0xe0, 0x25, 0x19, 0x91, 0x62, + 0x28, 0xfb, 0x18, 0xbf, 0x89, 0xb0, 0x42, 0x80, 0x14, 0xcd, 0xd2, 0x72, 0x84, 0x1c, 0xfd, 0xe5, 0xc3, 0x71, 0x3c, 0x3f, 0x12, 0x5e, 0xdd, 0x53, 0x39, 0xf6, 0x4b, 0x9f, 0xb3, 0x5c, 0xe3, 0x15 }, + { 0xd0, 0xc7, 0x18, 0x4d, 0x68, 0x9f, 0xdd, 0xec, 0x81, 0xf8, 0xc6, 0x0e, 0x83, 0x43, 0x23, 0x3d, 0xfc, 0xf3, 0x66, 0x55, 0xa8, 0x65, 0x8b, 0xd7, 0x9b, 0x3c, 0x74, 0x23, 0xcd, 0xae, 0x60, 0xe7, + 0x61, 0xed, 0x2c, 0x7e, 0xe7, 0xa7, 0x63, 0x7d, 0x72, 0x47, 0x6a, 0x33, 0x1c, 0xaa, 0x81, 0xba, 0x6f, 0xd4, 0x00, 0xe7, 0xa9, 0x58, 0xb2, 0xad, 0xee, 0x3f, 0x9c, 0x70, 0xff, 0x2f, 0x13, 0x6f }, + { 0x56, 0x7b, 0x19, 0x66, 0x42, 0x9a, 0x99, 0x51, 0x23, 0x4f, 0xb6, 0xe7, 0xcf, 0x98, 0xff, 0x20, 0x5a, 0xc3, 0x0e, 0x36, 0xc9, 0xc6, 0x20, 0x25, 0x0c, 0x56, 0x98, 0xfb, 0xbd, 0xd6, 0x66, 0x4f, + 0x6f, 0x94, 0x85, 0x8a, 0x35, 0xf3, 0x50, 0xad, 0x87, 0xde, 0x95, 0x9e, 0xae, 0x2a, 0xd8, 0xdd, 0x78, 0x87, 0x96, 0x2b, 0xe0, 0x12, 0x95, 0xd9, 0x3b, 0xb2, 0x2a, 0x06, 0xe2, 0xf0, 0x06, 0xd4 }, + { 0x42, 0x24, 0xdd, 0x0a, 0xd1, 0x11, 0x31, 0x7e, 0x56, 0x45, 0xb0, 0x0e, 0x86, 0xc1, 0x5d, 0x8c, 0x03, 0x01, 0xb8, 0x33, 0x20, 0xbd, 0x08, 0x10, 0xe5, 0x70, 0x92, 0x2b, 0x5b, 0x86, 0xd3, 0x50, + 0x4c, 0x1e, 0xe3, 0xd1, 0x2a, 0x4e, 0x40, 0x02, 0x19, 0x0b, 0xf6, 0x91, 0xd9, 0x9e, 0xaa, 0x54, 0x7c, 0x3d, 0xba, 0xc5, 0x5a, 0x9e, 0xb2, 0xbb, 0x4e, 0x0d, 0x5b, 0xdd, 0x90, 0xc9, 0x7b, 0xc2 }, + { 0x54, 0x95, 0xd5, 0xdc, 0x7e, 0x7e, 0xec, 0xd4, 0x67, 0x08, 0xdc, 0x58, 0xa9, 0x80, 0x8a, 0x03, 0x6a, 0xf8, 0x40, 0xca, 0x0d, 0x5b, 0x6c, 0xe4, 0xc9, 0x71, 0xa5, 0xaf, 0x2a, 0xaa, 0xe8, 0x95, + 0x45, 0xe7, 0xe2, 0xc3, 0x47, 0x84, 0xc6, 0xbe, 0xe5, 0x65, 0xaf, 0xcd, 0x7c, 0x20, 0x5f, 0x8b, 0x19, 0x61, 0xe4, 0xc9, 0xc1, 0x86, 0xa5, 0x6f, 0x96, 0xf3, 0x9c, 0x13, 0x28, 0x1b, 0xcf, 0x07 }, + { 0xc4, 0x7f, 0xf2, 0x6f, 0xcc, 0x4a, 0xf8, 0xa4, 0x1f, 0x1d, 0x6e, 0x5e, 0x30, 0xb2, 0x99, 0x8f, 0x5d, 0x7c, 0x26, 0x1c, 0x52, 0x6f, 0xd0, 0x33, 0xa7, 0xf8, 0xca, 0x2a, 0xc3, 0x8c, 0xa8, 0xd1, + 0x50, 0x4f, 0xa7, 0xe8, 0xf2, 0x10, 0x4c, 0xcd, 0x8a, 0x31, 0x03, 0xc8, 0x93, 0x2c, 0xd7, 0xe4, 0x21, 0xdb, 0xa2, 0x62, 0x7b, 0x1f, 0x28, 0x14, 0x69, 0x7e, 0x87, 0xac, 0xf9, 0xb4, 0x97, 0x00, + 0x62, 0x86, 0x14, 0xd7, 0xe4, 0x65, 0xdd, 0x9e, 0x1c, 0x64, 0x5f, 0x3e, 0xef, 0xfe, 0xa6, 0x60, 0x68, 0x91, 0x94, 0x8a, 0x1c, 0x89, 0xae, 0xe4, 0xcf, 0x3a, 0xdd, 0xc0, 0xb4, 0x47, 0xe8, 0x8f }, + { 0x12, 0x80, 0x00, 0xda, 0xce, 0xc4, 0x80, 0x8f, 0xa9, 0xa1, 0x5d, 0x98, 0x7d, 0x2c, 0xb2, 0x9c, 0x71, 0xde, 0x62, 0x89, 0x6a, 0xe1, 0x92, 0xd7, 0x96, 0xdc, 0xcd, 0xc8, 0x08, 0x0e, 0x48, 0xbf, + 0x2a, 0x53, 0x72, 0x90, 0x31, 0x71, 0x49, 0x02, 0xda, 0x4e, 0x19, 0x05, 0x10, 0xcb, 0x41, 0x97, 0x44, 0xdc, 0x2d, 0x1e, 0x48, 0xe5, 0x0e, 0x41, 0x9d, 0x7d, 0x03, 0xa3, 0xe2, 0x65, 0xd4, 0x01, + 0x62, 0x86, 0x14, 0xd7, 0xe4, 0x65, 0xdd, 0x9e, 0x1c, 0x64, 0x5f, 0x3e, 0xef, 0xfe, 0xa6, 0x60, 0x68, 0x91, 0x94, 0x8a, 0x1c, 0x89, 0xae, 0xe4, 0xcf, 0x3a, 0xdd, 0xc0, 0xb4, 0x47, 0xe8, 0x8f } }, + { { 0x00, 0x4b, 0x0b, 0xf5, 0x1f, 0x07, 0x1e, 0x23, 0xe3, 0x93, 0x7b, 0x31, 0x41, 0x2a, 0x0a, 0x50, 0x35, 0xe2, 0xbb, 0xfe, 0x51, 0x77, 0x6c, 0xc9, 0xc5, 0x13, 0xb9, 0x87, 0x79, 0x65, 0x68, 0x20, + 0xcc, 0x09, 0x90, 0xa9, 0xe4, 0xef, 0x9f, 0x1a, 0xe1, 0x69, 0x76, 0x14, 0x82, 0x42, 0x88, 0x4b, 0xdc, 0xe0, 0x10, 0x22, 0xe2, 0xd6, 0x36, 0x7c, 0x0b, 0xd9, 0x08, 0xea, 0xfa, 0xe4, 0xfd, 0x45 }, + { 0x57, 0x5c, 0x1e, 0x20, 0xb4, 0xae, 0x9e, 0x9d, 0x04, 0xfb, 0x1a, 0xd7, 0x23, 0xd8, 0x8a, 0x6b, 0x1b, 0xb2, 0xef, 0xa9, 0x06, 0x38, 0xbb, 0x9b, 0x43, 0x2e, 0xf1, 0x81, 0x0b, 0x76, 0xec, 0x20, + 0x46, 0x1b, 0xc4, 0x71, 0x19, 0x3e, 0x79, 0xe8, 0xcf, 0xea, 0xdc, 0x4b, 0x3f, 0x0b, 0xeb, 0x05, 0x13, 0x1a, 0x2c, 0xfe, 0x16, 0xe9, 0xf0, 0xc4, 0x9c, 0x41, 0xab, 0x45, 0x1b, 0xba, 0x05, 0xec }, + { 0x06, 0x0b, 0x73, 0xec, 0x30, 0x74, 0x0d, 0x8d, 0x13, 0x4b, 0xef, 0xac, 0x3b, 0x05, 0xb6, 0xed, 0x2b, 0x05, 0xd1, 0xa7, 0x65, 0xb0, 0xcb, 0x69, 0x00, 0xeb, 0x47, 0xe3, 0x1c, 0x07, 0x8b, 0x15, + 0xbf, 0x69, 0xff, 0x27, 0xb4, 0xdb, 0x77, 0xaf, 0xe9, 0x9a, 0xfb, 0xb2, 0x28, 0xa4, 0xf9, 0x05, 0xe4, 0x3c, 0x66, 0x56, 0x00, 0x1a, 0x2c, 0x41, 0xf2, 0xe1, 0x11, 0x09, 0xfa, 0xe1, 0x50, 0x49 }, + { 0xbc, 0x4d, 0x6f, 0x75, 0x79, 0x77, 0x64, 0x6b, 0xec, 0xac, 0x1a, 0x26, 0x73, 0x9c, 0xf3, 0xf1, 0x4d, 0x79, 0xbe, 0x6f, 0x0c, 0x07, 0x22, 0xd1, 0xa1, 0x31, 0x75, 0xa8, 0x9c, 0xb6, 0x00, 0x63, + 0x0d, 0x40, 0x17, 0xec, 0x83, 0xda, 0x82, 0x2c, 0x3b, 0xfd, 0x90, 0xe3, 0xbc, 0xc2, 0x2c, 0xf5, 0x3e, 0x41, 0xe9, 0x98, 0x57, 0xa2, 0xb7, 0xce, 0x5f, 0x31, 0xbb, 0x0b, 0x05, 0x61, 0x0f, 0x55 }, + { 0xb7, 0xab, 0xb2, 0x84, 0xf1, 0x67, 0x24, 0x16, 0x61, 0xe9, 0x20, 0x33, 0x0b, 0xff, 0x22, 0x61, 0x70, 0xa0, 0x5d, 0xf6, 0xa8, 0x33, 0xc9, 0x30, 0x73, 0xe5, 0x89, 0x36, 0x59, 0xea, 0xa8, 0xe7, + 0x03, 0xf6, 0x14, 0xc1, 0x79, 0xb6, 0x42, 0xa5, 0xc8, 0x6c, 0xb8, 0x94, 0x29, 0x24, 0x00, 0x09, 0xb5, 0x54, 0x3f, 0xe1, 0x6b, 0xfb, 0x4d, 0x2d, 0xa9, 0x9a, 0x02, 0xa1, 0xa5, 0x09, 0xf4, 0xcb }, + { 0x92, 0xfa, 0x18, 0x84, 0x3e, 0xdb, 0xdf, 0x7d, 0x87, 0xd6, 0x2d, 0x07, 0x05, 0x2c, 0xba, 0xe4, 0x30, 0x76, 0xa2, 0xe8, 0x71, 0x3b, 0x1b, 0x93, 0x5b, 0xce, 0x2e, 0xec, 0x50, 0x6e, 0x4a, 0x0b, + 0x2d, 0xbe, 0xa3, 0x76, 0x92, 0xf8, 0xc8, 0x4a, 0x71, 0x66, 0xec, 0xfa, 0x36, 0xc5, 0xdb, 0xab, 0x99, 0x9c, 0xbf, 0x99, 0x07, 0xe8, 0xfe, 0xf4, 0x2f, 0x90, 0x16, 0x5d, 0xdc, 0xbe, 0xfa, 0x08, + 0x93, 0xde, 0x13, 0xf5, 0x32, 0x45, 0x9a, 0xde, 0xa2, 0x5d, 0xb9, 0xe0, 0x38, 0x4c, 0x6a, 0xcc, 0x13, 0x46, 0x27, 0x28, 0xbf, 0xf8, 0x7a, 0x9c, 0x2e, 0xde, 0x6f, 0xfe, 0xe1, 0x86, 0x41, 0x79 }, + { 0xa7, 0x32, 0x52, 0x76, 0x4f, 0x3e, 0x1b, 0xab, 0x82, 0x18, 0x14, 0xe7, 0x42, 0x32, 0xb8, 0xa4, 0x98, 0xde, 0xa4, 0xd7, 0xae, 0x42, 0x84, 0xda, 0x71, 0xf7, 0x78, 0x40, 0x56, 0x94, 0x64, 0x49, + 0x34, 0x37, 0xeb, 0xe3, 0x05, 0x4c, 0xb9, 0xbb, 0xce, 0xb2, 0x72, 0xc0, 0x75, 0x1c, 0xc4, 0xd5, 0x1e, 0x3a, 0xc1, 0x43, 0xda, 0xd1, 0x81, 0x82, 0xa9, 0xd5, 0x0e, 0x0a, 0x5e, 0xc2, 0xd7, 0x04, + 0x93, 0xde, 0x13, 0xf5, 0x32, 0x45, 0x9a, 0xde, 0xa2, 0x5d, 0xb9, 0xe0, 0x38, 0x4c, 0x6a, 0xcc, 0x13, 0x46, 0x27, 0x28, 0xbf, 0xf8, 0x7a, 0x9c, 0x2e, 0xde, 0x6f, 0xfe, 0xe1, 0x86, 0x41, 0x79 } }, + { { 0xa3, 0xdf, 0x4a, 0xfd, 0xe6, 0x74, 0xb8, 0xeb, 0xed, 0xe7, 0x7e, 0xd2, 0xae, 0xf8, 0x40, 0x80, 0x3a, 0x55, 0x58, 0x1d, 0x6b, 0xa4, 0x32, 0x6c, 0x15, 0xbb, 0x67, 0xdf, 0x9e, 0xb5, 0x70, 0x4b, + 0x7f, 0x4d, 0xfe, 0x34, 0x42, 0x0c, 0x4d, 0xe3, 0x97, 0x87, 0x6d, 0x08, 0xe8, 0x4d, 0x8a, 0xa9, 0xbc, 0xbf, 0x1b, 0xb7, 0x66, 0x32, 0xf4, 0x7f, 0x93, 0xca, 0xa4, 0xd2, 0x8f, 0x02, 0x7b, 0xfa }, + { 0xea, 0xac, 0xdf, 0x25, 0x39, 0xf3, 0x28, 0xb6, 0xbe, 0xa8, 0x4a, 0x32, 0x59, 0x4b, 0x4f, 0xb5, 0xd2, 0xf7, 0xf5, 0x75, 0x43, 0x8b, 0xb3, 0x6a, 0x98, 0x8c, 0x14, 0xc9, 0x3f, 0x7e, 0x5c, 0x05, + 0xf0, 0xeb, 0x1d, 0xc5, 0xe6, 0x1b, 0x5d, 0x7f, 0x38, 0x5d, 0x9a, 0xbe, 0xc8, 0x97, 0x09, 0x65, 0x62, 0x88, 0x99, 0xda, 0x95, 0x13, 0x93, 0xd9, 0xa3, 0x19, 0x0a, 0xa7, 0x4a, 0xb2, 0x81, 0xa4 }, + { 0x6e, 0x70, 0x65, 0xaa, 0x1b, 0x16, 0xcb, 0xc1, 0x59, 0x6b, 0xc9, 0x4d, 0xd1, 0x0a, 0x9d, 0x8c, 0x76, 0x70, 0x3c, 0xc1, 0xc1, 0x66, 0xa6, 0x9f, 0xfc, 0xca, 0xb0, 0x3f, 0x0e, 0xe9, 0xa9, 0x36, + 0x09, 0x4f, 0x94, 0xf3, 0x32, 0x25, 0x34, 0xf6, 0xe4, 0xf9, 0x0b, 0x0c, 0xe6, 0xe0, 0x6d, 0x9e, 0xa5, 0x52, 0x82, 0x9c, 0xd4, 0x43, 0xa4, 0xd1, 0xd1, 0x63, 0x20, 0xce, 0xbc, 0x4f, 0x43, 0xdc }, + { 0x35, 0xd6, 0xc1, 0x68, 0xa6, 0xd7, 0xd3, 0x36, 0x82, 0x2a, 0x0f, 0x29, 0x3e, 0xd6, 0x15, 0x29, 0x19, 0x73, 0x14, 0x78, 0x87, 0x86, 0xca, 0x9f, 0x6e, 0x17, 0xea, 0xaf, 0x24, 0x37, 0xd6, 0xb4, + 0xb0, 0xee, 0x84, 0x90, 0x2d, 0x18, 0xbd, 0x26, 0xc3, 0xd4, 0x39, 0x4f, 0x45, 0xfa, 0x2f, 0x70, 0xf2, 0xe2, 0x2a, 0x2a, 0x5c, 0x65, 0x15, 0xcb, 0xaf, 0x92, 0x9a, 0xfc, 0x06, 0xe0, 0x8a, 0x1b }, + { 0x5d, 0xfa, 0xc0, 0x2b, 0xc3, 0x94, 0x19, 0xb4, 0xd6, 0x13, 0xe3, 0xcf, 0x91, 0xad, 0x8c, 0xe1, 0x97, 0x46, 0xfe, 0xea, 0x74, 0xe0, 0x0c, 0x03, 0xf7, 0x2e, 0x51, 0xa7, 0xf2, 0xbc, 0xce, 0xe8, + 0x6b, 0xfd, 0x2f, 0x54, 0x52, 0x12, 0x00, 0x8d, 0x95, 0x91, 0xc3, 0xf6, 0x25, 0xf8, 0x65, 0x6a, 0x9c, 0x79, 0x6b, 0x71, 0xc0, 0x0c, 0x29, 0xfb, 0xe7, 0x14, 0x9f, 0x2f, 0x1a, 0x07, 0x53, 0x50 }, + { 0xe9, 0xd4, 0x46, 0x0b, 0x51, 0x3f, 0xf1, 0xbe, 0x0a, 0x23, 0xa5, 0x38, 0xa0, 0xe3, 0x70, 0x14, 0x63, 0xf0, 0x94, 0xbb, 0x1c, 0x4f, 0x23, 0x05, 0x1b, 0x62, 0x40, 0x9b, 0xf9, 0x52, 0x1b, 0x41, + 0x51, 0x57, 0x2a, 0x99, 0x73, 0xda, 0xe1, 0xcf, 0xc5, 0x4c, 0x65, 0x3a, 0xc2, 0x9d, 0x73, 0xda, 0xc9, 0x59, 0xf1, 0xdf, 0xab, 0x2b, 0x27, 0xe1, 0x59, 0x8b, 0xa7, 0x48, 0xf9, 0x36, 0xcb, 0x08, + 0xe3, 0x5e, 0x1d, 0xdd, 0xf9, 0x20, 0x4f, 0x64, 0xa9, 0x26, 0x74, 0x97, 0xf2, 0x2d, 0x31, 0xac, 0x8c, 0x20, 0x77, 0x09, 0xa9, 0x8f, 0xed, 0x23, 0x77, 0x7e, 0xd7, 0x34, 0x93, 0x84, 0xe7, 0xaa }, + { 0xaa, 0xf7, 0x64, 0xdf, 0x34, 0x59, 0x1c, 0x2c, 0xbc, 0x47, 0x08, 0x6a, 0x25, 0xbf, 0x9d, 0x48, 0x54, 0xcf, 0xa0, 0x6c, 0xfc, 0xd4, 0x10, 0x39, 0x9f, 0x64, 0x46, 0xce, 0xd9, 0x95, 0x28, 0x89, + 0xdf, 0x94, 0x5e, 0x74, 0x0b, 0x55, 0x46, 0x82, 0xd9, 0x3d, 0x82, 0x97, 0x7d, 0xd0, 0x3e, 0xd7, 0xf6, 0x6f, 0xaa, 0x97, 0x3e, 0xdf, 0xa7, 0xde, 0xe3, 0xc5, 0xaf, 0xd3, 0xa0, 0x5a, 0x30, 0x0d, + 0xe3, 0x5e, 0x1d, 0xdd, 0xf9, 0x20, 0x4f, 0x64, 0xa9, 0x26, 0x74, 0x97, 0xf2, 0x2d, 0x31, 0xac, 0x8c, 0x20, 0x77, 0x09, 0xa9, 0x8f, 0xed, 0x23, 0x77, 0x7e, 0xd7, 0x34, 0x93, 0x84, 0xe7, 0xaa } }, + { { 0x96, 0x4e, 0xf2, 0x1e, 0x3a, 0xe5, 0x77, 0xbf, 0xa7, 0x1c, 0x3d, 0x66, 0x08, 0x06, 0xca, 0x55, 0x43, 0x7a, 0x08, 0xf8, 0xff, 0x55, 0xb3, 0xbc, 0x9a, 0x83, 0x9a, 0x2e, 0xe6, 0x97, 0x14, 0x32, + 0x36, 0x57, 0x5c, 0xa4, 0x04, 0x78, 0xb1, 0x92, 0xf4, 0x23, 0x94, 0xe6, 0x2a, 0xef, 0xd4, 0xe7, 0xc4, 0x02, 0x9f, 0xa9, 0x79, 0x77, 0x61, 0x90, 0xd6, 0xdb, 0x6e, 0x28, 0x7e, 0xc0, 0x1d, 0x70 }, + { 0xc5, 0xd1, 0x5c, 0x34, 0x15, 0xa9, 0x1e, 0x42, 0x2a, 0x1b, 0x0d, 0xf0, 0x56, 0x83, 0x10, 0xc3, 0xc9, 0x21, 0xfd, 0x05, 0xfa, 0x51, 0x0e, 0x11, 0x28, 0xcc, 0x84, 0xac, 0x35, 0xb5, 0xd8, 0xc8, + 0x5c, 0x80, 0x11, 0x1f, 0x60, 0x1c, 0x72, 0x25, 0x82, 0x45, 0xb5, 0x4f, 0x66, 0x6b, 0x52, 0xb1, 0xf7, 0x28, 0x0f, 0x80, 0x76, 0x44, 0xdc, 0x15, 0x70, 0x39, 0xe9, 0xaf, 0xc7, 0x0a, 0xa0, 0x43 }, + { 0xff, 0x20, 0x5e, 0x3b, 0x75, 0xe9, 0x38, 0x7c, 0xa3, 0x5c, 0x8b, 0x1a, 0xec, 0x17, 0x8d, 0xf0, 0xef, 0xb3, 0x53, 0x9b, 0x16, 0xa9, 0x44, 0xf9, 0x34, 0x45, 0x13, 0x66, 0x80, 0x24, 0xdc, 0x22, + 0x0e, 0x51, 0x94, 0xed, 0xe6, 0x83, 0x36, 0x32, 0x63, 0x23, 0x1b, 0xf8, 0x78, 0xb4, 0x04, 0x7f, 0x5a, 0x50, 0x54, 0x12, 0x19, 0x04, 0x61, 0xdd, 0x25, 0xf0, 0x48, 0x29, 0x04, 0xc1, 0x44, 0xe2 }, + { 0x46, 0x32, 0x2d, 0xc7, 0xbc, 0x05, 0x2a, 0xd3, 0xb5, 0xce, 0x7d, 0x47, 0x5e, 0xfc, 0x90, 0x38, 0xef, 0xfa, 0x6f, 0x42, 0xf0, 0x66, 0x05, 0x89, 0x7c, 0x9a, 0xc1, 0xfd, 0xa2, 0xe8, 0xa7, 0x38, + 0x18, 0x6d, 0x7f, 0x9e, 0xfb, 0xbd, 0x06, 0x0c, 0x70, 0xd7, 0x29, 0x10, 0x88, 0x04, 0x9f, 0x24, 0x28, 0x9d, 0xc7, 0x84, 0xdf, 0xb6, 0xec, 0xb2, 0xc7, 0x1b, 0xd1, 0xc1, 0x9d, 0x56, 0xb0, 0x83 }, + { 0xda, 0xd7, 0x34, 0xee, 0x62, 0x13, 0x8f, 0x47, 0xad, 0xb4, 0x9c, 0x98, 0xe4, 0xc5, 0xb3, 0x29, 0x31, 0x11, 0x64, 0xad, 0xf5, 0x0b, 0x60, 0xe1, 0x0e, 0x18, 0x28, 0x30, 0x3c, 0xa2, 0xe3, 0x29, + 0x89, 0x0a, 0x7e, 0x18, 0xba, 0x30, 0x9e, 0x7d, 0x53, 0xf1, 0x82, 0xd5, 0x27, 0xe5, 0xf3, 0xab, 0x15, 0xcd, 0x62, 0x7e, 0xdf, 0xf0, 0x0e, 0x42, 0xfa, 0x6b, 0x7b, 0x54, 0xd2, 0x74, 0x19, 0x8f }, + { 0x29, 0x4d, 0x28, 0x80, 0x62, 0xb5, 0x77, 0xbb, 0x69, 0x70, 0xb0, 0xb7, 0x10, 0x2e, 0xed, 0xfc, 0x13, 0x34, 0x93, 0x7f, 0xd8, 0xfc, 0xb5, 0x7b, 0xfe, 0x34, 0x0a, 0xa3, 0x95, 0x5b, 0xb1, 0xa7, + 0xc6, 0xab, 0x82, 0x79, 0x25, 0x23, 0x94, 0x12, 0xa4, 0x34, 0xec, 0x23, 0xca, 0xcb, 0xd0, 0xa3, 0xf9, 0x31, 0x32, 0xce, 0x50, 0x31, 0x73, 0x23, 0x98, 0x94, 0xe3, 0x08, 0xd9, 0x1e, 0xc3, 0x0b, + 0x39, 0xe3, 0x3b, 0xf2, 0xe8, 0xb7, 0x26, 0x28, 0x9d, 0xb3, 0x12, 0x8d, 0x16, 0xca, 0x89, 0x26, 0xa9, 0x1c, 0xa3, 0x1f, 0x36, 0x10, 0x60, 0x6a, 0x29, 0x85, 0xe7, 0x2c, 0xee, 0xc1, 0xb6, 0xae }, + { 0x68, 0xed, 0x3c, 0x64, 0xe6, 0x87, 0xf0, 0x14, 0x64, 0xfc, 0x38, 0x3a, 0x0f, 0xd9, 0x7a, 0x5b, 0x52, 0x32, 0x10, 0xca, 0xc6, 0x83, 0x0b, 0xae, 0x17, 0x0e, 0xfe, 0x77, 0xe0, 0xe7, 0x83, 0xa1, + 0x2c, 0x78, 0x62, 0x9c, 0x79, 0x08, 0x2b, 0xd4, 0x85, 0x72, 0x27, 0x8d, 0x97, 0x78, 0x62, 0x33, 0x34, 0xeb, 0x5c, 0xde, 0x5d, 0xaa, 0x4d, 0xfa, 0xd1, 0x67, 0xa4, 0xea, 0x45, 0xad, 0xf9, 0x06, + 0x39, 0xe3, 0x3b, 0xf2, 0xe8, 0xb7, 0x26, 0x28, 0x9d, 0xb3, 0x12, 0x8d, 0x16, 0xca, 0x89, 0x26, 0xa9, 0x1c, 0xa3, 0x1f, 0x36, 0x10, 0x60, 0x6a, 0x29, 0x85, 0xe7, 0x2c, 0xee, 0xc1, 0xb6, 0xae } }, + { { 0xd9, 0x64, 0xb2, 0xe1, 0x9f, 0x0a, 0x35, 0xfc, 0x9f, 0xc3, 0xa5, 0x2a, 0xa3, 0x84, 0xb4, 0xf3, 0x23, 0xc4, 0xf3, 0x5a, 0x9d, 0xf8, 0x7f, 0x35, 0xa9, 0xf5, 0x5b, 0x68, 0xfc, 0x19, 0x69, 0x63, + 0x6a, 0x13, 0x19, 0x32, 0xcc, 0x9d, 0x0c, 0x3c, 0x7d, 0xdd, 0x85, 0x16, 0xa8, 0xd9, 0x2b, 0x75, 0x08, 0x4b, 0x9a, 0xa5, 0x6e, 0xf3, 0xe9, 0xeb, 0xed, 0x5d, 0x2e, 0xfd, 0x2e, 0x0c, 0x60, 0xa2 }, + { 0x0f, 0xf6, 0x8c, 0x3f, 0x6e, 0xee, 0x56, 0x4f, 0x43, 0x6f, 0x54, 0xbd, 0x7a, 0xe4, 0xbe, 0xa8, 0x77, 0x05, 0x99, 0xe7, 0x9e, 0x59, 0x22, 0x85, 0x9b, 0xc6, 0xe4, 0x2a, 0x61, 0x9c, 0x19, 0xb1, + 0x5a, 0xeb, 0x7a, 0xf8, 0x41, 0x4e, 0xe5, 0x2a, 0xd0, 0xf7, 0x44, 0xf0, 0x16, 0xea, 0x0c, 0x04, 0x19, 0x6c, 0xb6, 0x30, 0x3c, 0x6e, 0x2d, 0x79, 0x9a, 0x8f, 0x08, 0x90, 0x11, 0xf1, 0xc0, 0x4d }, + { 0x68, 0xe7, 0x1d, 0x40, 0xf1, 0x07, 0xc0, 0xc6, 0xb2, 0x87, 0x9c, 0xa2, 0x19, 0x43, 0x7a, 0xdf, 0x8a, 0x5a, 0x0f, 0xe2, 0x24, 0x97, 0xa0, 0x38, 0x79, 0x20, 0x38, 0xa9, 0x9c, 0x77, 0xc4, 0x37, + 0xa6, 0x02, 0xe0, 0x93, 0x47, 0xa4, 0x55, 0x21, 0xc2, 0x69, 0xbe, 0x09, 0x05, 0xaa, 0x87, 0x28, 0xf1, 0x95, 0x2f, 0xdb, 0xf0, 0xbf, 0xd2, 0x9e, 0x5e, 0x3a, 0xfa, 0xc6, 0x2f, 0x13, 0x09, 0xaf }, + { 0xe1, 0x9e, 0xc8, 0x4f, 0xc9, 0xdd, 0x61, 0x60, 0x94, 0xbc, 0xd3, 0xd6, 0xde, 0x11, 0x6e, 0xec, 0x84, 0xc4, 0xdd, 0xbe, 0x20, 0x46, 0x6c, 0xef, 0xf6, 0x9d, 0x37, 0x07, 0x53, 0x72, 0x57, 0xf9, + 0x02, 0xb5, 0x64, 0x1f, 0xe2, 0x56, 0xa4, 0x38, 0x6d, 0xa4, 0xed, 0x23, 0x9e, 0xa3, 0xf4, 0x4d, 0x77, 0x52, 0xdc, 0x8c, 0x51, 0xfc, 0x88, 0x18, 0xbc, 0x83, 0x2a, 0xac, 0xc1, 0x1d, 0x3d, 0x59 }, + { 0x08, 0x4f, 0x78, 0x21, 0xfd, 0x4b, 0x85, 0x86, 0x4e, 0x25, 0xdd, 0x47, 0x60, 0x7f, 0x7e, 0xc6, 0xd3, 0xa1, 0xab, 0x91, 0x3f, 0xeb, 0xf6, 0x40, 0x7e, 0x1b, 0xbd, 0x99, 0x9c, 0x7c, 0x2f, 0x4f, + 0xca, 0x68, 0xa5, 0xf6, 0x8c, 0x1e, 0xcb, 0xb8, 0x76, 0xe2, 0x87, 0x5b, 0x49, 0x68, 0x97, 0x2c, 0x21, 0x5c, 0x7c, 0x93, 0x79, 0x9a, 0x95, 0xa1, 0x3a, 0x49, 0xc9, 0x6d, 0x34, 0x6b, 0xa1, 0x98 }, + { 0xb9, 0x88, 0x25, 0x9a, 0x3b, 0x53, 0x56, 0xa1, 0x48, 0x0f, 0xf0, 0x92, 0xde, 0x4e, 0x3e, 0x3a, 0xcf, 0x02, 0xdc, 0x5c, 0xc2, 0xc3, 0x78, 0xad, 0x8a, 0x0c, 0x3c, 0xc7, 0xdd, 0xdd, 0x71, 0x6e, + 0x3f, 0xd9, 0x3a, 0x57, 0x2a, 0x19, 0xa5, 0x3b, 0x5c, 0x46, 0x7b, 0xc9, 0x0f, 0x16, 0xb3, 0x58, 0xa6, 0x85, 0xfa, 0x91, 0x2c, 0x9a, 0x9c, 0x12, 0xb6, 0xd6, 0x7d, 0x9a, 0xf0, 0x9d, 0xe9, 0x02, + 0xad, 0x12, 0x87, 0xda, 0x85, 0x58, 0x6b, 0xff, 0x68, 0x96, 0x05, 0x33, 0xba, 0x7f, 0x08, 0xf9, 0xa9, 0xa2, 0xa9, 0x46, 0x43, 0xe5, 0x03, 0x12, 0xe4, 0xbe, 0x74, 0xaa, 0x46, 0x4e, 0x51, 0xb3 }, + { 0x61, 0x70, 0x17, 0x50, 0x26, 0xfa, 0x51, 0x83, 0xe0, 0xca, 0xa9, 0xb1, 0xc3, 0xc4, 0x83, 0xa9, 0xb6, 0x43, 0x6b, 0x7a, 0x5b, 0xe4, 0x21, 0x5a, 0x6b, 0xd4, 0x34, 0xf8, 0xee, 0x95, 0x86, 0x2d, + 0x03, 0xbf, 0xca, 0xd0, 0xfa, 0x68, 0x53, 0xb2, 0x97, 0x50, 0xad, 0x89, 0x2f, 0x99, 0x63, 0x67, 0x18, 0x57, 0x1f, 0x57, 0x41, 0xbc, 0xb7, 0xc0, 0x18, 0xe7, 0xb6, 0xf3, 0x0f, 0xc4, 0x49, 0x0d, + 0xad, 0x12, 0x87, 0xda, 0x85, 0x58, 0x6b, 0xff, 0x68, 0x96, 0x05, 0x33, 0xba, 0x7f, 0x08, 0xf9, 0xa9, 0xa2, 0xa9, 0x46, 0x43, 0xe5, 0x03, 0x12, 0xe4, 0xbe, 0x74, 0xaa, 0x46, 0x4e, 0x51, 0xb3 } }, + { { 0xc5, 0xdf, 0x86, 0x8f, 0xf1, 0xa7, 0xad, 0x57, 0xfd, 0xb4, 0x53, 0xc3, 0x92, 0x1b, 0x9e, 0x2e, 0xdd, 0xc5, 0xa4, 0x3b, 0x72, 0xa6, 0x9b, 0x4a, 0x15, 0xca, 0x35, 0xed, 0x3c, 0x1a, 0x3b, 0x38, + 0x36, 0xd6, 0xf2, 0x03, 0xb6, 0x97, 0x1f, 0xcb, 0x40, 0x5d, 0x3c, 0x25, 0xfc, 0xe7, 0xff, 0xc6, 0xbe, 0x61, 0xe1, 0x98, 0x31, 0x13, 0xa9, 0xbe, 0x05, 0x86, 0xfe, 0x5c, 0xf6, 0xcc, 0xaa, 0xf5 }, + { 0xd2, 0x57, 0x19, 0x98, 0xf8, 0x74, 0x90, 0xb7, 0x69, 0x6e, 0xdd, 0x44, 0xf1, 0x8b, 0xb1, 0x9c, 0xfd, 0x5b, 0x6b, 0xc0, 0x45, 0xf2, 0x49, 0xa5, 0x4b, 0xff, 0x8b, 0x7f, 0x87, 0xe3, 0xf9, 0x71, + 0xab, 0xfa, 0xc8, 0x17, 0xed, 0xeb, 0x19, 0xc6, 0x3c, 0xee, 0x78, 0xba, 0x89, 0x97, 0x49, 0x85, 0x39, 0x68, 0x29, 0x88, 0x0b, 0x1c, 0xd1, 0x42, 0x8b, 0xe8, 0x1a, 0x3b, 0xeb, 0x4d, 0xef, 0x3b }, + { 0xea, 0xfb, 0xec, 0x27, 0xc3, 0x92, 0xc3, 0x68, 0x0d, 0x3c, 0x5b, 0x20, 0x20, 0x9c, 0x96, 0xa7, 0x39, 0xfa, 0x80, 0x91, 0xef, 0x86, 0x7d, 0xa8, 0x87, 0xf6, 0xef, 0x14, 0x01, 0x46, 0xf0, 0x68, + 0x0a, 0x8b, 0xae, 0x83, 0x91, 0x7e, 0xa0, 0x14, 0x14, 0xde, 0xf9, 0xa8, 0xfd, 0x67, 0x57, 0x17, 0x20, 0x46, 0x43, 0x49, 0x07, 0xf0, 0x3e, 0xc8, 0xbe, 0x66, 0xaf, 0x58, 0x3a, 0xbd, 0xd8, 0x00 }, + { 0x35, 0xf5, 0xc8, 0x2c, 0x0e, 0x4b, 0x56, 0xe0, 0xef, 0x08, 0x34, 0x38, 0x57, 0xe9, 0xde, 0xdb, 0x1d, 0xe1, 0x28, 0x05, 0x01, 0xed, 0x62, 0x3d, 0xa9, 0x6e, 0xea, 0x5b, 0x95, 0x09, 0xe0, 0x04, + 0x46, 0xff, 0xdc, 0x34, 0xf6, 0xf7, 0x63, 0xb1, 0x76, 0xb8, 0x3c, 0x03, 0xef, 0x36, 0x0f, 0x82, 0x1b, 0x5b, 0x6f, 0xe2, 0x86, 0xd9, 0x10, 0x01, 0xe6, 0x73, 0x75, 0x0d, 0x50, 0x30, 0x11, 0x68 }, + { 0x27, 0xb6, 0x3b, 0x78, 0x79, 0xf3, 0x22, 0x78, 0x8f, 0x0c, 0x14, 0x8b, 0x3f, 0x68, 0xc2, 0xab, 0x9f, 0x9f, 0x05, 0x70, 0x7e, 0xee, 0x4b, 0x1b, 0x6b, 0xfc, 0x04, 0x72, 0xca, 0xf1, 0x9a, 0xba, + 0xe3, 0x65, 0x9d, 0xdb, 0x01, 0x33, 0xc5, 0xdb, 0xf6, 0x87, 0xe4, 0x73, 0x5a, 0x0f, 0x94, 0xa9, 0x2e, 0xfe, 0x8f, 0x3e, 0xd1, 0x0a, 0x6d, 0xa1, 0x21, 0x2a, 0x92, 0x8c, 0x4b, 0x43, 0x13, 0x2f }, + { 0xa3, 0xa8, 0x3b, 0xb4, 0x4f, 0x8a, 0xac, 0xab, 0x8a, 0x4c, 0x39, 0x7e, 0xb8, 0x2f, 0xb1, 0x01, 0x2e, 0xbe, 0x0e, 0x7d, 0x28, 0x8a, 0x18, 0x4a, 0xda, 0x58, 0x1a, 0xfb, 0x95, 0x97, 0xf3, 0x63, + 0x58, 0xbe, 0x8c, 0x30, 0x13, 0x9b, 0xba, 0x9f, 0x4e, 0xac, 0x8d, 0x95, 0xf2, 0x07, 0xbb, 0x85, 0xa1, 0x41, 0x4c, 0x33, 0xe3, 0x58, 0x8e, 0x5c, 0xa1, 0x05, 0x45, 0xab, 0x5c, 0x0c, 0xe4, 0x02, + 0xc3, 0xa0, 0xa0, 0x72, 0xdb, 0x9a, 0x9d, 0xbf, 0x13, 0x29, 0x94, 0x70, 0x8b, 0xe4, 0xe8, 0xdb, 0x0e, 0x0b, 0xd0, 0xa0, 0x25, 0xad, 0x71, 0xa0, 0x27, 0x9c, 0x1d, 0x77, 0xb0, 0x98, 0xa8, 0x03 }, + { 0xe1, 0x84, 0xa5, 0xea, 0xa5, 0xd8, 0x1b, 0x29, 0xce, 0xd7, 0xa3, 0x72, 0xa7, 0xc9, 0xa5, 0xea, 0xf1, 0x02, 0xf3, 0x0c, 0xb0, 0x65, 0x12, 0xbc, 0xa4, 0xf2, 0x5d, 0x69, 0x00, 0xa4, 0x7f, 0x5a, + 0x52, 0x09, 0xb6, 0x7b, 0x30, 0xf2, 0x99, 0x03, 0x39, 0x9d, 0xee, 0x6f, 0xb5, 0xf7, 0x9e, 0x7a, 0x97, 0x8b, 0x81, 0x03, 0x8c, 0xdd, 0x35, 0xfc, 0x1f, 0x0a, 0xc6, 0xa4, 0x60, 0x7b, 0xc8, 0x0a, + 0xc3, 0xa0, 0xa0, 0x72, 0xdb, 0x9a, 0x9d, 0xbf, 0x13, 0x29, 0x94, 0x70, 0x8b, 0xe4, 0xe8, 0xdb, 0x0e, 0x0b, 0xd0, 0xa0, 0x25, 0xad, 0x71, 0xa0, 0x27, 0x9c, 0x1d, 0x77, 0xb0, 0x98, 0xa8, 0x03 } }, + { { 0x67, 0xe9, 0x62, 0x76, 0x3a, 0x90, 0x9b, 0x6b, 0x19, 0x1d, 0x65, 0xb2, 0x2a, 0x2f, 0xf7, 0x50, 0xaa, 0x54, 0xa5, 0xbb, 0x53, 0xb5, 0xf9, 0xee, 0x0c, 0x04, 0x3a, 0x3c, 0x29, 0x4b, 0x66, 0x3e, + 0x7b, 0xb6, 0xaa, 0xd2, 0x10, 0x89, 0xcc, 0x89, 0x2c, 0x47, 0xbe, 0x23, 0xd6, 0x52, 0x81, 0x5d, 0xc8, 0xbc, 0x49, 0xd6, 0x6a, 0xcd, 0x62, 0x99, 0x30, 0xff, 0x16, 0xa5, 0x50, 0x44, 0xd8, 0x7a }, + { 0xd6, 0xcd, 0xfe, 0xd4, 0x44, 0x4a, 0x9e, 0x90, 0x44, 0x73, 0x8a, 0xff, 0xbb, 0x82, 0x08, 0xb6, 0x7f, 0xf2, 0x87, 0xcb, 0xa5, 0x0b, 0x56, 0xd3, 0x9e, 0x91, 0xb8, 0x52, 0x6b, 0x25, 0xa6, 0x5d, + 0x50, 0xaf, 0x9b, 0xd5, 0xfb, 0x9f, 0x7e, 0x2d, 0x57, 0xdf, 0x30, 0x78, 0x8d, 0x1a, 0xc3, 0xac, 0x9c, 0x5a, 0xbf, 0xab, 0x5a, 0x0d, 0xc9, 0xb6, 0x4b, 0x18, 0xd4, 0xe7, 0x55, 0x40, 0xde, 0x7e }, + { 0xc2, 0xa9, 0x7e, 0x5c, 0x26, 0xf4, 0x7d, 0xce, 0x9e, 0x73, 0xae, 0x50, 0xde, 0xe7, 0xa6, 0xf9, 0x8b, 0x57, 0xf9, 0x7a, 0x4c, 0x38, 0x82, 0xf6, 0x30, 0x80, 0x12, 0xf7, 0xf6, 0x66, 0x80, 0x46, + 0x4d, 0x41, 0x53, 0x63, 0xd9, 0x65, 0x90, 0xe7, 0xee, 0x24, 0x07, 0xb0, 0x4f, 0xeb, 0x3e, 0x8e, 0x83, 0x21, 0xa3, 0x40, 0x03, 0xc0, 0x64, 0x52, 0xc6, 0xb2, 0x12, 0x9d, 0x8d, 0x86, 0xdd, 0x19 }, + { 0xe2, 0xd5, 0x49, 0x5e, 0x2a, 0x6e, 0x4e, 0xd9, 0x31, 0x26, 0x53, 0x13, 0x98, 0x5e, 0x2f, 0x23, 0xea, 0xa0, 0x30, 0xee, 0xef, 0x62, 0x2b, 0xdc, 0x93, 0x65, 0x90, 0xad, 0x9a, 0xf1, 0x74, 0x12, + 0xf5, 0x24, 0x33, 0xcc, 0xc3, 0xda, 0x42, 0x54, 0xa6, 0x6c, 0x86, 0x99, 0xb9, 0xb5, 0xf7, 0x07, 0x90, 0xd8, 0x85, 0x7f, 0x69, 0xfb, 0x19, 0x2a, 0x2c, 0xc0, 0x11, 0x81, 0x64, 0x37, 0x38, 0x07 }, + { 0xc7, 0xb3, 0xf5, 0xe4, 0x4b, 0x55, 0xcf, 0xd8, 0x2b, 0x72, 0xde, 0x62, 0xfc, 0x66, 0xea, 0x82, 0xee, 0x2e, 0xe5, 0x4f, 0x66, 0xba, 0x19, 0x63, 0x01, 0x0b, 0x2d, 0x89, 0xb4, 0xaa, 0x76, 0xb3, + 0x7e, 0xc5, 0xbe, 0xdd, 0x57, 0x90, 0x5e, 0xff, 0x5b, 0x9a, 0x71, 0xe1, 0x47, 0xf9, 0xec, 0xe5, 0xf0, 0x19, 0x89, 0x17, 0x65, 0x3e, 0x56, 0x4a, 0x98, 0xb2, 0x3c, 0x3b, 0xf0, 0x14, 0x13, 0x1b }, + { 0xc0, 0x72, 0x26, 0x96, 0x6b, 0xf5, 0x50, 0xa1, 0x65, 0xcd, 0xfe, 0x92, 0xa5, 0x5a, 0xb3, 0x56, 0x27, 0x5b, 0x2f, 0x4a, 0x8f, 0x67, 0xaa, 0xf4, 0xa1, 0x6e, 0x3c, 0x66, 0xcc, 0xb7, 0x71, 0x70, + 0xff, 0x70, 0x1f, 0x9e, 0x09, 0xae, 0x31, 0xcb, 0x2a, 0xd5, 0x8a, 0x38, 0xa9, 0xaf, 0xbc, 0x94, 0xa2, 0xa8, 0xe9, 0x77, 0x1c, 0xc3, 0xfa, 0xd1, 0x45, 0xd2, 0xe2, 0xff, 0x7d, 0xf2, 0x44, 0x00, + 0xa0, 0xc3, 0xc1, 0xdd, 0xa0, 0x4c, 0xfb, 0xed, 0x1a, 0xbd, 0x0c, 0x05, 0x3b, 0xa9, 0xc8, 0x98, 0xb0, 0x7d, 0x6a, 0x77, 0xcb, 0x08, 0x70, 0x64, 0x31, 0x9d, 0x9c, 0x7b, 0x40, 0x9e, 0xbb, 0xf4 }, + { 0xbc, 0x88, 0x9d, 0x36, 0xae, 0xbc, 0x92, 0x47, 0x63, 0x85, 0x41, 0xe3, 0x1e, 0x1c, 0x39, 0xf5, 0xd3, 0xc2, 0x0a, 0x7d, 0x18, 0x7a, 0x8f, 0xd3, 0x0c, 0x37, 0x50, 0x28, 0x35, 0x93, 0x77, 0x4b, + 0xcb, 0xba, 0x35, 0x4e, 0x94, 0x48, 0xe4, 0x0c, 0xa7, 0x36, 0x4f, 0x74, 0x2b, 0xf9, 0xb5, 0xb5, 0xeb, 0x91, 0x50, 0x3c, 0x67, 0x9b, 0x4d, 0x25, 0xd4, 0x0e, 0x0d, 0xb9, 0x5b, 0x77, 0xf3, 0x0e, + 0xa0, 0xc3, 0xc1, 0xdd, 0xa0, 0x4c, 0xfb, 0xed, 0x1a, 0xbd, 0x0c, 0x05, 0x3b, 0xa9, 0xc8, 0x98, 0xb0, 0x7d, 0x6a, 0x77, 0xcb, 0x08, 0x70, 0x64, 0x31, 0x9d, 0x9c, 0x7b, 0x40, 0x9e, 0xbb, 0xf4 } }, + { { 0x44, 0xdd, 0x62, 0x9e, 0x0f, 0xee, 0x20, 0x11, 0x37, 0xfc, 0xd0, 0x5c, 0xe4, 0xe1, 0x0a, 0xb8, 0xc2, 0xe0, 0x9c, 0x2c, 0x3e, 0x1b, 0x31, 0x1c, 0xdb, 0xa3, 0x84, 0x9a, 0xb7, 0x4e, 0x40, 0x74, + 0x21, 0xfd, 0xfc, 0x65, 0xbd, 0x38, 0x8a, 0x55, 0x6f, 0x1e, 0xc3, 0x14, 0xfc, 0x66, 0x04, 0x7b, 0xc4, 0x61, 0xb0, 0xcb, 0xfa, 0xdd, 0x50, 0x45, 0x4b, 0x2e, 0xf0, 0x6d, 0x0f, 0x26, 0x6d, 0xbf }, + { 0xe6, 0xbc, 0x35, 0x73, 0xb3, 0x11, 0x38, 0xc6, 0x31, 0x82, 0x96, 0x80, 0x1d, 0xa9, 0xd9, 0x17, 0x85, 0x4e, 0xad, 0x0f, 0x5c, 0xb7, 0xe8, 0x78, 0x62, 0x2f, 0x3c, 0x10, 0x0e, 0xdc, 0xf2, 0x7e, + 0xf5, 0x02, 0x6d, 0x1a, 0x50, 0xc2, 0x50, 0x7d, 0x0d, 0x14, 0x77, 0x77, 0xfc, 0xbe, 0x23, 0x02, 0x81, 0x0a, 0xdc, 0xa3, 0x16, 0xfd, 0xab, 0xb9, 0x7c, 0xb6, 0x7e, 0x8a, 0xde, 0x1f, 0x22, 0xeb }, + { 0xab, 0xf3, 0xea, 0x63, 0xc0, 0x25, 0xa2, 0xc7, 0x6a, 0xfe, 0x91, 0x4a, 0x0a, 0x91, 0xdd, 0x6d, 0x6f, 0x8c, 0xf9, 0xa8, 0x1c, 0x9f, 0xb5, 0xe5, 0xd2, 0xac, 0xe6, 0x51, 0x9a, 0xd3, 0x87, 0x17, + 0x82, 0x12, 0x0a, 0x58, 0x99, 0x7f, 0x81, 0x2d, 0x8d, 0x27, 0x2d, 0x1b, 0xb0, 0x02, 0x7e, 0x0d, 0xd6, 0x18, 0x89, 0x5e, 0x0c, 0x2b, 0x57, 0xa6, 0x56, 0x35, 0xff, 0x71, 0x4e, 0xb0, 0x49, 0x38 }, + { 0x36, 0xdf, 0x1d, 0x1c, 0xf6, 0xa7, 0x4d, 0x87, 0x7e, 0x2c, 0x3f, 0xb4, 0xda, 0xd7, 0x80, 0x71, 0x0b, 0xf3, 0x2a, 0x47, 0x20, 0xe6, 0x9a, 0x3d, 0x17, 0x9a, 0x97, 0xc9, 0x4e, 0x53, 0xa6, 0xe2, + 0x23, 0xea, 0x94, 0x4d, 0xf9, 0xeb, 0x2c, 0x03, 0x2c, 0x88, 0xa2, 0xe6, 0xc5, 0x94, 0xa5, 0x6f, 0xc3, 0x98, 0xa9, 0x8b, 0xa7, 0x41, 0x7d, 0xd3, 0x82, 0x01, 0x13, 0xb6, 0x0f, 0x39, 0x1e, 0xd2 }, + { 0x08, 0x28, 0xc3, 0x1c, 0xec, 0x21, 0x3a, 0xb4, 0x4c, 0xb1, 0xfa, 0xb9, 0x0c, 0xfe, 0xc2, 0x50, 0xc5, 0x99, 0x62, 0xa0, 0x11, 0x74, 0xcf, 0x05, 0x1e, 0x2b, 0xdf, 0x6d, 0x22, 0x8e, 0x6e, 0x55, + 0x19, 0x21, 0x9c, 0xa1, 0x98, 0x56, 0x45, 0x90, 0x40, 0x3a, 0x8e, 0xad, 0x76, 0x4d, 0xd3, 0x95, 0x27, 0x67, 0x4e, 0x02, 0x16, 0xc3, 0xfe, 0x5a, 0x79, 0x4e, 0x2d, 0x6f, 0xd0, 0xe4, 0x4f, 0x62 }, + { 0x40, 0x14, 0xe1, 0x88, 0x3d, 0xcc, 0x51, 0xcb, 0x98, 0x86, 0x06, 0x4d, 0xe4, 0x52, 0x71, 0xe2, 0x2e, 0x2b, 0x80, 0xfd, 0x81, 0x65, 0xaf, 0x93, 0x31, 0x87, 0xe0, 0xff, 0x31, 0xab, 0xff, 0x53, + 0x0e, 0x2d, 0xb1, 0x47, 0xe6, 0x44, 0xb7, 0x29, 0xab, 0x0f, 0x51, 0x3a, 0x53, 0x84, 0x36, 0x58, 0x8c, 0x5f, 0x7b, 0x65, 0x6a, 0xb7, 0x6f, 0xdc, 0xad, 0xc1, 0xa3, 0xe4, 0x21, 0xfc, 0x22, 0x0e, + 0xc1, 0x10, 0xd1, 0x7d, 0x9f, 0xd3, 0x1e, 0x33, 0xb4, 0xca, 0xb9, 0xff, 0xd8, 0x27, 0xb8, 0xca, 0xde, 0x49, 0x6f, 0xdc, 0xf0, 0xe8, 0x70, 0x36, 0xdb, 0x90, 0x00, 0x07, 0x9e, 0x77, 0x39, 0xfe }, + { 0xc9, 0x93, 0x4b, 0xe6, 0x47, 0x7e, 0x1d, 0x86, 0x15, 0x46, 0xe8, 0x27, 0xf5, 0x84, 0x67, 0x4e, 0x42, 0xe3, 0x2b, 0x8a, 0x4e, 0x90, 0x7b, 0x87, 0xcc, 0xdf, 0xaa, 0x04, 0x06, 0x05, 0xe6, 0x72, + 0xff, 0x6f, 0x44, 0x1b, 0x08, 0xad, 0x79, 0x3e, 0xb7, 0xdd, 0xd7, 0x2c, 0x73, 0xf0, 0xf0, 0xc4, 0x6e, 0xb7, 0x37, 0xe1, 0x02, 0xf5, 0x42, 0xe7, 0xef, 0xa1, 0xdd, 0x50, 0x9a, 0xc5, 0x8d, 0x00, + 0xc1, 0x10, 0xd1, 0x7d, 0x9f, 0xd3, 0x1e, 0x33, 0xb4, 0xca, 0xb9, 0xff, 0xd8, 0x27, 0xb8, 0xca, 0xde, 0x49, 0x6f, 0xdc, 0xf0, 0xe8, 0x70, 0x36, 0xdb, 0x90, 0x00, 0x07, 0x9e, 0x77, 0x39, 0xfe } }, + { { 0x3e, 0x0c, 0x21, 0xc4, 0x3d, 0x64, 0x61, 0xc1, 0x9d, 0xa1, 0x83, 0x10, 0x74, 0x1d, 0x56, 0x12, 0xaf, 0x29, 0x5c, 0x6c, 0x12, 0x48, 0x0a, 0xc7, 0xe5, 0x12, 0xb6, 0x42, 0x6b, 0x54, 0xf4, 0x42, + 0x0c, 0x43, 0x42, 0x2e, 0x78, 0xc2, 0xe7, 0x26, 0x09, 0x41, 0x4a, 0x2f, 0xa1, 0xb0, 0x1f, 0xcd, 0x63, 0x76, 0x1e, 0xa1, 0x6f, 0xf6, 0xe2, 0xc2, 0x08, 0x89, 0x0d, 0x28, 0xbf, 0x1b, 0x56, 0x5b }, + { 0x3e, 0x2e, 0xf2, 0xcc, 0x81, 0xca, 0xa7, 0x5d, 0x01, 0xd2, 0x82, 0xfd, 0x45, 0xee, 0xc0, 0xf5, 0x49, 0x3b, 0xe2, 0xa4, 0x2a, 0x4d, 0x5f, 0x40, 0x0d, 0xbc, 0xb9, 0x3d, 0x6e, 0xda, 0xe2, 0x86, + 0xe1, 0x23, 0x8b, 0x5f, 0x0d, 0xa2, 0x35, 0x15, 0x1d, 0x22, 0x23, 0xa5, 0x69, 0x56, 0x34, 0x78, 0xb3, 0xb3, 0x55, 0xef, 0x63, 0x8a, 0x17, 0x63, 0xda, 0xf0, 0x64, 0x99, 0x8a, 0x8a, 0xba, 0xd6 }, + { 0x68, 0x79, 0x36, 0xa7, 0x6b, 0xe3, 0x76, 0x1c, 0xe3, 0x38, 0x0b, 0xa3, 0x91, 0xb6, 0xb0, 0x82, 0x37, 0xfa, 0x52, 0x74, 0xf1, 0xb5, 0xd5, 0xd9, 0x07, 0x06, 0x9e, 0xda, 0x87, 0x6b, 0x0f, 0x24, + 0x4f, 0xbe, 0xc9, 0xff, 0x03, 0x41, 0xaf, 0x77, 0x68, 0xed, 0xe7, 0x71, 0xba, 0x2d, 0xde, 0x27, 0xa1, 0xbf, 0xa8, 0xa7, 0x30, 0x7c, 0xcb, 0x79, 0x72, 0x89, 0x1a, 0xdc, 0xc1, 0xe4, 0xb2, 0x9d }, + { 0x94, 0xa3, 0x11, 0xf4, 0x44, 0x80, 0xd0, 0xa3, 0x47, 0x93, 0x36, 0xe2, 0xbd, 0x04, 0xe4, 0x74, 0x3d, 0x00, 0x60, 0xad, 0xd0, 0x2d, 0x86, 0x66, 0xa1, 0x72, 0x1a, 0xb9, 0x1c, 0x14, 0xa2, 0x9b, + 0x4b, 0x04, 0x7d, 0x5b, 0xcd, 0xf8, 0x01, 0x33, 0xde, 0x34, 0x10, 0x29, 0xc4, 0x72, 0x56, 0xff, 0x11, 0xcd, 0xd8, 0x61, 0x2c, 0xb6, 0xb7, 0xf4, 0x24, 0x8b, 0x44, 0xb4, 0xe7, 0x34, 0x50, 0xb8 }, + { 0x72, 0xf6, 0xd4, 0xa3, 0x24, 0xf9, 0xef, 0xf4, 0x55, 0x8d, 0x3c, 0x07, 0xca, 0x10, 0xdd, 0x54, 0x87, 0x13, 0x32, 0x78, 0x5c, 0x64, 0x10, 0x08, 0x62, 0x7e, 0xf4, 0x34, 0x0f, 0x1c, 0xcd, 0xcc, + 0x3b, 0x42, 0xfe, 0x60, 0x41, 0x70, 0x2c, 0x6b, 0xd4, 0x6c, 0xf7, 0xb8, 0x24, 0xf6, 0xd7, 0x07, 0xb3, 0x46, 0xb0, 0x7d, 0x14, 0x24, 0x9b, 0x72, 0x79, 0xf4, 0x23, 0x2a, 0xec, 0x02, 0xe7, 0x69 }, + { 0xe5, 0xbe, 0x84, 0xc3, 0x92, 0x47, 0x15, 0xd3, 0xac, 0x06, 0x44, 0x72, 0x41, 0xeb, 0xb6, 0x5a, 0x17, 0x06, 0x90, 0xd9, 0x55, 0x3d, 0xe4, 0x87, 0x7d, 0x5a, 0x11, 0x9f, 0x02, 0x6d, 0xd3, 0x4e, + 0x71, 0xd1, 0x5e, 0x16, 0x9f, 0xb2, 0xc0, 0x7f, 0xcb, 0x78, 0x8b, 0x89, 0x11, 0xae, 0x43, 0xe8, 0x85, 0xb7, 0xf9, 0xc8, 0x48, 0x5a, 0xb2, 0x96, 0xaf, 0x8f, 0xab, 0x71, 0x84, 0x9d, 0x40, 0x09, + 0x30, 0xd4, 0x32, 0x6e, 0xa2, 0x77, 0x97, 0x71, 0x37, 0xce, 0x22, 0x6b, 0xca, 0xc9, 0x79, 0xef, 0xc0, 0xb2, 0xb4, 0x3d, 0x30, 0xbf, 0x77, 0xe9, 0xc3, 0x8d, 0xec, 0x15, 0x04, 0x08, 0xfa, 0x15 }, + { 0x4b, 0xf3, 0x7f, 0xb2, 0x78, 0x75, 0x45, 0xd4, 0xce, 0x5e, 0x3d, 0xaf, 0x92, 0x63, 0x3d, 0x90, 0xc0, 0xa7, 0x23, 0x62, 0x7f, 0x37, 0x58, 0x8d, 0x12, 0xe0, 0xb8, 0x6c, 0x46, 0x38, 0xaa, 0xf7, + 0xe1, 0x03, 0x9e, 0x1f, 0x31, 0xf9, 0x5a, 0xa4, 0x59, 0x0d, 0xec, 0xc5, 0x1f, 0x17, 0x88, 0x25, 0xcc, 0xed, 0x69, 0x2b, 0x91, 0x73, 0x6a, 0x3f, 0xcb, 0xe5, 0x9c, 0x1e, 0x26, 0x3e, 0xec, 0x0b, + 0x30, 0xd4, 0x32, 0x6e, 0xa2, 0x77, 0x97, 0x71, 0x37, 0xce, 0x22, 0x6b, 0xca, 0xc9, 0x79, 0xef, 0xc0, 0xb2, 0xb4, 0x3d, 0x30, 0xbf, 0x77, 0xe9, 0xc3, 0x8d, 0xec, 0x15, 0x04, 0x08, 0xfa, 0x15 } }, + { { 0xc5, 0x1d, 0xcd, 0x70, 0xb2, 0x9e, 0x53, 0x29, 0x05, 0x78, 0x83, 0x5d, 0x56, 0x30, 0x89, 0xee, 0x02, 0xd7, 0xac, 0x57, 0x0a, 0xd2, 0xa0, 0x9c, 0x96, 0x0c, 0xbf, 0xf2, 0x30, 0xbf, 0x1a, 0x2b, + 0xee, 0x0e, 0x9f, 0x1e, 0x1c, 0x65, 0x7d, 0xb5, 0x48, 0xad, 0x6f, 0x51, 0xa0, 0x91, 0x61, 0xe4, 0xe6, 0x83, 0x9f, 0x58, 0x7c, 0x76, 0x2b, 0x52, 0x94, 0x87, 0x3c, 0x8d, 0x36, 0x4c, 0x37, 0x3c }, + { 0x59, 0x3b, 0x0d, 0x38, 0xab, 0x93, 0xca, 0xfb, 0x67, 0x44, 0x30, 0x96, 0xec, 0xbd, 0x00, 0x1d, 0x93, 0xd0, 0xb3, 0x3d, 0x3c, 0xd4, 0x4e, 0x3d, 0xd8, 0x29, 0x93, 0xb2, 0xb3, 0x77, 0xfc, 0x57, + 0x31, 0x20, 0xe3, 0x90, 0x0d, 0xf4, 0x91, 0x2f, 0x8b, 0x43, 0xce, 0xfe, 0x99, 0x03, 0x03, 0xa2, 0x90, 0x8d, 0xcf, 0xa8, 0xc0, 0x21, 0x00, 0xca, 0xcc, 0xcb, 0x4b, 0x2f, 0xa5, 0x39, 0xa8, 0x0b }, + { 0xca, 0xf6, 0xf9, 0xbb, 0x53, 0xcb, 0x97, 0x76, 0xb6, 0x9c, 0x2c, 0x18, 0x21, 0x43, 0x13, 0x48, 0x13, 0xc9, 0x0e, 0xeb, 0x40, 0xea, 0xce, 0x1f, 0x3a, 0xe9, 0xd2, 0x9e, 0x29, 0xdb, 0xe2, 0x79, + 0xe2, 0x1a, 0x9f, 0x84, 0x9d, 0xe4, 0x55, 0x82, 0x17, 0xeb, 0x87, 0xf6, 0xc3, 0xef, 0xcd, 0x54, 0x14, 0xee, 0xc8, 0x5b, 0xd7, 0x67, 0x05, 0xe2, 0x34, 0xa2, 0x7e, 0x81, 0x83, 0x21, 0x7a, 0x02 }, + { 0xc5, 0x03, 0xd9, 0x75, 0xdf, 0x17, 0x15, 0xe3, 0x5b, 0x7b, 0x4f, 0x66, 0x9c, 0x15, 0x4e, 0x01, 0xdf, 0x3d, 0x16, 0xb6, 0x52, 0xcc, 0xcf, 0x28, 0x40, 0xdb, 0x20, 0xee, 0x8b, 0x69, 0xb1, 0x2b, + 0xc0, 0x6e, 0xe4, 0xd2, 0xf5, 0xd1, 0x49, 0x3f, 0xf3, 0x0a, 0x12, 0xcd, 0x13, 0xbd, 0x9d, 0x3d, 0x5b, 0x28, 0x5c, 0xb0, 0x0d, 0x0e, 0xb6, 0xed, 0xec, 0x65, 0xeb, 0x25, 0x28, 0x2e, 0x65, 0x2f }, + { 0xed, 0xa7, 0x05, 0xc1, 0xa6, 0x81, 0xf2, 0x7a, 0x69, 0x68, 0x17, 0x8e, 0xf7, 0xc9, 0x14, 0x80, 0x9f, 0x81, 0xfe, 0x16, 0xfd, 0x81, 0x93, 0xb4, 0x0b, 0x05, 0x5b, 0x4e, 0xef, 0x6e, 0x7a, 0x67, + 0x9d, 0x99, 0x4c, 0x17, 0xcd, 0x1c, 0x16, 0xfd, 0x31, 0x35, 0xd5, 0x3e, 0xa3, 0x00, 0xbf, 0xbe, 0xda, 0xd6, 0xe2, 0x37, 0x9b, 0x13, 0x1b, 0xca, 0x29, 0x90, 0x4b, 0xf2, 0x09, 0x57, 0x2f, 0xe9 }, + { 0xd7, 0xba, 0x23, 0xd3, 0xa0, 0x6e, 0x14, 0x6a, 0xf0, 0x77, 0xb7, 0xe6, 0xe3, 0xc9, 0x3b, 0x38, 0xbb, 0xe7, 0xbe, 0x54, 0x75, 0xf8, 0xb7, 0x42, 0x29, 0xe2, 0x83, 0xde, 0x20, 0x22, 0x41, 0xcf, + 0x5f, 0x6f, 0x80, 0x60, 0xf3, 0x44, 0x04, 0x21, 0xd5, 0x03, 0x68, 0x42, 0xde, 0x81, 0xea, 0xe8, 0x7e, 0x5b, 0x80, 0x0f, 0x1b, 0x2d, 0x06, 0xc7, 0xce, 0xe9, 0x46, 0xc7, 0xf7, 0xb3, 0xa2, 0x02, + 0x21, 0xb5, 0x4d, 0xc2, 0x36, 0xea, 0xe6, 0x7b, 0xb3, 0x61, 0xe6, 0x18, 0x40, 0x5b, 0xce, 0x5b, 0xc2, 0xee, 0xa5, 0xde, 0xe9, 0xe6, 0xe0, 0xa8, 0x58, 0x58, 0x03, 0x34, 0x26, 0x27, 0x65, 0x2a }, + { 0xfa, 0x43, 0xa6, 0xc4, 0x32, 0xa1, 0x2f, 0xb6, 0x37, 0x05, 0xf4, 0xa4, 0xa7, 0x36, 0xdd, 0x1c, 0x45, 0x10, 0x95, 0x83, 0x67, 0x89, 0x79, 0x18, 0x34, 0xad, 0xe7, 0x57, 0x7f, 0x0d, 0x48, 0x9b, + 0x14, 0xdf, 0x5f, 0xc8, 0xd7, 0x0f, 0x78, 0x47, 0x88, 0x20, 0xff, 0x7f, 0xb1, 0x21, 0x27, 0x14, 0x58, 0x32, 0x12, 0xfb, 0x97, 0xe0, 0x81, 0x0e, 0x92, 0xf4, 0x5c, 0x0e, 0x44, 0x48, 0x4e, 0x01, + 0x21, 0xb5, 0x4d, 0xc2, 0x36, 0xea, 0xe6, 0x7b, 0xb3, 0x61, 0xe6, 0x18, 0x40, 0x5b, 0xce, 0x5b, 0xc2, 0xee, 0xa5, 0xde, 0xe9, 0xe6, 0xe0, 0xa8, 0x58, 0x58, 0x03, 0x34, 0x26, 0x27, 0x65, 0x2a } }, + { { 0x1e, 0x89, 0x12, 0xe8, 0xab, 0xca, 0xeb, 0x96, 0x78, 0x43, 0x89, 0x79, 0x26, 0x61, 0x86, 0x2e, 0x37, 0xd7, 0x94, 0xb5, 0xb9, 0xf7, 0xc9, 0xe7, 0x04, 0x6c, 0x96, 0x1c, 0x54, 0x0d, 0xb0, 0x6c, + 0xd3, 0x68, 0x9b, 0x53, 0xa7, 0x56, 0x34, 0x1b, 0x65, 0xff, 0xf9, 0xee, 0xf1, 0xc6, 0xfd, 0x7e, 0xa8, 0x42, 0x59, 0x60, 0x06, 0x5f, 0xc2, 0x89, 0x8b, 0xfc, 0xf8, 0x6c, 0x9a, 0x0d, 0xb1, 0x36 }, + { 0x52, 0x3d, 0x83, 0x25, 0x0f, 0x57, 0x81, 0x76, 0x7b, 0x21, 0xf7, 0x96, 0xd6, 0x1f, 0xfe, 0xd7, 0x7c, 0xc1, 0x32, 0xb5, 0xbc, 0x05, 0x46, 0xdb, 0x6f, 0x25, 0xd8, 0x7a, 0x68, 0xe2, 0x01, 0x81, + 0xf8, 0x9a, 0xc5, 0x29, 0x78, 0x1c, 0x01, 0xc5, 0x4d, 0x61, 0x4e, 0x75, 0xdf, 0x9f, 0xc3, 0x22, 0x96, 0x7c, 0xf9, 0xa7, 0xed, 0x41, 0x6f, 0x64, 0xfd, 0xd4, 0x61, 0x58, 0x0d, 0x49, 0xc9, 0xa4 }, + { 0x4a, 0xf7, 0xda, 0xef, 0xe0, 0x3b, 0x33, 0x19, 0x79, 0x02, 0x7a, 0xbb, 0xd3, 0x53, 0xf4, 0x8c, 0x8a, 0x16, 0xfb, 0xbd, 0x35, 0xd9, 0x70, 0xb2, 0x0a, 0x06, 0x05, 0x14, 0xd0, 0x9e, 0xf6, 0x13, + 0x44, 0xbb, 0xb7, 0x93, 0x86, 0x1b, 0x3c, 0xb0, 0x54, 0xa7, 0x48, 0xc2, 0xa7, 0x10, 0xda, 0x65, 0xb2, 0xdb, 0x0f, 0x85, 0x23, 0x57, 0x77, 0x44, 0x23, 0x20, 0x6d, 0x2e, 0xde, 0x20, 0x01, 0xed }, + { 0x9c, 0xb8, 0x68, 0xeb, 0xbb, 0x8b, 0xaf, 0x81, 0x9c, 0x2f, 0x90, 0x4c, 0xc2, 0x62, 0x17, 0xfc, 0xf2, 0xa5, 0xab, 0x4c, 0x2e, 0x69, 0xcb, 0x82, 0x5f, 0x4c, 0x3c, 0x82, 0xcd, 0x6a, 0xcb, 0x15, + 0xa2, 0xfc, 0x50, 0x54, 0x5e, 0x2e, 0x83, 0x52, 0x48, 0x29, 0x51, 0xcc, 0x50, 0xaa, 0x27, 0xa3, 0xf3, 0x71, 0xdb, 0x2c, 0x1c, 0xa9, 0x8a, 0xa5, 0x95, 0xab, 0x3e, 0x6f, 0xcd, 0xba, 0x22, 0x7c }, + { 0xf7, 0x5d, 0xb5, 0x20, 0x65, 0xfe, 0xa9, 0xe7, 0x1f, 0x8e, 0xd6, 0xc0, 0xf2, 0x3f, 0x1b, 0x8c, 0x7a, 0x02, 0x54, 0xd8, 0xa7, 0x0e, 0x6f, 0x68, 0x94, 0x81, 0xff, 0x30, 0x0e, 0x6d, 0x1a, 0x96, + 0x1b, 0x86, 0x07, 0xaa, 0xbf, 0x37, 0xc5, 0x5e, 0x26, 0xa2, 0xdf, 0x0b, 0xd0, 0x7f, 0x94, 0x35, 0x30, 0xa4, 0x9e, 0x47, 0xaf, 0xad, 0x9c, 0xc9, 0x02, 0x21, 0x55, 0x94, 0x04, 0x13, 0xff, 0x64 }, + { 0x9c, 0x8d, 0x18, 0x63, 0x83, 0xad, 0x01, 0xcc, 0xbb, 0xe6, 0x00, 0xda, 0x15, 0xce, 0xc6, 0x6e, 0x7a, 0x37, 0x6a, 0x81, 0x44, 0xb3, 0xfc, 0xb7, 0xcd, 0x05, 0xee, 0x4a, 0x6f, 0x29, 0xe4, 0x79, + 0x63, 0x52, 0x7e, 0x14, 0xc9, 0x14, 0x77, 0xa8, 0x19, 0x94, 0x03, 0xc6, 0x51, 0x57, 0xf1, 0xcc, 0x11, 0x29, 0xde, 0x86, 0x08, 0xfe, 0x41, 0x02, 0x71, 0xb7, 0xbf, 0xd7, 0xe7, 0x83, 0x3e, 0x0c, + 0x9a, 0x59, 0x7e, 0xe8, 0x61, 0x36, 0x56, 0x9a, 0xbf, 0x64, 0xfd, 0xf3, 0xb7, 0xb9, 0x2f, 0x9e, 0x56, 0x1f, 0x57, 0x45, 0x2e, 0x19, 0x0f, 0x6f, 0x70, 0x01, 0xc2, 0x48, 0x05, 0x23, 0x9b, 0x2f }, + { 0xb5, 0x4e, 0xe7, 0xcc, 0x7b, 0x66, 0x7a, 0xf8, 0xec, 0xcd, 0x1b, 0x0c, 0x0f, 0xec, 0x04, 0x27, 0xa0, 0x61, 0xfd, 0x12, 0x2d, 0xab, 0xc9, 0xc5, 0x8e, 0xee, 0x36, 0xc2, 0xef, 0x67, 0xd5, 0x87, + 0x95, 0x6c, 0x12, 0xb7, 0x12, 0x81, 0x55, 0xe0, 0x7b, 0xdb, 0x8f, 0x67, 0xea, 0x04, 0x55, 0x91, 0x9b, 0x50, 0x65, 0x05, 0xc1, 0xf1, 0x0b, 0x04, 0x91, 0x66, 0x3c, 0x32, 0x53, 0x72, 0x01, 0x04, + 0x9a, 0x59, 0x7e, 0xe8, 0x61, 0x36, 0x56, 0x9a, 0xbf, 0x64, 0xfd, 0xf3, 0xb7, 0xb9, 0x2f, 0x9e, 0x56, 0x1f, 0x57, 0x45, 0x2e, 0x19, 0x0f, 0x6f, 0x70, 0x01, 0xc2, 0x48, 0x05, 0x23, 0x9b, 0x2f } }, + { { 0xc8, 0x37, 0x10, 0xdc, 0xdb, 0xfc, 0x51, 0x91, 0xae, 0x37, 0xa4, 0xe0, 0xcf, 0xbb, 0xdd, 0x92, 0x93, 0x5f, 0x6b, 0xd6, 0x81, 0xbf, 0x9b, 0x24, 0x5e, 0x0d, 0xf1, 0xe4, 0x04, 0x89, 0xd1, 0x1b, + 0xb2, 0x68, 0x56, 0x3a, 0xdc, 0x59, 0xd0, 0x8a, 0x93, 0x37, 0x5d, 0xa5, 0x40, 0x5e, 0xfe, 0xc9, 0x41, 0x0b, 0x8a, 0x50, 0xd2, 0xa0, 0x94, 0x86, 0xf7, 0x46, 0x3b, 0x7e, 0x1d, 0xea, 0x2b, 0xa8 }, + { 0x1b, 0xe2, 0xe6, 0x48, 0x86, 0xa8, 0x65, 0xfd, 0x2b, 0xae, 0xc7, 0x7d, 0x41, 0xee, 0xb2, 0x80, 0x33, 0x1c, 0x0a, 0xdc, 0x42, 0xea, 0x99, 0xd0, 0x1f, 0x6d, 0xc8, 0x80, 0x51, 0x70, 0xd4, 0x19, + 0xae, 0xfc, 0x66, 0x16, 0xa2, 0x53, 0x27, 0x19, 0x7a, 0xf2, 0x9a, 0x25, 0x0c, 0x39, 0x8c, 0xbf, 0xe7, 0xa3, 0x7a, 0xd6, 0xa3, 0x43, 0x62, 0xd2, 0x4a, 0xc2, 0xf1, 0x96, 0x7e, 0xe3, 0x83, 0x13 }, + { 0xf5, 0xb1, 0x2a, 0xc5, 0x4d, 0xcc, 0xdf, 0x56, 0xde, 0x92, 0x96, 0x46, 0x03, 0x11, 0xfc, 0xa0, 0xbc, 0xa2, 0x22, 0xf7, 0x25, 0x74, 0x2a, 0x1f, 0x27, 0x34, 0x18, 0xe8, 0x06, 0xa4, 0x77, 0x26, + 0x1a, 0x51, 0x5e, 0xfb, 0x77, 0xbc, 0x55, 0xb1, 0xf8, 0xa5, 0x19, 0x23, 0x00, 0x97, 0xf7, 0xbb, 0xe4, 0xcd, 0x41, 0x9e, 0xd9, 0x5e, 0x0c, 0x6b, 0x1b, 0x8a, 0xba, 0x52, 0x93, 0xbe, 0x2c, 0xf3 }, + { 0xb3, 0x02, 0xeb, 0x44, 0x3c, 0x05, 0xae, 0x9c, 0x94, 0xa9, 0x1f, 0x72, 0x41, 0xbc, 0x81, 0x66, 0x5f, 0x50, 0xc0, 0x57, 0xb4, 0x44, 0xf0, 0xe1, 0x2a, 0xa9, 0x88, 0x69, 0xa6, 0x1c, 0x05, 0x85, + 0xda, 0xc7, 0xb2, 0xe1, 0x8c, 0x2f, 0x7c, 0x49, 0x37, 0xa2, 0xf2, 0x56, 0xab, 0x12, 0x9f, 0x12, 0x4b, 0x1b, 0x73, 0x75, 0x3f, 0x30, 0x0f, 0x40, 0xf1, 0xf9, 0x1d, 0xa7, 0x2c, 0x98, 0x8c, 0x91 }, + { 0xcb, 0xd3, 0x39, 0x60, 0x56, 0xe3, 0xbd, 0x65, 0x86, 0x1a, 0x58, 0x40, 0xc0, 0xa4, 0xc4, 0x8b, 0xe5, 0xf7, 0x49, 0x0a, 0xf2, 0x09, 0x51, 0x32, 0x6e, 0x06, 0x5a, 0x27, 0x19, 0x78, 0x2e, 0x3a, + 0x04, 0xf9, 0x34, 0x80, 0x49, 0x39, 0x93, 0xcd, 0x89, 0x67, 0x7b, 0xc0, 0x8d, 0x9d, 0x8d, 0x4c, 0x83, 0x20, 0x80, 0xfc, 0x00, 0xf2, 0x8a, 0x8f, 0xa4, 0x4d, 0x8e, 0x8f, 0x58, 0x51, 0x5b, 0x71 }, + { 0x71, 0x3f, 0x90, 0x41, 0xb8, 0x74, 0xbc, 0x7a, 0x85, 0xf5, 0xab, 0xca, 0x7e, 0xf2, 0x70, 0x41, 0xbc, 0x36, 0xb5, 0xc3, 0x4e, 0xf1, 0x2b, 0x17, 0x35, 0x40, 0xdb, 0x3c, 0xdb, 0xd2, 0xec, 0x0b, + 0x99, 0xc1, 0x43, 0x17, 0xad, 0x38, 0x45, 0x2d, 0x07, 0x31, 0xd7, 0xb6, 0x95, 0x1c, 0x89, 0x25, 0xe4, 0x89, 0x97, 0xd3, 0xcf, 0x11, 0x2f, 0x63, 0x31, 0x51, 0xa2, 0x18, 0xfc, 0x12, 0x04, 0x0a, + 0xb0, 0x33, 0xce, 0x0b, 0x57, 0xc0, 0x8c, 0x58, 0x25, 0xf8, 0x9b, 0x50, 0x22, 0x1c, 0x5c, 0x7b, 0x02, 0xc7, 0xed, 0xfc, 0x98, 0x8b, 0xbd, 0xd2, 0x4e, 0xfc, 0x78, 0x91, 0x7f, 0x4c, 0x99, 0x24 }, + { 0xfc, 0x46, 0xe4, 0x85, 0x0c, 0x52, 0x14, 0xf8, 0x8a, 0xa4, 0x97, 0x17, 0x10, 0xb2, 0x93, 0xef, 0xa0, 0x66, 0x3c, 0xfd, 0x61, 0x42, 0x24, 0x30, 0x70, 0x4b, 0xfd, 0x0b, 0x86, 0xc8, 0x97, 0xd7, + 0x04, 0xc2, 0xa6, 0x61, 0x41, 0xaf, 0xcc, 0x1d, 0x52, 0xc9, 0xf3, 0xca, 0xe1, 0x90, 0x7c, 0xbd, 0xce, 0xaf, 0x30, 0xc4, 0xb4, 0x7d, 0x81, 0x7e, 0xbd, 0xe2, 0x09, 0x70, 0x1e, 0x6b, 0xb9, 0x03, + 0xb0, 0x33, 0xce, 0x0b, 0x57, 0xc0, 0x8c, 0x58, 0x25, 0xf8, 0x9b, 0x50, 0x22, 0x1c, 0x5c, 0x7b, 0x02, 0xc7, 0xed, 0xfc, 0x98, 0x8b, 0xbd, 0xd2, 0x4e, 0xfc, 0x78, 0x91, 0x7f, 0x4c, 0x99, 0x24 } }, + { { 0x5f, 0x01, 0x6d, 0xec, 0x82, 0x02, 0x96, 0x47, 0x74, 0xd9, 0x73, 0x2e, 0x2e, 0x17, 0x00, 0xb6, 0xe0, 0xa4, 0x13, 0x17, 0xae, 0x7f, 0x85, 0xcb, 0xff, 0xe7, 0x96, 0x99, 0xdb, 0x9f, 0xad, 0x21, + 0x60, 0xd9, 0x12, 0xdc, 0x41, 0x01, 0x33, 0x66, 0x4c, 0x24, 0x8b, 0x25, 0x17, 0xd7, 0x22, 0x14, 0x12, 0x4d, 0xad, 0x82, 0x9a, 0x85, 0x69, 0x5e, 0x35, 0x10, 0xe0, 0xd7, 0x1a, 0x82, 0x88, 0x14 }, + { 0xab, 0x5f, 0x2c, 0x7d, 0xa2, 0xe5, 0x67, 0x5f, 0xe4, 0x92, 0x03, 0x93, 0xd7, 0x13, 0xa1, 0xfa, 0x4a, 0xb7, 0x18, 0x4a, 0x8e, 0x8c, 0x78, 0x9a, 0x0c, 0x60, 0x02, 0xe8, 0x2d, 0x50, 0x05, 0x0f, + 0x92, 0xee, 0x9f, 0x81, 0xde, 0x6b, 0x20, 0xe4, 0x9b, 0x17, 0x2e, 0x99, 0x0f, 0x01, 0x31, 0xa7, 0xc5, 0xc4, 0x53, 0x70, 0xda, 0x03, 0xc6, 0xf7, 0x22, 0x87, 0x98, 0x87, 0x19, 0x36, 0xa6, 0x49 }, + { 0x93, 0xab, 0x22, 0xc4, 0x39, 0x6c, 0x97, 0x80, 0xd2, 0xe2, 0x36, 0xfa, 0x31, 0x74, 0x67, 0xcc, 0x50, 0x1b, 0x95, 0xbe, 0x77, 0xe0, 0xd1, 0x00, 0x74, 0x04, 0xe1, 0x4d, 0xca, 0x44, 0x35, 0x72, + 0x74, 0x69, 0x82, 0x23, 0x56, 0x9b, 0xcc, 0x34, 0x5a, 0xcb, 0xa2, 0xa3, 0x31, 0x12, 0x4a, 0x84, 0x4c, 0xe9, 0x37, 0x3a, 0x58, 0xf8, 0x79, 0x65, 0x4a, 0x66, 0x79, 0x82, 0xf4, 0x5d, 0x75, 0xc3 }, + { 0x2d, 0x5d, 0xac, 0x4f, 0xb5, 0x00, 0x68, 0x3b, 0x5f, 0x2e, 0xdd, 0xcb, 0x14, 0x4a, 0x7f, 0xad, 0x12, 0x45, 0x91, 0xd1, 0x84, 0xd8, 0x14, 0xff, 0xcb, 0x64, 0x43, 0x6d, 0x65, 0xe7, 0x19, 0x68, + 0x2b, 0x5e, 0x53, 0x05, 0x74, 0x66, 0xed, 0xac, 0x2f, 0x5a, 0x8f, 0x70, 0x96, 0xab, 0x29, 0xf3, 0x9a, 0x59, 0xa2, 0xe2, 0xef, 0xd3, 0xc9, 0xd7, 0x53, 0xf8, 0xf5, 0xa3, 0xd6, 0xf4, 0x34, 0xf8 }, + { 0x1d, 0x14, 0xf3, 0xfd, 0xb0, 0x66, 0x20, 0xff, 0xfc, 0x79, 0x47, 0xc7, 0x4c, 0xe9, 0x45, 0x67, 0xf5, 0x97, 0x14, 0xea, 0x7c, 0x63, 0xc5, 0x3f, 0x0b, 0x46, 0xe0, 0x88, 0xd6, 0x9b, 0x67, 0x71, + 0xba, 0xa6, 0x15, 0x28, 0x94, 0x54, 0x83, 0x68, 0x00, 0x3a, 0x33, 0xa6, 0x1a, 0x05, 0x6a, 0x68, 0x72, 0x98, 0x48, 0x71, 0xea, 0x5b, 0x47, 0xf5, 0x80, 0x46, 0xa9, 0x57, 0x84, 0xec, 0xad, 0xfc }, + { 0xa3, 0x1d, 0x87, 0xd3, 0x28, 0x62, 0xc6, 0xf7, 0xdb, 0xfb, 0xfa, 0xfc, 0xf3, 0x27, 0x5c, 0x31, 0xd3, 0x32, 0x26, 0x0e, 0x0f, 0x41, 0x49, 0xec, 0x05, 0x16, 0xf7, 0xa5, 0x63, 0xb3, 0xbc, 0xe5, + 0x0d, 0x1e, 0x6f, 0x97, 0x4f, 0x68, 0x40, 0xc0, 0xd4, 0x6c, 0x4f, 0x9e, 0x25, 0xd0, 0xab, 0x8d, 0x2a, 0xb9, 0x3e, 0x06, 0x4d, 0x9d, 0x3d, 0x2d, 0x79, 0x8d, 0x93, 0xdc, 0xfc, 0x6f, 0x0b, 0x04, + 0x48, 0x7c, 0x19, 0x5c, 0xa9, 0xc8, 0x44, 0xe5, 0xf6, 0x4f, 0x51, 0xd8, 0x72, 0x63, 0x41, 0xda, 0x62, 0xac, 0x78, 0x73, 0xb3, 0x3e, 0xc8, 0xb2, 0xf1, 0x3f, 0x89, 0xf2, 0x0e, 0x95, 0xdf, 0xed }, + { 0xfd, 0x69, 0xb1, 0x9a, 0xdb, 0xae, 0x95, 0x87, 0xe2, 0xc6, 0x8a, 0x97, 0x0c, 0xee, 0xc4, 0x22, 0x60, 0x4e, 0x96, 0xa9, 0x72, 0xb9, 0x6f, 0x86, 0x97, 0xa8, 0xdf, 0x83, 0xc5, 0x18, 0x18, 0x6e, + 0xc9, 0x43, 0x30, 0x7e, 0x5b, 0xcf, 0x37, 0x0f, 0xc1, 0xd7, 0xe5, 0xab, 0xb1, 0x31, 0xe0, 0x97, 0xc7, 0x53, 0xb7, 0xfd, 0xd7, 0xdf, 0x00, 0x43, 0x0e, 0x41, 0x62, 0x80, 0x0b, 0xe3, 0xe0, 0x06, + 0x48, 0x7c, 0x19, 0x5c, 0xa9, 0xc8, 0x44, 0xe5, 0xf6, 0x4f, 0x51, 0xd8, 0x72, 0x63, 0x41, 0xda, 0x62, 0xac, 0x78, 0x73, 0xb3, 0x3e, 0xc8, 0xb2, 0xf1, 0x3f, 0x89, 0xf2, 0x0e, 0x95, 0xdf, 0xed } }, + { { 0x98, 0x29, 0xf7, 0x57, 0xfd, 0xbd, 0x44, 0x3f, 0xd9, 0x90, 0x98, 0x19, 0x97, 0xf2, 0x60, 0x27, 0xfd, 0x08, 0xfc, 0x8a, 0xc6, 0xaf, 0x87, 0x22, 0x7f, 0x74, 0x4a, 0x80, 0xaf, 0x72, 0x00, 0x01, + 0x70, 0x9b, 0x47, 0x2a, 0xd2, 0x8e, 0x41, 0x0a, 0xea, 0x6a, 0xdf, 0xb7, 0x61, 0x54, 0x89, 0x5e, 0x01, 0x9f, 0x76, 0x64, 0x29, 0xee, 0x8d, 0x85, 0x20, 0xff, 0x30, 0x58, 0xc2, 0xa3, 0x2a, 0x56 }, + { 0xea, 0x69, 0x8e, 0x6b, 0x8e, 0xdd, 0x55, 0x22, 0x45, 0x61, 0xd4, 0x92, 0x66, 0x8e, 0x96, 0xaf, 0x7e, 0x40, 0x28, 0x72, 0xc4, 0x46, 0xe7, 0x88, 0xd4, 0x6c, 0x74, 0xb7, 0x48, 0x7f, 0xe8, 0xe1, + 0x5e, 0xa5, 0x85, 0x62, 0x8f, 0xd6, 0xfc, 0x27, 0x0a, 0xb2, 0x4b, 0x38, 0x94, 0x59, 0x52, 0x0d, 0x6a, 0x4d, 0xe5, 0x61, 0xce, 0x0d, 0x44, 0x03, 0xa6, 0x2a, 0xc2, 0xd4, 0xd4, 0xe2, 0x71, 0xe3 }, + { 0x40, 0xf0, 0x82, 0xf0, 0x8d, 0xaa, 0xad, 0xa9, 0x9f, 0x9b, 0x85, 0x02, 0xcf, 0x57, 0x15, 0x41, 0x13, 0x59, 0xf2, 0xba, 0xdd, 0xbf, 0x93, 0xe5, 0x40, 0x2e, 0xaf, 0xdd, 0x43, 0x52, 0xc8, 0x7f, + 0x40, 0xad, 0x91, 0x5b, 0x58, 0xd1, 0xa1, 0xe8, 0x6f, 0x77, 0xc3, 0x41, 0x35, 0x5e, 0xf7, 0x03, 0xba, 0xe4, 0xed, 0x2c, 0x28, 0x59, 0xd6, 0x48, 0xfe, 0x50, 0xcc, 0xf9, 0x80, 0xd1, 0x49, 0xd1 }, + { 0xd7, 0xa5, 0xd9, 0x13, 0xdf, 0x7d, 0xf6, 0xc6, 0x25, 0x0f, 0x52, 0xc2, 0x57, 0x61, 0x20, 0xf2, 0xf0, 0xdb, 0x47, 0x49, 0x56, 0xaf, 0x89, 0x11, 0xa7, 0x8d, 0x09, 0x3a, 0xfe, 0x45, 0x43, 0xef, + 0x9f, 0x0c, 0x42, 0xaf, 0xa8, 0xcc, 0x60, 0x48, 0xc0, 0x1c, 0x7c, 0xbe, 0x01, 0xe2, 0x88, 0xcc, 0x6c, 0x3e, 0x97, 0x91, 0xf3, 0xd9, 0xb2, 0xb2, 0x09, 0x7e, 0x35, 0xb1, 0x78, 0xb4, 0x03, 0xf6 }, + { 0x08, 0xc4, 0x1a, 0x3a, 0xc3, 0xe3, 0x26, 0xbd, 0x8d, 0xee, 0x5d, 0xf0, 0xba, 0xb6, 0x65, 0xff, 0x77, 0xc0, 0x99, 0xd1, 0xca, 0xdc, 0xf5, 0x4b, 0x50, 0x50, 0x0a, 0x9e, 0x13, 0x33, 0x76, 0x86, + 0x9b, 0x39, 0x79, 0x78, 0x73, 0x5c, 0x2f, 0x69, 0xa9, 0x9e, 0x0b, 0xeb, 0x11, 0x1e, 0x12, 0xaa, 0xc1, 0x09, 0x83, 0x0f, 0xca, 0xcb, 0x95, 0x10, 0xde, 0x85, 0xe3, 0x75, 0x62, 0x4a, 0xc2, 0x4c }, + { 0x68, 0x78, 0x6c, 0xce, 0x2f, 0x72, 0x80, 0xfe, 0x83, 0x88, 0x63, 0x37, 0xa7, 0xa1, 0x5a, 0x0b, 0x84, 0x8a, 0xda, 0x28, 0x84, 0xf1, 0x6a, 0x63, 0x24, 0x1c, 0x72, 0xda, 0x84, 0xee, 0x1d, 0xe0, + 0x77, 0xf0, 0xf6, 0xce, 0x7e, 0x79, 0x0a, 0x55, 0x03, 0x01, 0x13, 0x0f, 0xf7, 0x6b, 0x45, 0xe7, 0xcb, 0xfd, 0xb0, 0x37, 0x93, 0x4b, 0x40, 0x69, 0xe0, 0x77, 0x67, 0x72, 0x65, 0xee, 0x35, 0x08, + 0x00, 0xc0, 0x07, 0x10, 0xd8, 0x6e, 0x55, 0x83, 0x5a, 0xbc, 0xfa, 0x67, 0x80, 0x8f, 0xfa, 0x21, 0x3e, 0x56, 0x53, 0x5b, 0xbc, 0x9d, 0xff, 0x16, 0xd9, 0x57, 0xcf, 0x2b, 0x78, 0x06, 0x5a, 0x89 }, + { 0xdf, 0x32, 0x1a, 0x01, 0x84, 0xe5, 0xb8, 0x2c, 0x70, 0x6c, 0xeb, 0xd1, 0xf0, 0xb4, 0x9b, 0x32, 0xc8, 0xd0, 0x81, 0xc4, 0xea, 0xb2, 0x7c, 0x32, 0x1a, 0x02, 0x61, 0xf2, 0xd9, 0x4d, 0xe5, 0x85, + 0xad, 0xfc, 0xc6, 0x70, 0xee, 0x85, 0x77, 0x07, 0x9b, 0x5d, 0x5f, 0x88, 0xef, 0xb6, 0xd8, 0xdf, 0x2b, 0xa2, 0x4d, 0x90, 0x11, 0x2d, 0x38, 0x3f, 0xa8, 0x84, 0xf0, 0x76, 0xdd, 0x31, 0xd0, 0x09, + 0x00, 0xc0, 0x07, 0x10, 0xd8, 0x6e, 0x55, 0x83, 0x5a, 0xbc, 0xfa, 0x67, 0x80, 0x8f, 0xfa, 0x21, 0x3e, 0x56, 0x53, 0x5b, 0xbc, 0x9d, 0xff, 0x16, 0xd9, 0x57, 0xcf, 0x2b, 0x78, 0x06, 0x5a, 0x89 } }, + { { 0x25, 0x87, 0x1e, 0x6f, 0xe8, 0xd0, 0xde, 0x1d, 0xd5, 0xf2, 0xd3, 0x5b, 0xff, 0x9e, 0x67, 0x99, 0x60, 0xb4, 0x0e, 0xb7, 0x98, 0x1b, 0x2a, 0x3a, 0x9c, 0xec, 0xc1, 0xe1, 0x2e, 0x2b, 0xc0, 0x3e, + 0x3c, 0xfb, 0x64, 0x91, 0x72, 0xc6, 0x7e, 0x57, 0x47, 0x00, 0x97, 0xbf, 0x8e, 0x0e, 0xbf, 0xad, 0xd9, 0x28, 0x86, 0x7c, 0xfd, 0x41, 0x91, 0xae, 0x2d, 0xee, 0xc0, 0xb2, 0x32, 0x7d, 0x99, 0x7d }, + { 0x63, 0xc1, 0xf9, 0x61, 0x9c, 0x9e, 0x1a, 0xd7, 0xca, 0xa3, 0x71, 0xd6, 0x34, 0x3d, 0xa7, 0x08, 0x36, 0x0c, 0xec, 0x37, 0x35, 0x94, 0x1a, 0x45, 0xa9, 0xfa, 0xf2, 0xb5, 0x25, 0x92, 0xbf, 0xd1, + 0x1e, 0xca, 0xdd, 0x5a, 0x23, 0xad, 0x9e, 0x45, 0xc3, 0x66, 0xcb, 0x8f, 0xda, 0xa3, 0xd1, 0xe6, 0x27, 0x38, 0x11, 0x54, 0x67, 0x31, 0x03, 0x64, 0x35, 0xe0, 0x68, 0x0b, 0x93, 0xee, 0x81, 0x17 }, + { 0x8b, 0x01, 0xe9, 0x99, 0x54, 0x54, 0x73, 0x15, 0x0b, 0xac, 0x38, 0x7b, 0xe9, 0xe3, 0x17, 0x4f, 0x02, 0x3e, 0xe3, 0x8e, 0xda, 0x41, 0xa0, 0x9d, 0x10, 0xe0, 0xda, 0x11, 0xfe, 0xec, 0x2f, 0x42, + 0xe7, 0xc8, 0xb3, 0xde, 0x2f, 0x7b, 0xfd, 0xdf, 0x7c, 0x34, 0x3b, 0x5e, 0xac, 0x22, 0x8c, 0x99, 0x3d, 0xa1, 0xa9, 0xd9, 0x81, 0xb6, 0x51, 0xc8, 0xaf, 0x3e, 0x75, 0xed, 0x45, 0xcf, 0xf7, 0xb9 }, + { 0xaf, 0xe9, 0x9c, 0x16, 0x4a, 0x8f, 0x3b, 0x0f, 0xef, 0x71, 0x2f, 0xaa, 0x8d, 0x7d, 0xce, 0xed, 0xea, 0x31, 0x93, 0xaf, 0x2c, 0x75, 0xc6, 0xfa, 0xda, 0x3e, 0xa6, 0xea, 0x2a, 0x3e, 0x7b, 0x72, + 0xb6, 0xf8, 0xd7, 0x9a, 0x88, 0xcb, 0x0b, 0x81, 0x97, 0x24, 0x29, 0x3b, 0x11, 0x23, 0x69, 0xc2, 0xff, 0x98, 0x39, 0x25, 0x99, 0xae, 0xe1, 0x07, 0x3e, 0x97, 0xde, 0x10, 0x21, 0x23, 0x7a, 0x2d }, + { 0xbe, 0x2f, 0xb9, 0x4c, 0x41, 0x5a, 0x9a, 0xf6, 0xfb, 0xf8, 0x26, 0x9d, 0x81, 0x7f, 0x39, 0x91, 0xaf, 0x5b, 0xf1, 0xd7, 0x93, 0x0a, 0xdf, 0x18, 0x19, 0x4a, 0x80, 0x74, 0x14, 0x98, 0x2b, 0xf2, + 0x3b, 0x25, 0xc5, 0xe8, 0xfc, 0x07, 0x3f, 0x5d, 0xa1, 0x39, 0x27, 0x4e, 0x1c, 0xd2, 0x7a, 0xfe, 0x3e, 0x7b, 0x03, 0x35, 0x15, 0x9e, 0x35, 0x2b, 0xd0, 0xbe, 0x67, 0x48, 0x42, 0xdd, 0xa4, 0xdd }, + { 0xbd, 0xcd, 0xd7, 0xbf, 0xb1, 0x0a, 0xdb, 0x9f, 0x85, 0x42, 0xba, 0xf4, 0xc8, 0xff, 0xb0, 0xe1, 0x9a, 0x18, 0x6d, 0x1a, 0xe0, 0x37, 0xc1, 0xa2, 0xe1, 0x1c, 0x38, 0x55, 0x14, 0xbf, 0x64, 0x67, + 0x84, 0x47, 0xb6, 0x0a, 0xf6, 0x93, 0xf1, 0x10, 0xab, 0x09, 0xf0, 0x60, 0x84, 0xe2, 0x4e, 0x4b, 0x5e, 0xa2, 0xd2, 0xd1, 0x19, 0x22, 0xd7, 0xc4, 0x85, 0x13, 0x23, 0xa3, 0x6a, 0xb6, 0x75, 0x0f, + 0x43, 0xe6, 0xde, 0x7b, 0x67, 0x2a, 0x73, 0x77, 0x9e, 0xb4, 0x94, 0x6c, 0xc3, 0x9a, 0x67, 0x51, 0xcf, 0xe9, 0x47, 0x46, 0x0e, 0x3a, 0x12, 0x7d, 0x7c, 0x66, 0x73, 0x6c, 0xd5, 0x4a, 0x21, 0x4d }, + { 0x89, 0x7e, 0xd0, 0xbf, 0x2e, 0x9f, 0x0c, 0xff, 0x6e, 0x56, 0x25, 0x9b, 0x79, 0x99, 0x52, 0x27, 0xc2, 0x3a, 0xaa, 0xf0, 0x47, 0x6d, 0xed, 0x05, 0xa1, 0xeb, 0x9c, 0x92, 0x28, 0x7f, 0x1b, 0xc8, + 0x1c, 0x57, 0x76, 0xab, 0x05, 0xe3, 0xd3, 0xb7, 0xa3, 0xf5, 0xac, 0xa8, 0x21, 0x33, 0x7c, 0xb7, 0xe7, 0xc2, 0xd0, 0x25, 0x6f, 0xdf, 0x34, 0xd1, 0xb0, 0x34, 0x41, 0x46, 0x30, 0x9c, 0x76, 0x07, + 0x43, 0xe6, 0xde, 0x7b, 0x67, 0x2a, 0x73, 0x77, 0x9e, 0xb4, 0x94, 0x6c, 0xc3, 0x9a, 0x67, 0x51, 0xcf, 0xe9, 0x47, 0x46, 0x0e, 0x3a, 0x12, 0x7d, 0x7c, 0x66, 0x73, 0x6c, 0xd5, 0x4a, 0x21, 0x4d } } }; ////////////////////////////////////////////////////////////////////////////// static int testCrypto() { - static unsigned char buf1[16384]; - static unsigned char buf2[sizeof(buf1)],buf3[sizeof(buf1)]; - static char hexbuf[1024]; + static unsigned char buf1[16384]; + static unsigned char buf2[sizeof(buf1)], buf3[sizeof(buf1)]; + static char hexbuf[1024]; - for(int i=0;i<3;++i) { - Utils::getSecureRandom(buf1,64); - std::cout << "[crypto] getSecureRandom: " << Utils::hex(buf1,64,hexbuf) << std::endl; - } + for (int i = 0; i < 3; ++i) { + Utils::getSecureRandom(buf1, 64); + std::cout << "[crypto] getSecureRandom: " << Utils::hex(buf1, 64, hexbuf) << std::endl; + } - std::cout << "[crypto] Testing Salsa20... "; std::cout.flush(); - for(unsigned int i=0;i<4;++i) { - for(unsigned int k=0;k= 5000) - break; - } - std::cout << (((double)bytes / 1048576.0) / ((double)(end - start) / 1024.0)) << " MiB/second" << std::endl; - } + std::cout << "[crypto] Benchmarking AES-GMAC-SIV... "; + std::cout.flush(); + { + uint64_t end, start = OSUtils::now(); + uint64_t bytes = 0; + AES k0, k1; + k0.init(buf1); + k1.init(buf2); + AES::GMACSIVEncryptor enc(k0, k1); + for (;;) { + for (unsigned int i = 0; i < 10000; ++i) { + enc.init(i, buf2); + enc.update1(buf1, sizeof(buf1)); + enc.finish1(); + enc.update2(buf1, sizeof(buf1)); + enc.finish2(); + buf1[0] = buf2[0]; + bytes += sizeof(buf1); + } + end = OSUtils::now(); + if ((end - start) >= 5000) + break; + } + std::cout << (((double)bytes / 1048576.0) / ((double)(end - start) / 1024.0)) << " MiB/second" << std::endl; + } - std::cout << "[crypto] Testing SHA-512... "; std::cout.flush(); - SHA512(buf1,sha512TV0Input,(unsigned int)strlen(sha512TV0Input)); - if (memcmp(buf1,sha512TV0Digest,64)) { - std::cout << "FAIL" << std::endl; - return -1; - } - std::cout << "PASS" << std::endl; + std::cout << "[crypto] Testing SHA-512... "; + std::cout.flush(); + SHA512(buf1, sha512TV0Input, (unsigned int)strlen(sha512TV0Input)); + if (memcmp(buf1, sha512TV0Digest, 64)) { + std::cout << "FAIL" << std::endl; + return -1; + } + std::cout << "PASS" << std::endl; - std::cout << "[crypto] Testing Poly1305... "; std::cout.flush(); - Poly1305::compute(buf1,poly1305TV0Input,sizeof(poly1305TV0Input),poly1305TV0Key); - if (memcmp(buf1,poly1305TV0Tag,16)) { - std::cout << "FAIL (1)" << std::endl; - return -1; - } - Poly1305::compute(buf1,poly1305TV1Input,sizeof(poly1305TV1Input),poly1305TV1Key); - if (memcmp(buf1,poly1305TV1Tag,16)) { - std::cout << "FAIL (2)" << std::endl; - return -1; - } - std::cout << "PASS" << std::endl; + std::cout << "[crypto] Testing Poly1305... "; + std::cout.flush(); + Poly1305::compute(buf1, poly1305TV0Input, sizeof(poly1305TV0Input), poly1305TV0Key); + if (memcmp(buf1, poly1305TV0Tag, 16)) { + std::cout << "FAIL (1)" << std::endl; + return -1; + } + Poly1305::compute(buf1, poly1305TV1Input, sizeof(poly1305TV1Input), poly1305TV1Key); + if (memcmp(buf1, poly1305TV1Tag, 16)) { + std::cout << "FAIL (2)" << std::endl; + return -1; + } + std::cout << "PASS" << std::endl; - std::cout << "[crypto] Benchmarking Poly1305... "; std::cout.flush(); - { - unsigned char *bb = (unsigned char *)::malloc(1234567); - for(unsigned int i=0;i<1234567;++i) - bb[i] = (unsigned char)i; - long double bytes = 0.0; - uint64_t start = OSUtils::now(); - for(unsigned int i=0;i<200;++i) { - Poly1305::compute(buf1,bb,1234567,poly1305TV0Key); - bytes += 1234567.0; - } - uint64_t end = OSUtils::now(); - std::cout << ((bytes / 1048576.0) / ((long double)(end - start) / 1000.0)) << " MiB/second" << std::endl; - ::free((void *)bb); - } + std::cout << "[crypto] Benchmarking Poly1305... "; + std::cout.flush(); + { + unsigned char* bb = (unsigned char*)::malloc(1234567); + for (unsigned int i = 0; i < 1234567; ++i) + bb[i] = (unsigned char)i; + long double bytes = 0.0; + uint64_t start = OSUtils::now(); + for (unsigned int i = 0; i < 200; ++i) { + Poly1305::compute(buf1, bb, 1234567, poly1305TV0Key); + bytes += 1234567.0; + } + uint64_t end = OSUtils::now(); + std::cout << ((bytes / 1048576.0) / ((long double)(end - start) / 1000.0)) << " MiB/second" << std::endl; + ::free((void*)bb); + } - /* - for(unsigned int d=8;d<=10;++d) { - for(int k=0;k<8;++k) { - std::cout << "[crypto] computeSalsa2012Sha512ProofOfWork(" << d << ",\"foobarbaz\",9) == "; std::cout.flush(); - unsigned char result[16]; - uint64_t start = OSUtils::now(); - IncomingPacket::computeSalsa2012Sha512ProofOfWork(d,"foobarbaz",9,result); - uint64_t end = OSUtils::now(); - std::cout << Utils::hex(result,16) << " -- valid: " << IncomingPacket::testSalsa2012Sha512ProofOfWorkResult(d,"foobarbaz",9,result) << ", " << (end - start) << "ms" << std::endl; - } - } - */ + /* + for(unsigned int d=8;d<=10;++d) { + for(int k=0;k<8;++k) { + std::cout << "[crypto] computeSalsa2012Sha512ProofOfWork(" << d << ",\"foobarbaz\",9) == "; std::cout.flush(); + unsigned char result[16]; + uint64_t start = OSUtils::now(); + IncomingPacket::computeSalsa2012Sha512ProofOfWork(d,"foobarbaz",9,result); + uint64_t end = OSUtils::now(); + std::cout << Utils::hex(result,16) << " -- valid: " << IncomingPacket::testSalsa2012Sha512ProofOfWorkResult(d,"foobarbaz",9,result) << ", " << (end - start) << "ms" << std::endl; + } + } + */ - std::cout << "[crypto] Testing C25519 and Ed25519 against test vectors... "; std::cout.flush(); - for(int k=0;kp2 should equal p2<>p1 - if (memcmp(buf1,buf2,64)) { - std::cout << "FAIL (1)" << std::endl; - return -1; - } - // p2<>p1 should not equal p3<>p1 - if (!memcmp(buf2,buf3,64)) { - std::cout << "FAIL (2)" << std::endl; - return -1; - } - } - std::cout << "PASS" << std::endl; + std::cout << "[crypto] Testing C25519 ECC key agreement... "; + std::cout.flush(); + for (unsigned int i = 0; i < 100; ++i) { + memset(buf1, 64, sizeof(buf1)); + memset(buf2, 64, sizeof(buf2)); + memset(buf3, 64, sizeof(buf3)); + ECC::Pair p1 = ECC::generate(); + ECC::Pair p2 = ECC::generate(); + ECC::Pair p3 = ECC::generate(); + ECC::agree(p1, p2.pub, buf1, 64); + ECC::agree(p2, p1.pub, buf2, 64); + ECC::agree(p3, p1.pub, buf3, 64); + // p1<>p2 should equal p2<>p1 + if (memcmp(buf1, buf2, 64)) { + std::cout << "FAIL (1)" << std::endl; + return -1; + } + // p2<>p1 should not equal p3<>p1 + if (! memcmp(buf2, buf3, 64)) { + std::cout << "FAIL (2)" << std::endl; + return -1; + } + } + std::cout << "PASS" << std::endl; - std::cout << "[crypto] Benchmarking C25519 ECC key agreement... "; std::cout.flush(); - C25519::Pair bp[8]; - for(int k=0;k<8;++k) - bp[k] = C25519::generate(); - uint64_t st = OSUtils::now(); - for(unsigned int k=0;k<50;++k) { - C25519::agree(bp[~k & 7],bp[k & 7].pub,buf1,64); - } - uint64_t et = OSUtils::now(); - std::cout << ((double)(et - st) / 50.0) << "ms per agreement." << std::endl; + std::cout << "[crypto] Benchmarking C25519 ECC key agreement... "; + std::cout.flush(); + ECC::Pair bp[8]; + for (int k = 0; k < 8; ++k) + bp[k] = ECC::generate(); + uint64_t st = OSUtils::now(); + for (unsigned int k = 0; k < 50; ++k) { + ECC::agree(bp[~k & 7], bp[k & 7].pub, buf1, 64); + } + uint64_t et = OSUtils::now(); + std::cout << ((double)(et - st) / 50.0) << "ms per agreement." << std::endl; - std::cout << "[crypto] Testing Ed25519 ECC signatures... "; std::cout.flush(); - C25519::Pair didntSign = C25519::generate(); - for(unsigned int i=0;i<10;++i) { - C25519::Pair p1 = C25519::generate(); - for(unsigned int k=0;k buf; - char buf2[1024]; + Identity id; + Buffer<512> buf; + char buf2[1024]; - std::cout << "[identity] Validate known-good identity... "; std::cout.flush(); - if (!id.fromString(KNOWN_GOOD_IDENTITY)) { - std::cout << "FAIL (1)" << std::endl; - return -1; - } - const uint64_t vst = OSUtils::now(); - for(int k=0;k<10;++k) { - if (!id.locallyValidate()) { - std::cout << "FAIL (2)" << std::endl; - return -1; - } - } - const uint64_t vet = OSUtils::now(); - std::cout << "PASS (" << ((double)(vet - vst) / 10.0) << "ms per validation)" << std::endl; + std::cout << "[identity] Validate known-good identity... "; + std::cout.flush(); + if (! id.fromString(KNOWN_GOOD_IDENTITY)) { + std::cout << "FAIL (1)" << std::endl; + return -1; + } + const uint64_t vst = OSUtils::now(); + for (int k = 0; k < 10; ++k) { + if (! id.locallyValidate()) { + std::cout << "FAIL (2)" << std::endl; + return -1; + } + } + const uint64_t vet = OSUtils::now(); + std::cout << "PASS (" << ((double)(vet - vst) / 10.0) << "ms per validation)" << std::endl; - std::cout << "[identity] Validate known-bad identity... "; std::cout.flush(); - if (!id.fromString(KNOWN_BAD_IDENTITY)) { - std::cout << "FAIL (1)" << std::endl; - return -1; - } - if (id.locallyValidate()) { - std::cout << "FAIL (2)" << std::endl; - return -1; - } - std::cout << "PASS (i.e. it failed)" << std::endl; + std::cout << "[identity] Validate known-bad identity... "; + std::cout.flush(); + if (! id.fromString(KNOWN_BAD_IDENTITY)) { + std::cout << "FAIL (1)" << std::endl; + return -1; + } + if (id.locallyValidate()) { + std::cout << "FAIL (2)" << std::endl; + return -1; + } + std::cout << "PASS (i.e. it failed)" << std::endl; - for(unsigned int k=0;k<4;++k) { - std::cout << "[identity] Generate identity... "; std::cout.flush(); - uint64_t genstart = OSUtils::now(); - id.generate(); - uint64_t genend = OSUtils::now(); - std::cout << "(took " << (genend - genstart) << "ms): " << id.toString(true,buf2) << std::endl; - std::cout << "[identity] Locally validate identity: "; - if (id.locallyValidate()) { - std::cout << "PASS" << std::endl; - } else { - std::cout << "FAIL" << std::endl; - return -1; - } - } + for (unsigned int k = 0; k < 4; ++k) { + std::cout << "[identity] Generate identity... "; + std::cout.flush(); + uint64_t genstart = OSUtils::now(); + id.generate(); + uint64_t genend = OSUtils::now(); + std::cout << "(took " << (genend - genstart) << "ms): " << id.toString(true, buf2) << std::endl; + std::cout << "[identity] Locally validate identity: "; + if (id.locallyValidate()) { + std::cout << "PASS" << std::endl; + } + else { + std::cout << "FAIL" << std::endl; + return -1; + } + } - { - Identity id2; - buf.clear(); - id.serialize(buf,true); - id2.deserialize(buf); - std::cout << "[identity] Serialize and deserialize (w/private): "; - if ((id == id2)&&(id2.locallyValidate())) { - std::cout << "PASS" << std::endl; - } else { - std::cout << "FAIL" << std::endl; - return -1; - } - } + { + Identity id2; + buf.clear(); + id.serialize(buf, true); + id2.deserialize(buf); + std::cout << "[identity] Serialize and deserialize (w/private): "; + if ((id == id2) && (id2.locallyValidate())) { + std::cout << "PASS" << std::endl; + } + else { + std::cout << "FAIL" << std::endl; + return -1; + } + } - { - Identity id2; - buf.clear(); - id.serialize(buf,false); - id2.deserialize(buf); - std::cout << "[identity] Serialize and deserialize (no private): "; - if ((id == id2)&&(id2.locallyValidate())) { - std::cout << "PASS" << std::endl; - } else { - std::cout << "FAIL" << std::endl; - return -1; - } - } + { + Identity id2; + buf.clear(); + id.serialize(buf, false); + id2.deserialize(buf); + std::cout << "[identity] Serialize and deserialize (no private): "; + if ((id == id2) && (id2.locallyValidate())) { + std::cout << "PASS" << std::endl; + } + else { + std::cout << "FAIL" << std::endl; + return -1; + } + } - { - Identity id2; - id2.fromString(id.toString(true,buf2)); - std::cout << "[identity] Serialize and deserialize (ASCII w/private): "; - if ((id == id2)&&(id2.locallyValidate())) { - std::cout << "PASS" << std::endl; - } else { - std::cout << "FAIL" << std::endl; - return -1; - } - } + { + Identity id2; + id2.fromString(id.toString(true, buf2)); + std::cout << "[identity] Serialize and deserialize (ASCII w/private): "; + if ((id == id2) && (id2.locallyValidate())) { + std::cout << "PASS" << std::endl; + } + else { + std::cout << "FAIL" << std::endl; + return -1; + } + } - { - Identity id2; - id2.fromString(id.toString(false,buf2)); - std::cout << "[identity] Serialize and deserialize (ASCII no private): "; - if ((id == id2)&&(id2.locallyValidate())) { - std::cout << "PASS" << std::endl; - } else { - std::cout << "FAIL" << std::endl; - return -1; - } - } + { + Identity id2; + id2.fromString(id.toString(false, buf2)); + std::cout << "[identity] Serialize and deserialize (ASCII no private): "; + if ((id == id2) && (id2.locallyValidate())) { + std::cout << "PASS" << std::endl; + } + else { + std::cout << "FAIL" << std::endl; + return -1; + } + } - return 0; + return 0; } static int testCertificate() { - char buf[4096]; + char buf[4096]; - Identity authority; - std::cout << "[certificate] Generating identity to act as authority... "; std::cout.flush(); - authority.generate(); - std::cout << authority.address().toString(buf) << std::endl; + Identity authority; + std::cout << "[certificate] Generating identity to act as authority... "; + std::cout.flush(); + authority.generate(); + std::cout << authority.address().toString(buf) << std::endl; - Identity idA,idB; - std::cout << "[certificate] Generating identities A and B... "; std::cout.flush(); - idA.generate(); - idB.generate(); - std::cout << idA.address().toString(buf) << ", " << idB.address().toString(buf) << std::endl; + Identity idA, idB; + std::cout << "[certificate] Generating identities A and B... "; + std::cout.flush(); + idA.generate(); + idB.generate(); + std::cout << idA.address().toString(buf) << ", " << idB.address().toString(buf) << std::endl; - std::cout << "[certificate] Generating certificates A and B..."; - CertificateOfMembership cA(10000,100,1,idA); - CertificateOfMembership cB(10099,100,1,idB); - std::cout << std::endl; + std::cout << "[certificate] Generating certificates A and B..."; + CertificateOfMembership cA(10000, 100, 1, idA); + CertificateOfMembership cB(10099, 100, 1, idB); + std::cout << std::endl; - std::cout << "[certificate] Signing certificates A and B with authority..."; - cA.sign(authority); - cB.sign(authority); - std::cout << std::endl; + std::cout << "[certificate] Signing certificates A and B with authority..."; + cA.sign(authority); + cB.sign(authority); + std::cout << std::endl; - //std::cout << "[certificate] A: " << cA.toString() << std::endl; - //std::cout << "[certificate] B: " << cB.toString() << std::endl; + // std::cout << "[certificate] A: " << cA.toString() << std::endl; + // std::cout << "[certificate] B: " << cB.toString() << std::endl; - std::cout << "[certificate] A agrees with B and B with A... "; - if (cA.agreesWith(cB, idB)) - std::cout << "yes, "; - else { - std::cout << "FAIL" << std::endl; - return -1; - } - if (cB.agreesWith(cA, idA)) - std::cout << "yes." << std::endl; - else { - std::cout << "FAIL" << std::endl; - return -1; - } + std::cout << "[certificate] A agrees with B and B with A... "; + if (cA.agreesWith(cB, idB)) + std::cout << "yes, "; + else { + std::cout << "FAIL" << std::endl; + return -1; + } + if (cB.agreesWith(cA, idA)) + std::cout << "yes." << std::endl; + else { + std::cout << "FAIL" << std::endl; + return -1; + } - std::cout << "[certificate] Generating two certificates that should not agree..."; - cA = CertificateOfMembership(10000,100,1,idA); - cB = CertificateOfMembership(10101,100,1,idB); - std::cout << std::endl; + std::cout << "[certificate] Generating two certificates that should not agree..."; + cA = CertificateOfMembership(10000, 100, 1, idA); + cB = CertificateOfMembership(10101, 100, 1, idB); + std::cout << std::endl; - std::cout << "[certificate] A agrees with B and B with A... "; - if (!cA.agreesWith(cB, idB)) - std::cout << "no, "; - else { - std::cout << "FAIL" << std::endl; - return -1; - } - if (!cB.agreesWith(cA, idA)) - std::cout << "no." << std::endl; - else { - std::cout << "FAIL" << std::endl; - return -1; - } + std::cout << "[certificate] A agrees with B and B with A... "; + if (! cA.agreesWith(cB, idB)) + std::cout << "no, "; + else { + std::cout << "FAIL" << std::endl; + return -1; + } + if (! cB.agreesWith(cA, idA)) + std::cout << "no." << std::endl; + else { + std::cout << "FAIL" << std::endl; + return -1; + } - return 0; + return 0; } static int testPacket() { - unsigned char salsaKey[32]; - Packet a,b; + unsigned char salsaKey[32]; + Packet a, b; - a.burn(); - b.burn(); + a.burn(); + b.burn(); - for(unsigned int i=0;i<32;++i) - salsaKey[i] = (unsigned char)rand(); + for (unsigned int i = 0; i < 32; ++i) + salsaKey[i] = (unsigned char)rand(); - std::cout << "[packet] Testing Packet encoder/decoder... "; + std::cout << "[packet] Testing Packet encoder/decoder... "; - a.reset(Address(),Address(),Packet::VERB_HELLO); - for(int i=0;i<32;++i) - a.append("supercalifragilisticexpealidocious",(unsigned int)strlen("supercalifragilisticexpealidocious")); + a.reset(Address(), Address(), Packet::VERB_HELLO); + for (int i = 0; i < 32; ++i) + a.append("supercalifragilisticexpealidocious", (unsigned int)strlen("supercalifragilisticexpealidocious")); - b = a; - if (a != b) { - std::cout << "FAIL (assign)" << std::endl; - return -1; - } + b = a; + if (a != b) { + std::cout << "FAIL (assign)" << std::endl; + return -1; + } - a.compress(); - unsigned int complen = a.size(); - a.uncompress(); + a.compress(); + unsigned int complen = a.size(); + a.uncompress(); - std::cout << "(compressed: " << complen << ", decompressed: " << a.size() << ") "; - if (a != b) { - std::cout << "FAIL (compression)" << std::endl; - return -1; - } + std::cout << "(compressed: " << complen << ", decompressed: " << a.size() << ") "; + if (a != b) { + std::cout << "FAIL (compression)" << std::endl; + return -1; + } - a.armor(salsaKey,true,nullptr); - if (!a.dearmor(salsaKey,nullptr)) { - std::cout << "FAIL (encrypt-decrypt/verify)" << std::endl; - return -1; - } + /* + a.armor(salsaKey, true, false, nullptr); + if (! a.dearmor(salsaKey, nullptr)) { + std::cout << "FAIL (encrypt-decrypt/verify)" << std::endl; + return -1; + } + */ - std::cout << "PASS" << std::endl; - return 0; + std::cout << "PASS" << std::endl; + return 0; } static int testOther() { - char buf[1024]; - char buf2[4096]; - char buf3[1024]; + char buf[1024]; + char buf2[4096]; + char buf3[1024]; - std::cout << "[other] Testing hex/unhex... "; std::cout.flush(); - Utils::getSecureRandom(buf,(unsigned int)sizeof(buf)); - Utils::hex(buf,(unsigned int)sizeof(buf),buf2); - Utils::unhex(buf2,buf3,(unsigned int)sizeof(buf3)); - if (memcmp(buf,buf3,sizeof(buf)) == 0) { - std::cout << "PASS" << std::endl; - } else { - std::cout << "FAIL!" << std::endl; - buf2[78] = 0; - std::cout << buf2 << std::endl; - Utils::hex(buf3,(unsigned int)sizeof(buf3),buf2); - buf2[78] = 0; - std::cout << buf2 << std::endl; - return -1; - } + std::cout << "[other] Testing hex/unhex... "; + std::cout.flush(); + Utils::getSecureRandom(buf, (unsigned int)sizeof(buf)); + Utils::hex(buf, (unsigned int)sizeof(buf), buf2); + Utils::unhex(buf2, buf3, (unsigned int)sizeof(buf3)); + if (memcmp(buf, buf3, sizeof(buf)) == 0) { + std::cout << "PASS" << std::endl; + } + else { + std::cout << "FAIL!" << std::endl; + buf2[78] = 0; + std::cout << buf2 << std::endl; + Utils::hex(buf3, (unsigned int)sizeof(buf3), buf2); + buf2[78] = 0; + std::cout << buf2 << std::endl; + return -1; + } - std::cout << "[other] Testing InetAddress encode/decode..."; std::cout.flush(); - std::cout << " " << InetAddress("127.0.0.1/9993").toString(buf); - std::cout << " " << InetAddress("feed:dead:babe:dead:beef:f00d:1234:5678/12345").toString(buf); - std::cout << " " << InetAddress("0/9993").toString(buf); - std::cout << " " << InetAddress("").toString(buf); - std::cout << std::endl; + std::cout << "[other] Testing InetAddress encode/decode..."; + std::cout.flush(); + std::cout << " " << InetAddress("127.0.0.1/9993").toString(buf); + std::cout << " " << InetAddress("feed:dead:babe:dead:beef:f00d:1234:5678/12345").toString(buf); + std::cout << " " << InetAddress("0/9993").toString(buf); + std::cout << " " << InetAddress("").toString(buf); + std::cout << std::endl; #if 0 std::cout << "[other] Testing Hashtable... "; std::cout.flush(); @@ -876,286 +1395,303 @@ static int testOther() std::cout << "PASS" << std::endl; #endif - std::cout << "[other] Testing/fuzzing Dictionary... "; std::cout.flush(); - for(int k=0;k<1000;++k) { - Dictionary<8194> *test = new Dictionary<8194>(); - char key[32][16]; - char value[32][128]; - memset(key, 0, sizeof(key)); - memset(value, 0, sizeof(value)); - for(unsigned int q=0;q<32;++q) { - Utils::hex((uint32_t)((rand() % 1000) + (q * 1000)),key[q]); - int r = rand() % 128; - for(int x=0;xadd(key[q],value[q],r); - } - for(unsigned int q=0;q<1024;++q) { - int r = rand() % 32; - char tmp[128]; - if (test->get(key[r],tmp,sizeof(tmp)) >= 0) { - if (strcmp(value[r],tmp)) { - std::cout << "FAILED (invalid value '" << value[r] << "' != '" << tmp << "')!" << std::endl; - return -1; - } - } else { - std::cout << "FAILED (can't find key '" << key[r] << "')!" << std::endl; - return -1; - } - } - delete test; - } - int foo = 0; - volatile int *volatile bar = &foo; // force compiler not to optimize out test.get() below - for(int k=0;k<200;++k) { - int r = rand() % 8194; - unsigned char *tmp = new unsigned char[8194]; - for(int q=0;q *test = new Dictionary<8194>((const char *)tmp); - for(unsigned int q=0;q<100;++q) { - char tmp[128]; - for(unsigned int x=0;x<128;++x) - tmp[x] = (char)(rand() & 0xff); - tmp[127] = (char)0; - char value[8194]; - *bar += test->get(tmp,value,sizeof(value)); - } - delete test; - delete[] tmp; - } - std::cout << "PASS (junk value to prevent optimization-out of test: " << foo << ")" << std::endl; + std::cout << "[other] Testing/fuzzing Dictionary... "; + std::cout.flush(); + for (int k = 0; k < 1000; ++k) { + Dictionary<8194>* test = new Dictionary<8194>(); + char key[32][16]; + char value[32][128]; + memset(key, 0, sizeof(key)); + memset(value, 0, sizeof(value)); + for (unsigned int q = 0; q < 32; ++q) { + Utils::hex((uint32_t)((rand() % 1000) + (q * 1000)), key[q]); + int r = rand() % 128; + for (int x = 0; x < r; ++x) + value[q][x] = ("0123456789\0\t\r\n= ")[rand() % 16]; + value[q][r] = (char)0; + test->add(key[q], value[q], r); + } + for (unsigned int q = 0; q < 1024; ++q) { + int r = rand() % 32; + char tmp[128]; + if (test->get(key[r], tmp, sizeof(tmp)) >= 0) { + if (strcmp(value[r], tmp)) { + std::cout << "FAILED (invalid value '" << value[r] << "' != '" << tmp << "')!" << std::endl; + return -1; + } + } + else { + std::cout << "FAILED (can't find key '" << key[r] << "')!" << std::endl; + return -1; + } + } + delete test; + } + int foo = 0; + volatile int* volatile bar = &foo; // force compiler not to optimize out test.get() below + for (int k = 0; k < 200; ++k) { + int r = rand() % 8194; + unsigned char* tmp = new unsigned char[8194]; + for (int q = 0; q < r; ++q) + tmp[q] = (unsigned char)((rand() % 254) + 1); // don't put nulls since those will always just terminate scan + tmp[r] = (r % 32) ? (char)(rand() & 0xff) : (char)0; // every 32nd iteration don't terminate the string maybe... + Dictionary<8194>* test = new Dictionary<8194>((const char*)tmp); + for (unsigned int q = 0; q < 100; ++q) { + char tmp[128]; + for (unsigned int x = 0; x < 128; ++x) + tmp[x] = (char)(rand() & 0xff); + tmp[127] = (char)0; + char value[8194]; + *bar += test->get(tmp, value, sizeof(value)); + } + delete test; + delete[] tmp; + } + std::cout << "PASS (junk value to prevent optimization-out of test: " << foo << ")" << std::endl; - return 0; + return 0; } -#define ZT_TEST_PHY_NUM_UDP_PACKETS 10000 -#define ZT_TEST_PHY_UDP_PACKET_SIZE 1000 -#define ZT_TEST_PHY_NUM_VALID_TCP_CONNECTS 10 +#define ZT_TEST_PHY_NUM_UDP_PACKETS 10000 +#define ZT_TEST_PHY_UDP_PACKET_SIZE 1000 +#define ZT_TEST_PHY_NUM_VALID_TCP_CONNECTS 10 #define ZT_TEST_PHY_NUM_INVALID_TCP_CONNECTS 2 -#define ZT_TEST_PHY_TCP_MESSAGE_SIZE 1000000 -#define ZT_TEST_PHY_TIMEOUT_MS 20000 +#define ZT_TEST_PHY_TCP_MESSAGE_SIZE 1000000 +#define ZT_TEST_PHY_TIMEOUT_MS 20000 static unsigned long phyTestUdpPacketCount = 0; static unsigned long phyTestTcpByteCount = 0; static unsigned long phyTestTcpConnectSuccessCount = 0; static unsigned long phyTestTcpConnectFailCount = 0; static unsigned long phyTestTcpAcceptCount = 0; struct TestPhyHandlers; -static Phy *testPhyInstance = (Phy *)0; -struct TestPhyHandlers -{ - inline void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len) - { - ++phyTestUdpPacketCount; - } +static Phy* testPhyInstance = (Phy*)0; +struct TestPhyHandlers { + inline void phyOnDatagram(PhySocket* sock, void** uptr, const struct sockaddr* localAddr, const struct sockaddr* from, void* data, unsigned long len) + { + ++phyTestUdpPacketCount; + } - inline void phyOnTcpConnect(PhySocket *sock,void **uptr,bool success) - { - if (success) { - ++phyTestTcpConnectSuccessCount; - } else { - ++phyTestTcpConnectFailCount; - } - } + inline void phyOnTcpConnect(PhySocket* sock, void** uptr, bool success) + { + if (success) { + ++phyTestTcpConnectSuccessCount; + } + else { + ++phyTestTcpConnectFailCount; + } + } - inline void phyOnTcpAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN,const struct sockaddr *from) - { - ++phyTestTcpAcceptCount; - *uptrN = new std::string(ZT_TEST_PHY_TCP_MESSAGE_SIZE,(char)0xff); - testPhyInstance->setNotifyWritable(sockN,true); - } + inline void phyOnTcpAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN, const struct sockaddr* from) + { + ++phyTestTcpAcceptCount; + *uptrN = new std::string(ZT_TEST_PHY_TCP_MESSAGE_SIZE, (char)0xff); + testPhyInstance->setNotifyWritable(sockN, true); + } - inline void phyOnTcpClose(PhySocket *sock,void **uptr) - { - delete (std::string *)*uptr; // delete testMessage if any - } + inline void phyOnTcpClose(PhySocket* sock, void** uptr) + { + delete (std::string*)*uptr; // delete testMessage if any + } - inline void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len) - { - phyTestTcpByteCount += len; - } + inline void phyOnTcpData(PhySocket* sock, void** uptr, void* data, unsigned long len) + { + phyTestTcpByteCount += len; + } - inline void phyOnTcpWritable(PhySocket *sock,void **uptr) - { - std::string *testMessage = (std::string *)*uptr; - if ((testMessage)&&(testMessage->length() > 0)) { - long sent = testPhyInstance->streamSend(sock,(const void *)testMessage->data(),(unsigned long)testMessage->length(),true); - if (sent > 0) - testMessage->erase(0,sent); - } - if ((!testMessage)||(!testMessage->length())) { - testPhyInstance->close(sock,true); - } - } + inline void phyOnTcpWritable(PhySocket* sock, void** uptr) + { + std::string* testMessage = (std::string*)*uptr; + if ((testMessage) && (testMessage->length() > 0)) { + long sent = testPhyInstance->streamSend(sock, (const void*)testMessage->data(), (unsigned long)testMessage->length(), true); + if (sent > 0) + testMessage->erase(0, sent); + } + if ((! testMessage) || (! testMessage->length())) { + testPhyInstance->close(sock, true); + } + } #ifdef __UNIX_LIKE__ - inline void phyOnUnixAccept(PhySocket *sockL,PhySocket *sockN,void **uptrL,void **uptrN) {} - inline void phyOnUnixClose(PhySocket *sock,void **uptr) {} - inline void phyOnUnixData(PhySocket *sock,void **uptr,void *data,unsigned long len) {} - inline void phyOnUnixWritable(PhySocket *sock,void **uptr) {} -#endif // __UNIX_LIKE__ + inline void phyOnUnixAccept(PhySocket* sockL, PhySocket* sockN, void** uptrL, void** uptrN) + { + } + inline void phyOnUnixClose(PhySocket* sock, void** uptr) + { + } + inline void phyOnUnixData(PhySocket* sock, void** uptr, void* data, unsigned long len) + { + } + inline void phyOnUnixWritable(PhySocket* sock, void** uptr) + { + } +#endif // __UNIX_LIKE__ - inline void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable) {} + inline void phyOnFileDescriptorActivity(PhySocket* sock, void** uptr, bool readable, bool writable) + { + } }; static int testPhy() { - char udpTestPayload[ZT_TEST_PHY_UDP_PACKET_SIZE]; - memset(udpTestPayload,0xff,sizeof(udpTestPayload)); + char udpTestPayload[ZT_TEST_PHY_UDP_PACKET_SIZE]; + memset(udpTestPayload, 0xff, sizeof(udpTestPayload)); - struct sockaddr_in bindaddr; - memset(&bindaddr,0,sizeof(bindaddr)); - bindaddr.sin_family = AF_INET; - bindaddr.sin_port = Utils::hton((uint16_t)60002); - bindaddr.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); - struct sockaddr_in invalidAddr; - memset(&bindaddr,0,sizeof(bindaddr)); - bindaddr.sin_family = AF_INET; - bindaddr.sin_port = Utils::hton((uint16_t)60004); - bindaddr.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); + struct sockaddr_in bindaddr; + memset(&bindaddr, 0, sizeof(bindaddr)); + bindaddr.sin_family = AF_INET; + bindaddr.sin_port = Utils::hton((uint16_t)60002); + bindaddr.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); + struct sockaddr_in invalidAddr; + memset(&bindaddr, 0, sizeof(bindaddr)); + bindaddr.sin_family = AF_INET; + bindaddr.sin_port = Utils::hton((uint16_t)60004); + bindaddr.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); - std::cout << "[phy] Creating phy endpoint..." << std::endl; - TestPhyHandlers testPhyHandlers; - testPhyInstance = new Phy(&testPhyHandlers,false,true); + std::cout << "[phy] Creating phy endpoint..." << std::endl; + TestPhyHandlers testPhyHandlers; + testPhyInstance = new Phy(&testPhyHandlers, false, true); - std::cout << "[phy] Binding UDP listen socket to 127.0.0.1/60002... "; - PhySocket *udpListenSock = testPhyInstance->udpBind((const struct sockaddr *)&bindaddr); - if (!udpListenSock) { - std::cout << "FAILED." << std::endl; - return -1; - } - std::cout << "OK" << std::endl; + std::cout << "[phy] Binding UDP listen socket to 127.0.0.1/60002... "; + PhySocket* udpListenSock = testPhyInstance->udpBind((const struct sockaddr*)&bindaddr); + if (! udpListenSock) { + std::cout << "FAILED." << std::endl; + return -1; + } + std::cout << "OK" << std::endl; - std::cout << "[phy] Binding TCP listen socket to 127.0.0.1/60002... "; - PhySocket *tcpListenSock = testPhyInstance->tcpListen((const struct sockaddr *)&bindaddr); - if (!tcpListenSock) { - std::cout << "FAILED." << std::endl; - return -1; - } - std::cout << "OK" << std::endl; + std::cout << "[phy] Binding TCP listen socket to 127.0.0.1/60002... "; + PhySocket* tcpListenSock = testPhyInstance->tcpListen((const struct sockaddr*)&bindaddr); + if (! tcpListenSock) { + std::cout << "FAILED." << std::endl; + return -1; + } + std::cout << "OK" << std::endl; - unsigned long phyTestUdpPacketsSent = 0; - unsigned long phyTestTcpValidConnectionsAttempted = 0; - unsigned long phyTestTcpInvalidConnectionsAttempted = 0; + unsigned long phyTestUdpPacketsSent = 0; + unsigned long phyTestTcpValidConnectionsAttempted = 0; + unsigned long phyTestTcpInvalidConnectionsAttempted = 0; - std::cout << "[phy] Testing UDP send/receive... "; std::cout.flush(); - uint64_t timeoutAt = OSUtils::now() + ZT_TEST_PHY_TIMEOUT_MS; - while ((OSUtils::now() < timeoutAt)&&(phyTestUdpPacketCount < ZT_TEST_PHY_NUM_UDP_PACKETS)) { - if (phyTestUdpPacketsSent < ZT_TEST_PHY_NUM_UDP_PACKETS) { - if (!testPhyInstance->udpSend(udpListenSock,(const struct sockaddr *)&bindaddr,udpTestPayload,sizeof(udpTestPayload))) { - std::cout << "FAILED." << std::endl; - return -1; - } else ++phyTestUdpPacketsSent; - } - testPhyInstance->poll(100); - } - std::cout << "got " << phyTestUdpPacketCount << " packets, OK" << std::endl; + std::cout << "[phy] Testing UDP send/receive... "; + std::cout.flush(); + uint64_t timeoutAt = OSUtils::now() + ZT_TEST_PHY_TIMEOUT_MS; + while ((OSUtils::now() < timeoutAt) && (phyTestUdpPacketCount < ZT_TEST_PHY_NUM_UDP_PACKETS)) { + if (phyTestUdpPacketsSent < ZT_TEST_PHY_NUM_UDP_PACKETS) { + if (! testPhyInstance->udpSend(udpListenSock, (const struct sockaddr*)&bindaddr, udpTestPayload, sizeof(udpTestPayload))) { + std::cout << "FAILED." << std::endl; + return -1; + } + else + ++phyTestUdpPacketsSent; + } + testPhyInstance->poll(100); + } + std::cout << "got " << phyTestUdpPacketCount << " packets, OK" << std::endl; - std::cout << "[phy] Testing TCP... "; std::cout.flush(); - timeoutAt = OSUtils::now() + ZT_TEST_PHY_TIMEOUT_MS; - while ((OSUtils::now() < timeoutAt)&&(phyTestTcpByteCount < (ZT_TEST_PHY_NUM_VALID_TCP_CONNECTS * ZT_TEST_PHY_TCP_MESSAGE_SIZE))) { - if (phyTestTcpValidConnectionsAttempted < ZT_TEST_PHY_NUM_VALID_TCP_CONNECTS) { - ++phyTestTcpValidConnectionsAttempted; - bool connected = false; - if (!testPhyInstance->tcpConnect((const struct sockaddr *)&bindaddr,connected,(void *)0,true)) - ++phyTestTcpConnectFailCount; - } - if (phyTestTcpInvalidConnectionsAttempted < ZT_TEST_PHY_NUM_INVALID_TCP_CONNECTS) { - ++phyTestTcpInvalidConnectionsAttempted; - bool connected = false; - if (!testPhyInstance->tcpConnect((const struct sockaddr *)&invalidAddr,connected,(void *)0,true)) - ++phyTestTcpConnectFailCount; - } - testPhyInstance->poll(100); - } - if (phyTestTcpByteCount < (ZT_TEST_PHY_NUM_VALID_TCP_CONNECTS * ZT_TEST_PHY_TCP_MESSAGE_SIZE)) { - std::cout << "got " << phyTestTcpConnectSuccessCount << " connect successes, " << phyTestTcpConnectFailCount << " failures, and " << phyTestTcpByteCount << " bytes, FAILED." << std::endl; - return -1; - } else { - std::cout << "got " << phyTestTcpConnectSuccessCount << " connect successes, " << phyTestTcpConnectFailCount << " failures, and " << phyTestTcpByteCount << " bytes, OK" << std::endl; - } + std::cout << "[phy] Testing TCP... "; + std::cout.flush(); + timeoutAt = OSUtils::now() + ZT_TEST_PHY_TIMEOUT_MS; + while ((OSUtils::now() < timeoutAt) && (phyTestTcpByteCount < (ZT_TEST_PHY_NUM_VALID_TCP_CONNECTS * ZT_TEST_PHY_TCP_MESSAGE_SIZE))) { + if (phyTestTcpValidConnectionsAttempted < ZT_TEST_PHY_NUM_VALID_TCP_CONNECTS) { + ++phyTestTcpValidConnectionsAttempted; + bool connected = false; + if (! testPhyInstance->tcpConnect((const struct sockaddr*)&bindaddr, connected, (void*)0, true)) + ++phyTestTcpConnectFailCount; + } + if (phyTestTcpInvalidConnectionsAttempted < ZT_TEST_PHY_NUM_INVALID_TCP_CONNECTS) { + ++phyTestTcpInvalidConnectionsAttempted; + bool connected = false; + if (! testPhyInstance->tcpConnect((const struct sockaddr*)&invalidAddr, connected, (void*)0, true)) + ++phyTestTcpConnectFailCount; + } + testPhyInstance->poll(100); + } + if (phyTestTcpByteCount < (ZT_TEST_PHY_NUM_VALID_TCP_CONNECTS * ZT_TEST_PHY_TCP_MESSAGE_SIZE)) { + std::cout << "got " << phyTestTcpConnectSuccessCount << " connect successes, " << phyTestTcpConnectFailCount << " failures, and " << phyTestTcpByteCount << " bytes, FAILED." << std::endl; + return -1; + } + else { + std::cout << "got " << phyTestTcpConnectSuccessCount << " connect successes, " << phyTestTcpConnectFailCount << " failures, and " << phyTestTcpByteCount << " bytes, OK" << std::endl; + } - return 0; + return 0; } #ifdef __WINDOWS__ int __cdecl _tmain(int argc, _TCHAR* argv[]) #else -int main(int argc,char **argv) +int main(int argc, char** argv) #endif { - int r = 0; + int r = 0; #ifdef __WINDOWS__ - WSADATA wsaData; - WSAStartup(MAKEWORD(2,2),&wsaData); + WSADATA wsaData; + WSAStartup(MAKEWORD(2, 2), &wsaData); #endif - // Code to generate the C25519 test vectors -- did this once and then - // put these up top so that we can ensure that every platform produces - // the same result. - /* - for(int k=0;k<32;++k) { - C25519::Pair p1 = C25519::generate(); - C25519::Pair p2 = C25519::generate(); - unsigned char agg[64]; - C25519::agree(p1,p2.pub,agg,64); - C25519::Signature sig1 = C25519::sign(p1,agg,64); - C25519::Signature sig2 = C25519::sign(p2,agg,64); - printf("{{"); - for(int i=0;i<64;++i) - printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)p1.pub.data[i]); - printf("},{"); - for(int i=0;i<64;++i) - printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)p1.priv.data[i]); - printf("},{"); - for(int i=0;i<64;++i) - printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)p2.pub.data[i]); - printf("},{"); - for(int i=0;i<64;++i) - printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)p2.priv.data[i]); - printf("},{"); - for(int i=0;i<64;++i) - printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)agg[i]); - printf("},{"); - for(int i=0;i<96;++i) - printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)sig1.data[i]); - printf("},{"); - for(int i=0;i<96;++i) - printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)sig2.data[i]); - printf("}}\n"); - } - exit(0); - */ + // Code to generate the C25519 test vectors -- did this once and then + // put these up top so that we can ensure that every platform produces + // the same result. + /* + for(int k=0;k<32;++k) { + ECC::Pair p1 = ECC::generate(); + ECC::Pair p2 = ECC::generate(); + unsigned char agg[64]; + ECC::agree(p1,p2.pub,agg,64); + ECC::Signature sig1 = ECC::sign(p1,agg,64); + ECC::Signature sig2 = ECC::sign(p2,agg,64); + printf("{{"); + for(int i=0;i<64;++i) + printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)p1.pub.data[i]); + printf("},{"); + for(int i=0;i<64;++i) + printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)p1.priv.data[i]); + printf("},{"); + for(int i=0;i<64;++i) + printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)p2.pub.data[i]); + printf("},{"); + for(int i=0;i<64;++i) + printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)p2.priv.data[i]); + printf("},{"); + for(int i=0;i<64;++i) + printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)agg[i]); + printf("},{"); + for(int i=0;i<96;++i) + printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)sig1.data[i]); + printf("},{"); + for(int i=0;i<96;++i) + printf("%s0x%.2x",((i > 0) ? "," : ""),(unsigned int)sig2.data[i]); + printf("}}\n"); + } + exit(0); + */ - std::cout << "[info] sizeof(void *) == " << sizeof(void *) << std::endl; - std::cout << "[info] OSUtils::now() == " << OSUtils::now() << std::endl; - std::cout << "[info] hardware concurrency == " << std::thread::hardware_concurrency() << std::endl; - std::cout << "[info] sizeof(NetworkConfig) == " << sizeof(ZeroTier::NetworkConfig) << std::endl; + std::cout << "[info] sizeof(void *) == " << sizeof(void*) << std::endl; + std::cout << "[info] OSUtils::now() == " << OSUtils::now() << std::endl; + std::cout << "[info] hardware concurrency == " << std::thread::hardware_concurrency() << std::endl; + std::cout << "[info] sizeof(NetworkConfig) == " << sizeof(ZeroTier::NetworkConfig) << std::endl; - srand((unsigned int)time(0)); + srand((unsigned int)time(0)); - ///* - r |= testOther(); - r |= testCrypto(); - r |= testPacket(); - r |= testIdentity(); - r |= testCertificate(); - r |= testPhy(); - //*/ + ///* + r |= testOther(); + r |= testCrypto(); + r |= testPacket(); + r |= testIdentity(); + r |= testCertificate(); + r |= testPhy(); + //*/ - if (r) - std::cout << std::endl << "SOMETHING FAILED!" << std::endl; + if (r) + std::cout << std::endl << "SOMETHING FAILED!" << std::endl; - /* + /* #ifdef ZT_USE_MINIUPNPC - std::cout << std::endl; - std::cout << "[portmapper] Starting port mapper and waiting forever... use CTRL+C to exit. (enable ZT_PORTMAPPER_TRACE in PortMapper.cpp for output)" << std::endl; - PortMapper mapper(12345,"ZeroTier/__selftest"); - Thread::sleep(0xffffffff); + std::cout << std::endl; + std::cout << "[portmapper] Starting port mapper and waiting forever... use CTRL+C to exit. (enable ZT_PORTMAPPER_TRACE in PortMapper.cpp for output)" << std::endl; + PortMapper mapper(12345,"ZeroTier/__selftest"); + Thread::sleep(0xffffffff); #endif - */ + */ - return r; + return r; } diff --git a/service/OneService.cpp b/service/OneService.cpp index a089d11a8..69a0daca0 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -709,8 +709,8 @@ static void _moonToJson(nlohmann::json& mj, const World& world) OSUtils::ztsnprintf(tmp, sizeof(tmp), "%.16llx", world.id()); mj["id"] = tmp; mj["timestamp"] = world.timestamp(); - mj["signature"] = Utils::hex(world.signature().data, ZT_C25519_SIGNATURE_LEN, tmp); - mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data, ZT_C25519_PUBLIC_KEY_LEN, tmp); + mj["signature"] = Utils::hex(world.signature().data, ZT_ECC_SIGNATURE_LEN, tmp); + mj["updatesMustBeSignedBy"] = Utils::hex(world.updatesMustBeSignedBy().data, ZT_ECC_PUBLIC_KEY_SET_LEN, tmp); nlohmann::json ra = nlohmann::json::array(); for (std::vector::const_iterator r(world.roots().begin()); r != world.roots().end(); ++r) { nlohmann::json rj; diff --git a/version.h b/version.h index 6027e70ea..8da788867 100644 --- a/version.h +++ b/version.h @@ -22,7 +22,7 @@ /** * Minor version */ -#define ZEROTIER_ONE_VERSION_MINOR 14 +#define ZEROTIER_ONE_VERSION_MINOR 15 /** * Revision diff --git a/windows/ZeroTierOne/ZeroTierOne.vcxproj b/windows/ZeroTierOne/ZeroTierOne.vcxproj index 2dd05aa57..69db06168 100644 --- a/windows/ZeroTierOne/ZeroTierOne.vcxproj +++ b/windows/ZeroTierOne/ZeroTierOne.vcxproj @@ -66,17 +66,10 @@ - - MaxSpeed - MaxSpeed - MaxSpeed - Default - Default - Default - + @@ -200,7 +193,7 @@ - + diff --git a/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters b/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters index 1b1bb507a..9f05b729a 100644 --- a/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters +++ b/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters @@ -96,9 +96,6 @@ Source Files\osdep - - Source Files\node - Source Files\node @@ -297,6 +294,9 @@ Source Files\node + + Source Files\node + @@ -335,7 +335,7 @@ Header Files\node - + Header Files\node diff --git a/windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj b/windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj index bc719b6ec..9e3a12707 100644 --- a/windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj +++ b/windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj @@ -168,7 +168,7 @@ - + @@ -254,4 +254,4 @@ - \ No newline at end of file + diff --git a/windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj.filters b/windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj.filters index d7e947f3f..7276ba315 100644 --- a/windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj.filters +++ b/windows/ZeroTierOneSDK/ZeroTierOneSDK.vcxproj.filters @@ -42,7 +42,7 @@ Header Files - + Header Files @@ -237,4 +237,4 @@ Source Files - \ No newline at end of file +