mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-12-23 15:15:18 +00:00
v1.4.19
This commit is contained in:
parent
58456c1057
commit
ebb31fd792
@ -1,6 +1,9 @@
|
||||
.config*
|
||||
**/.config*
|
||||
**/.idea
|
||||
**/.vscode
|
||||
github.env
|
||||
Taskfile.yaml
|
||||
|
||||
# Rust
|
||||
target
|
||||
vdf/generated
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -8,3 +8,7 @@ ceremony-client
|
||||
.env.signers
|
||||
.task
|
||||
node-tmp-*
|
||||
build
|
||||
|
||||
# Rust
|
||||
target
|
||||
|
39
CONTRIBUTING.md
Normal file
39
CONTRIBUTING.md
Normal file
@ -0,0 +1,39 @@
|
||||
# Contributing
|
||||
|
||||
## Testing
|
||||
|
||||
Testing the [`vdf`](./vdf) and [`node`](./node) packages requires linking the
|
||||
[native VDF](./crates/vdf). The `test.sh` scripts in the respective directories
|
||||
help with this.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Contributions are welcome – a new network is rife with opportunities. We are
|
||||
in the process of updating our JIRA board so that it can be made public. The
|
||||
repository has basic coding guidelines:
|
||||
|
||||
- 80 character line limit, with the exception where gofmt or the syntax is
|
||||
impossible to achieve otherwise
|
||||
- Error wrapping matching function names
|
||||
- Interface composition and dependency injection with Wire
|
||||
|
||||
## Building release binaries
|
||||
|
||||
The following software is required to build release binaries (assuming MacOS
|
||||
ARM):
|
||||
|
||||
- [Running from source](README.md#running-from-source) dependencies
|
||||
- Docker
|
||||
- [Taskfile](https://taskfile.dev/)
|
||||
|
||||
Then from the repo root use the following commands to build the release binaries
|
||||
that statically link the [native VDF](./crates/vdf) for the supported platforms:
|
||||
|
||||
```shell
|
||||
task build_node_arm64_macos
|
||||
task build_node_arm64_linux
|
||||
task build_node_amd64_linux
|
||||
```
|
||||
|
||||
The output binaries will be in `node/build`.
|
||||
|
1201
Cargo.lock
generated
Normal file
1201
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
Cargo.toml
Normal file
25
Cargo.toml
Normal file
@ -0,0 +1,25 @@
|
||||
# Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# and limitations under the License.
|
||||
[workspace]
|
||||
members = [
|
||||
"crates/vdf",
|
||||
"crates/classgroup",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
# rpath = false is important to make Go bindings work
|
||||
rpath = false
|
||||
lto = true
|
||||
debug = false
|
||||
# panic = 'abort'
|
@ -6,9 +6,9 @@ The only requirements are `git` (to checkout the repository) and docker (to buil
|
||||
Golang does not have to be installed, the docker image build process uses a build stage that provides the
|
||||
correct Go environment and compiles the node down to one command.
|
||||
|
||||
In the repository root folder, where the [Dockerfile](Dockerfile) file is, build the docker image:
|
||||
In the repository root folder, where the [Dockerfile.source](Dockerfile.source) file is, build the docker image:
|
||||
```shell
|
||||
docker build --build-arg GIT_COMMIT=$(git log -1 --format=%h) -t quilibrium -t quilibrium:1.4.16 .
|
||||
docker build -f Dockerfile.source --build-arg GIT_COMMIT=$(git log -1 --format=%h) -t quilibrium -t quilibrium:1.4.16 .
|
||||
```
|
||||
|
||||
Use latest version instead of `1.4.16`.
|
||||
|
@ -1,20 +1,28 @@
|
||||
FROM golang:1.20.14-alpine3.19 as build
|
||||
|
||||
ARG NODE_VERSION
|
||||
ARG MAX_KEY_ID
|
||||
|
||||
ENV GOEXPERIMENT=arenas
|
||||
|
||||
WORKDIR /opt/ceremonyclient
|
||||
|
||||
COPY . .
|
||||
|
||||
WORKDIR /opt/ceremonyclient/node
|
||||
|
||||
RUN go install ./...
|
||||
RUN go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
|
||||
RUN cp "node/node-${NODE_VERSION}-linux-amd64" "node/node"
|
||||
RUN cp "node/node-${NODE_VERSION}-linux-amd64.dgst" "node/node.dgst"
|
||||
RUN for i in $(seq 1 ${MAX_KEY_ID}); do \
|
||||
if [ -f node/node-${NODE_VERSION}-linux-amd64.dgst.sig.${i} ]; then \
|
||||
cp "node/node-${NODE_VERSION}-linux-amd64.dgst.sig.${i}" "node/node.dgst.sig.${i}"; \
|
||||
fi \
|
||||
done
|
||||
|
||||
WORKDIR /opt/ceremonyclient/client
|
||||
|
||||
RUN go build -o qclient ./main.go
|
||||
|
||||
RUN go install github.com/fullstorydev/grpcurl/cmd/grpcurl@v1.9.1
|
||||
|
||||
FROM alpine:3.19
|
||||
|
||||
ARG NODE_VERSION
|
||||
@ -34,10 +42,14 @@ LABEL org.opencontainers.image.source=$GIT_REPO
|
||||
LABEL org.opencontainers.image.ref.name=$GIT_BRANCH
|
||||
LABEL org.opencontainers.image.revision=$GIT_COMMIT
|
||||
|
||||
COPY --from=build /go/bin/node /usr/local/bin
|
||||
COPY --from=build /go/bin/grpcurl /usr/local/bin
|
||||
COPY --from=build /opt/ceremonyclient/node/node /usr/local/bin
|
||||
COPY --from=build /opt/ceremonyclient/node/node.dgst /usr/local/bin
|
||||
COPY --from=build /opt/ceremonyclient/node/node.dgst.sig.* /usr/local/bin
|
||||
|
||||
COPY --from=build /opt/ceremonyclient/client/qclient /usr/local/bin
|
||||
|
||||
COPY --from=build /go/bin/grpcurl /usr/local/bin
|
||||
|
||||
WORKDIR /root
|
||||
|
||||
ENTRYPOINT ["node"]
|
71
Dockerfile.source
Normal file
71
Dockerfile.source
Normal file
@ -0,0 +1,71 @@
|
||||
FROM golang:1.22.4-bullseye as build-base
|
||||
|
||||
ENV PATH="${PATH}:/root/.cargo/bin/"
|
||||
|
||||
# Install GMP 6.2 (6.3 which MacOS is using only available on Debian unstable)
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libgmp-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY docker/rustup-init.sh /opt/rustup-init.sh
|
||||
|
||||
RUN /opt/rustup-init.sh -y --profile minimal
|
||||
|
||||
# Install uniffi-bindgen-go
|
||||
RUN cargo install uniffi-bindgen-go --git https://github.com/NordSecurity/uniffi-bindgen-go --tag v0.2.1+v0.25.0
|
||||
|
||||
FROM build-base as build
|
||||
|
||||
ENV GOEXPERIMENT=arenas
|
||||
ENV QUILIBRIUM_SIGNATURE_CHECK=false
|
||||
|
||||
WORKDIR /opt/ceremonyclient
|
||||
|
||||
COPY . .
|
||||
|
||||
## Generate Rust bindings for VDF
|
||||
WORKDIR /opt/ceremonyclient/vdf
|
||||
RUN ./generate.sh
|
||||
|
||||
# Build and install the node
|
||||
WORKDIR /opt/ceremonyclient/node
|
||||
|
||||
RUN ./build.sh && cp node /go/bin
|
||||
RUN go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
|
||||
|
||||
# Build and install qclient
|
||||
WORKDIR /opt/ceremonyclient/client
|
||||
|
||||
RUN go build -o qclient ./main.go
|
||||
|
||||
# Allows exporting single binary
|
||||
FROM scratch AS node
|
||||
COPY --from=build /go/bin/node /node
|
||||
ENTRYPOINT [ "/node" ]
|
||||
|
||||
FROM debian:bullseye
|
||||
|
||||
ARG NODE_VERSION
|
||||
ARG GIT_REPO
|
||||
ARG GIT_BRANCH
|
||||
ARG GIT_COMMIT
|
||||
|
||||
ENV GOEXPERIMENT=arenas
|
||||
|
||||
LABEL org.opencontainers.image.title="Quilibrium Network Node"
|
||||
LABEL org.opencontainers.image.description="Quilibrium is a decentralized alternative to platform as a service providers."
|
||||
LABEL org.opencontainers.image.version=$NODE_VERSION
|
||||
LABEL org.opencontainers.image.vendor=Quilibrium
|
||||
LABEL org.opencontainers.image.url=https://quilibrium.com/
|
||||
LABEL org.opencontainers.image.documentation=https://quilibrium.com/docs
|
||||
LABEL org.opencontainers.image.source=$GIT_REPO
|
||||
LABEL org.opencontainers.image.ref.name=$GIT_BRANCH
|
||||
LABEL org.opencontainers.image.revision=$GIT_COMMIT
|
||||
|
||||
COPY --from=build /go/bin/node /usr/local/bin
|
||||
COPY --from=build /go/bin/grpcurl /usr/local/bin
|
||||
COPY --from=build /opt/ceremonyclient/client/qclient /usr/local/bin
|
||||
|
||||
WORKDIR /root
|
||||
|
||||
ENTRYPOINT ["node"]
|
277
README-linux.md
277
README-linux.md
@ -1,277 +0,0 @@
|
||||
# Quilibrium - Dawn
|
||||
|
||||
Quilibrium is a decentralized alternative to platform as a service providers.
|
||||
This release, mirrored to GitHub, is the Dawn release, which contains the
|
||||
initial application, the MPC Powers-of-Tau Ceremony. Documentation for the
|
||||
underlying technology can be found at https://www.quilibrium.com/
|
||||
|
||||
## Install Requirements
|
||||
|
||||
wget https://:go.dev/dl/go1.20.14.linux-amd64.tar.gz
|
||||
sudo tar -xvf go1.20.14.linux-amd64.tar.gz
|
||||
sudo mv go /usr/local
|
||||
sudo rm go1.20.14.linux-amd64.tar.gz
|
||||
sudo nano ~/.bashrc
|
||||
|
||||
At the end of the file, add these lines and save the file.
|
||||
|
||||
GOROOT=/usr/local/go
|
||||
GOPATH=$HOME/go
|
||||
PATH=$GOPATH/bin:$GOROOT/bin:$PATH
|
||||
|
||||
On command line, run
|
||||
~/.bashrc
|
||||
|
||||
Check GO Version
|
||||
go version
|
||||
|
||||
It must show "go version go.1.20.14 linux/amd64"
|
||||
|
||||
## Configure Linux Network Device Settings
|
||||
|
||||
To optimize throughput and latency for large parallel job typcal of network like Q
|
||||
|
||||
nano /etc/sysctl.conf
|
||||
|
||||
Copy and paste the 3 lines below into the file. The values below are six hundred million.
|
||||
|
||||
#Increase buffer sizes for better network performance
|
||||
net.core.rmem_max=600000000
|
||||
net.core.wmem_max=600000000
|
||||
|
||||
Save and exit then
|
||||
sudo sysctl -p
|
||||
|
||||
|
||||
## Clone the Repo
|
||||
|
||||
git clone https://github.com/QuilibriumNetwork/ceremonyclient.git
|
||||
cd ceremonyclient/node
|
||||
|
||||
## Quick Start
|
||||
|
||||
All commands are to be run in the `node/` folder.
|
||||
|
||||
If you have a voucher from the offline ceremony, first run:
|
||||
|
||||
GOEXPERIMENT=arenas go run ./... -import-priv-key `cat /path/to/voucher.hex`
|
||||
|
||||
If you do not, or have already run the above, run:
|
||||
|
||||
GOEXPERIMENT=arenas go run ./...
|
||||
|
||||
## Peer ID
|
||||
|
||||
In order to find the peer id of a running node, execute the following command from the `node/` folder:
|
||||
|
||||
GOEXPERIMENT=arenas go run ./... -peer-id
|
||||
|
||||
The peer id will be printed to stdout.
|
||||
|
||||
## EXPERIMENTAL – gRPC/REST Support
|
||||
|
||||
If you want to enable gRPC/REST, add the following entries to your config.yml:
|
||||
|
||||
sudo nano .config/config.yml
|
||||
|
||||
edit these lines below
|
||||
|
||||
listenGrpcMultiaddr: /ip4/127.0.0.1/tcp/8337
|
||||
listenRESTMultiaddr: /ip4/127.0.0.1/tcp/8338
|
||||
|
||||
Save and exit
|
||||
|
||||
Ensure that port 8337 among other neeeded ports are enabled via firewall.
|
||||
|
||||
sudo ufw enable
|
||||
sudo ufw allow 8336
|
||||
sudo ufw allow 8337
|
||||
sudo ufw allow 8338
|
||||
sudo ufw status
|
||||
|
||||
|
||||
Please note: this interface, while read-only, is unauthenticated and not rate-
|
||||
limited. It is recommended that you only enable if you are properly controlling
|
||||
access via firewall or only query via localhost.
|
||||
|
||||
## Token Balance
|
||||
|
||||
In order to query the token balance of a running node, execute the following command from the `node/` folder:
|
||||
|
||||
GOEXPERIMENT=arenas go run ./... -balance
|
||||
|
||||
Or
|
||||
|
||||
GOEXPERIMENT=arenas /root/go/bin/node -balance
|
||||
|
||||
The confirmed token balance will be printed to stdout in QUILs.
|
||||
|
||||
Note that this feature requires that [gRPC support](#experimental--grpcrest-support) is enabled.
|
||||
|
||||
## Build the node binary file
|
||||
|
||||
GOEXPERIMENT=arenas go install ./...
|
||||
|
||||
Thiw will build binary file in /root/go/bin folder
|
||||
|
||||
## Start the Quilibrium Node as a Service
|
||||
|
||||
nano /lib/systemd/system/ceremonyclient.service
|
||||
|
||||
Write the code below
|
||||
|
||||
[Unit]
|
||||
Description=Ceremony Client Go App Service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
WorkingDirectory=/root/ceremonyclient/node
|
||||
Environment=GOEXPERIMENT=arenas
|
||||
ExecStart=/root/go/bin/node ./...
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
Save and exit
|
||||
|
||||
To start service run
|
||||
|
||||
service ceremonyclient start
|
||||
|
||||
To stop service run
|
||||
|
||||
service ceremonyclient stop
|
||||
|
||||
To view service logs run
|
||||
|
||||
sudo journalctl -u ceremonyclient.service -f --no-hostname -o cat
|
||||
|
||||
## Upgrading Node
|
||||
|
||||
service ceremonyclient stop
|
||||
git fetch origin
|
||||
git merge origin
|
||||
|
||||
Go to ceremonyclient/node folder and run
|
||||
|
||||
GOEXPERIMENT=arenas go clean -v -n -a ./...
|
||||
rm /root/go/bin/node
|
||||
GOEXPERIMENT=arenas go install ./...
|
||||
service ceremonyclient start
|
||||
|
||||
If everything is okay you would see logs when you run
|
||||
|
||||
sudo journalctl -u ceremonyclient.service -f --no-hostname -o cat
|
||||
|
||||
Ensure that your service running correctly.
|
||||
|
||||
## Auto Upgrading Script
|
||||
|
||||
Create a file named update.sh in your server and put the code below.
|
||||
|
||||
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
# Stop the ceremonyclient service
|
||||
service ceremonyclient stop
|
||||
|
||||
# Switch to the ~/ceremonyclient directory
|
||||
cd ~/ceremonyclient
|
||||
|
||||
# Fetch updates from the remote repository
|
||||
git fetch origin
|
||||
git merge origin
|
||||
|
||||
# Switch to the ~/ceremonyclient/node directory
|
||||
cd ~/ceremonyclient/node
|
||||
|
||||
# Clean and reinstall node
|
||||
GOEXPERIMENT=arenas go clean -v -n -a ./...
|
||||
rm /root/go/bin/node
|
||||
GOEXPERIMENT=arenas go install ./...
|
||||
|
||||
# Start the ceremonyclient service
|
||||
service ceremonyclient start
|
||||
|
||||
|
||||
chmod u+x update.sh
|
||||
|
||||
When there is new update, run
|
||||
./update.sh
|
||||
|
||||
## Stats Collection
|
||||
|
||||
In order to opt-in to stats collection about the health of the network, edit your `config.yml` in the `node/.config` directory to have a new section under `engine`:
|
||||
|
||||
```yml
|
||||
<earlier parts of config>
|
||||
engine:
|
||||
statsMultiaddr: "/dns/stats.quilibrium.com/tcp/443"
|
||||
<rest of config continues below>
|
||||
```
|
||||
|
||||
## Purpose
|
||||
|
||||
The ceremony application provides a secure reference string (SRS) from which
|
||||
KZG proofs can be constructed for the network. This yields applicability for a
|
||||
number of proof systems, in particular for the release after Dawn, the ability
|
||||
to provide proofs of execution, and proofs of data availability for the network.
|
||||
|
||||
### Rewards
|
||||
|
||||
For participating in a round of the ceremony, nodes will be allocated:
|
||||
|
||||
reward = 161 * log_2(participant_count) QUIL
|
||||
|
||||
### Basic Flow
|
||||
|
||||
Rounds of the ceremony follow the following order:
|
||||
|
||||
- OPEN: Nodes can join in for the round, deferring preference to nodes that
|
||||
could not join in on the prior round
|
||||
- IN PROGRESS: The MPC ceremony round is in progress, nodes are engaging in a
|
||||
logarithmic collection of Multiplication-to-Add Oblivious Transfer circuits,
|
||||
each sub round producing a new collection of values, until the sub rounds have
|
||||
completed, producing a collection of public G1 and G2 BLS48-581 points for each
|
||||
peer.
|
||||
- FINALIZING: The collection of points are broadcasted, and added together,
|
||||
producing a singular ceremony transcript contribution.
|
||||
- VALIDATING: The updated ceremony transcript is validated against the
|
||||
predecessor, and is confirmed to be the new state, issuing rewards to the
|
||||
participant set. The next round can begin.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Contributions are welcome – a new network is rife with opportunities. We are
|
||||
in the process of updating our JIRA board so that it can be made public. The
|
||||
repository has basic coding guidelines:
|
||||
|
||||
- 80 character line limit, with the exception where gofmt or the syntax is
|
||||
impossible to achieve otherwise
|
||||
- Error wrapping matching function names
|
||||
- Interface composition and dependency injection with Wire
|
||||
|
||||
## Minimum System Requirements
|
||||
|
||||
For the Dawn phase, a server must have a minimum of 16GB of RAM, preferably
|
||||
32 GB, 250GB of storage, preferably via SSD, and 50MBps symmetric bandwidth.
|
||||
For Intel/AMD, the baseline processor is a Skylake processor @ 3.4GHz with 12
|
||||
dedicated cores. For ARM, the M1 line of Apple is a good reference.
|
||||
|
||||
With Dusk, these minimum requirements will reduce significantly.
|
||||
|
||||
## License + Interpretation
|
||||
|
||||
Significant portions of Quilibrium's codebase depends on GPL-licensed code,
|
||||
mandating a minimum license of GPL, however Quilibrium is licensed as AGPL to
|
||||
accomodate the scenario in which a cloud provider may wish to coopt the network
|
||||
software. The AGPL allows such providers to do so, provided they are willing
|
||||
to contribute back the management code that interacts with the protocol and node
|
||||
software. To provide clarity, our interpretation is with respect to node
|
||||
provisioning and management tooling for deploying alternative networks, and not
|
||||
applications which are deployed to the network, mainnet status monitors, or
|
||||
container deployments of mainnet nodes from the public codebase.
|
||||
|
104
README.md
104
README.md
@ -1,31 +1,40 @@
|
||||
# Quilibrium - Aurora
|
||||
# Quilibrium - Betelgeuse
|
||||
|
||||
Quilibrium is a decentralized alternative to platform as a service providers.
|
||||
This release, mirrored to GitHub, is the Dawn release, which contains the
|
||||
initial application, the MPC Powers-of-Tau Ceremony. Documentation for the
|
||||
This release is part of the phases of the Dusk release, which finalizes with
|
||||
the full permissionless mainnet in version 2.0. Documentation for the
|
||||
underlying technology can be found at https://www.quilibrium.com/
|
||||
|
||||
## Quick Start
|
||||
|
||||
All commands are to be run in the `node/` folder.
|
||||
Running production nodes from source is no longer recommended given build complexity. Please refer to our release information to obtain the latest version.
|
||||
|
||||
If you have a voucher from the offline ceremony, first run:
|
||||
## Running From Source
|
||||
|
||||
GOEXPERIMENT=arenas go run ./... -import-priv-key `cat /path/to/voucher.hex`
|
||||
Builds are now a hybrid of Rust and Go, so you will need both go 1.22 and latest Rust + Cargo.
|
||||
|
||||
If you do not, or have already run the above, run:
|
||||
### VDF
|
||||
|
||||
GOEXPERIMENT=arenas go run ./...
|
||||
The VDF implementation is now in Rust, and requires GMP to build. On Mac, you can install GMP with brew (`brew install gmp`). On Linux, you will need to find the appropriate package for your distro.
|
||||
|
||||
## Peer ID
|
||||
Install the go plugin for uniffi-rs:
|
||||
|
||||
In order to find the peer id of a running node, execute the following command from the `node/` folder:
|
||||
cargo install uniffi-bindgen-go --git https://github.com/NordSecurity/uniffi-bindgen-go --tag v0.2.1+v0.25.0
|
||||
|
||||
GOEXPERIMENT=arenas go run ./... -peer-id
|
||||
Be sure to follow the PATH export given by the installer.
|
||||
|
||||
The peer id will be printed to stdout.
|
||||
Build the Rust VDF implementation by navigating to the vdf folder, and run `./generate.sh`.
|
||||
|
||||
## EXPERIMENTAL – gRPC/REST Support
|
||||
### Node
|
||||
|
||||
Because of the Rust interop, be sure you follow the above steps for the VDF before proceeding to this. Navigate to the node folder, and run (making sure to update the path for the repo):
|
||||
|
||||
CGO_LDFLAGS="-L/path/to/ceremonyclient/target/release -lvdf -ldl -lm" \
|
||||
CGO_ENABLED=1 \
|
||||
GOEXPERIMENT=arenas \
|
||||
go run ./... --signature-check=false
|
||||
|
||||
## gRPC/REST Support
|
||||
|
||||
If you want to enable gRPC/REST, add the following entries to your config.yml:
|
||||
|
||||
@ -40,52 +49,11 @@ access via firewall or only query via localhost.
|
||||
|
||||
In order to query the token balance of a running node, execute the following command from the `node/` folder:
|
||||
|
||||
GOEXPERIMENT=arenas go run ./... -balance
|
||||
./node-$version-$platform -balance
|
||||
|
||||
The confirmed token balance will be printed to stdout in QUILs.
|
||||
The accumulated token balance will be printed to stdout in QUILs.
|
||||
|
||||
Note that this feature requires that [gRPC support](#experimental--grpcrest-support) is enabled.
|
||||
|
||||
## Stats Collection
|
||||
|
||||
In order to opt-in to stats collection about the health of the network, edit your `config.yml` in the `node/.config` directory to have a new section under `engine`:
|
||||
|
||||
```yml
|
||||
<earlier parts of config>
|
||||
engine:
|
||||
statsMultiaddr: "/dns/stats.quilibrium.com/tcp/443"
|
||||
<rest of config continues below>
|
||||
```
|
||||
|
||||
## Purpose
|
||||
|
||||
The ceremony application provides a secure reference string (SRS) from which
|
||||
KZG proofs can be constructed for the network. This yields applicability for a
|
||||
number of proof systems, in particular for the release after Dawn, the ability
|
||||
to provide proofs of execution, and proofs of data availability for the network.
|
||||
|
||||
### Rewards
|
||||
|
||||
For participating in a round of the ceremony, nodes will be allocated:
|
||||
|
||||
reward = 161 * log_2(participant_count) QUIL
|
||||
|
||||
### Basic Flow
|
||||
|
||||
Rounds of the ceremony follow the following order:
|
||||
|
||||
- OPEN: Nodes can join in for the round, deferring preference to nodes that
|
||||
could not join in on the prior round
|
||||
- IN PROGRESS: The MPC ceremony round is in progress, nodes are engaging in a
|
||||
logarithmic collection of Multiplication-to-Add Oblivious Transfer circuits,
|
||||
each sub round producing a new collection of values, until the sub rounds have
|
||||
completed, producing a collection of public G1 and G2 BLS48-581 points for each
|
||||
peer.
|
||||
- FINALIZING: The collection of points are broadcasted, and added together,
|
||||
producing a singular ceremony transcript contribution.
|
||||
- VALIDATING: The updated ceremony transcript is validated against the
|
||||
predecessor, and is confirmed to be the new state, issuing rewards to the
|
||||
participant set. The next round can begin.
|
||||
Note that this feature requires that [gRPC support](#grpcrest-support) is enabled.
|
||||
|
||||
## Community Section
|
||||
|
||||
@ -96,26 +64,10 @@ This section contains community-built clients, applications, guides, etc <br /><
|
||||
|
||||
- A detailed beginners' guide for how to setup a Quilibrium Node, created by [@demipoet](https://www.github.com/demipoet) - [link](https://quilibrium.guide/)<br/>
|
||||
|
||||
|
||||
## Pull Requests
|
||||
## Development
|
||||
|
||||
Contributions are welcome – a new network is rife with opportunities. We are
|
||||
in the process of updating our JIRA board so that it can be made public. The
|
||||
repository has basic coding guidelines:
|
||||
|
||||
- 80 character line limit, with the exception where gofmt or the syntax is
|
||||
impossible to achieve otherwise
|
||||
- Error wrapping matching function names
|
||||
- Interface composition and dependency injection with Wire
|
||||
|
||||
## Minimum System Requirements
|
||||
|
||||
For the Dawn phase, a server must have a minimum of 16GB of RAM, preferably
|
||||
32 GB, 250GB of storage, preferably via SSD, and 50MBps symmetric bandwidth.
|
||||
For Intel/AMD, the baseline processor is a Skylake processor @ 3.4GHz with 12
|
||||
dedicated cores. For ARM, the M1 line of Apple is a good reference.
|
||||
|
||||
With Dusk, these minimum requirements will reduce significantly.
|
||||
Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information on
|
||||
how to contribute to this repository.
|
||||
|
||||
## License + Interpretation
|
||||
|
||||
|
@ -5,6 +5,9 @@ version: '3'
|
||||
dotenv:
|
||||
- '.env'
|
||||
|
||||
env:
|
||||
DOCKER_BUILDKIT: '1'
|
||||
|
||||
vars:
|
||||
VERSION:
|
||||
sh: cat node/config/version.go | grep -A 1 "func GetVersion() \[\]byte {" | grep -Eo '0x[0-9a-fA-F]+' | xargs printf "%d.%d.%d"
|
||||
@ -14,6 +17,7 @@ vars:
|
||||
sh: git rev-parse --abbrev-ref HEAD
|
||||
GIT_COMMIT:
|
||||
sh: git log -1 --format=%h
|
||||
MAX_KEY_ID: 17
|
||||
|
||||
tasks:
|
||||
status:
|
||||
@ -24,33 +28,70 @@ tasks:
|
||||
- echo -n "Repo :" && echo " {{.GIT_REPO}}"
|
||||
- echo -n "Branch :" && echo " {{.GIT_BRANCH}}"
|
||||
- echo -n "Commit :" && echo " {{.GIT_COMMIT}}"
|
||||
- echo -n "Max Key ID:" && echo " {{.MAX_KEY_ID}}"
|
||||
silent: true
|
||||
|
||||
build_node_arm64_macos:
|
||||
desc: Build the Quilibrium node binary for MacOS ARM. Assumes it's ran from the same platform. Outputs to node/build.
|
||||
cmds:
|
||||
- vdf/generate.sh
|
||||
- node/build.sh -o build/arm64_macos/node
|
||||
|
||||
build:
|
||||
desc: Build the Quilibrium docker image, unless it is already built.
|
||||
build_node_arm64_linux:
|
||||
desc: Build the Quilibrium node binary for ARM64 Linux. Outputs to node/build.
|
||||
cmds:
|
||||
- docker build --platform linux/arm64 -f Dockerfile.source --output node/build/arm64_linux --target=node .
|
||||
|
||||
build_node_amd64_linux:
|
||||
desc: Build the Quilibrium node binary for AMD64 Linux. Outputs to node/build.
|
||||
cmds:
|
||||
- docker build --platform linux/amd64 -f Dockerfile.source --output node/build/amd64_linux --target=node .
|
||||
|
||||
build:source:
|
||||
desc: Build the Quilibrium docker image from source.
|
||||
cmds:
|
||||
- |
|
||||
docker build \
|
||||
-f Dockerfile.source \
|
||||
--build-arg NODE_VERSION={{.VERSION}} \
|
||||
--build-arg GIT_REPO={{.GIT_REPO}} \
|
||||
--build-arg GIT_BRANCH={{.GIT_BRANCH}} \
|
||||
--build-arg GIT_COMMIT={{.GIT_COMMIT}} \
|
||||
-t ${QUILIBRIUM_IMAGE_NAME:-quilibrium}:{{.VERSION}} \
|
||||
-t ${QUILIBRIUM_IMAGE_NAME:-quilibrium}:latest \
|
||||
-t ${QUILIBRIUM_IMAGE_NAME:-quilibrium}:{{.VERSION}}-source \
|
||||
-t ${QUILIBRIUM_IMAGE_NAME:-quilibrium}:source \
|
||||
.
|
||||
status:
|
||||
- |
|
||||
docker image inspect \
|
||||
${QUILIBRIUM_IMAGE_NAME:-quilibrium}:{{.VERSION}} \
|
||||
${QUILIBRIUM_IMAGE_NAME:-quilibrium}:{{.VERSION}}-source \
|
||||
>/dev/null 2>/dev/null
|
||||
|
||||
github:login:
|
||||
desc: Login to GitHub container registry.
|
||||
build:release:
|
||||
desc: Build the Quilibrium docker image from release binaries.
|
||||
aliases:
|
||||
- build
|
||||
cmds:
|
||||
- echo $GITHUB_TOKEN | docker login ghcr.io -u $GITHUB_USERNAME --password-stdin
|
||||
- |
|
||||
docker build \
|
||||
-f Dockerfile.release \
|
||||
--build-arg NODE_VERSION={{.VERSION}} \
|
||||
--build-arg GIT_REPO={{.GIT_REPO}} \
|
||||
--build-arg GIT_BRANCH={{.GIT_BRANCH}} \
|
||||
--build-arg GIT_COMMIT={{.GIT_COMMIT}} \
|
||||
--build-arg MAX_KEY_ID={{.MAX_KEY_ID}} \
|
||||
-t ${QUILIBRIUM_IMAGE_NAME:-quilibrium}:{{.VERSION}}-release \
|
||||
-t ${QUILIBRIUM_IMAGE_NAME:-quilibrium}:release \
|
||||
.
|
||||
status:
|
||||
- |
|
||||
docker image inspect \
|
||||
${QUILIBRIUM_IMAGE_NAME:-quilibrium}:{{.VERSION}}-release \
|
||||
>/dev/null 2>/dev/null
|
||||
|
||||
docker:login:
|
||||
desc: Login to Docker hub
|
||||
aliases:
|
||||
- login
|
||||
cmds:
|
||||
- echo $DOCKER_TOKEN | docker login -u $DOCKER_USERNAME --password-stdin
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
module source.quilibrium.com/quilibrium/monorepo/client
|
||||
|
||||
go 1.20
|
||||
go 1.21
|
||||
|
||||
toolchain go1.22.1
|
||||
|
||||
replace github.com/libp2p/go-libp2p => ../go-libp2p
|
||||
|
||||
@ -11,7 +13,7 @@ replace source.quilibrium.com/quilibrium/monorepo/nekryptology => ../nekryptolog
|
||||
require (
|
||||
github.com/iden3/go-iden3-crypto v0.0.15
|
||||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/stretchr/testify v1.9.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -20,12 +22,10 @@ require (
|
||||
github.com/bwesterb/go-ristretto v1.2.3 // indirect
|
||||
github.com/consensys/gnark-crypto v0.5.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/minio/sha256-simd v1.0.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.18.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
source.quilibrium.com/quilibrium/monorepo/nekryptology v0.0.0-00010101000000-000000000000 // indirect
|
||||
@ -33,7 +33,7 @@ require (
|
||||
|
||||
require (
|
||||
github.com/cloudflare/circl v1.3.8
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/libp2p/go-libp2p v0.33.2
|
||||
github.com/pkg/errors v0.9.1
|
||||
@ -41,6 +41,6 @@ require (
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
go.uber.org/zap v1.27.0
|
||||
google.golang.org/protobuf v1.32.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
source.quilibrium.com/quilibrium/monorepo/node v1.14.17
|
||||
)
|
||||
|
@ -26,40 +26,53 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/iden3/go-iden3-crypto v0.0.15 h1:4MJYlrot1l31Fzlo2sF56u7EVFeHHJkxGXXZCtESgK4=
|
||||
github.com/iden3/go-iden3-crypto v0.0.15/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
|
||||
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
|
||||
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
||||
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||
github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10=
|
||||
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||
github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc=
|
||||
github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII=
|
||||
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
||||
github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg=
|
||||
github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k=
|
||||
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
||||
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
||||
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
@ -69,17 +82,20 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
@ -89,9 +105,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@ -102,18 +119,19 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@ -122,4 +140,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
|
||||
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
|
||||
|
34
crates/classgroup/Cargo.toml
Normal file
34
crates/classgroup/Cargo.toml
Normal file
@ -0,0 +1,34 @@
|
||||
# Copyright 2018 POA Networks Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# and limitations under the License.
|
||||
[package]
|
||||
name = "classgroup"
|
||||
version = "0.1.0"
|
||||
authors = ["Demi M. Obenour <demiobenour@gmail.com>"]
|
||||
description = """An implementation of class groups in Rust. Uses GMP for arithmetic."""
|
||||
keywords = ["classgroup", "vdf"]
|
||||
repository = "https://github.com/poanetwork/vdf"
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
num-traits = "0.2"
|
||||
libc = "0.2"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = ">=0.2"
|
||||
|
||||
[[bench]]
|
||||
name = "classgroup-bench"
|
||||
harness = false
|
||||
path = "bench/bench.rs"
|
66
crates/classgroup/bench/bench.rs
Normal file
66
crates/classgroup/bench/bench.rs
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright 2018 POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[macro_use]
|
||||
extern crate criterion;
|
||||
|
||||
use classgroup::{gmp_classgroup::GmpClassGroup, ClassGroup};
|
||||
use criterion::Criterion;
|
||||
use gmp::mpz::Mpz;
|
||||
use std::str::FromStr;
|
||||
|
||||
fn bench_square(c: &mut Criterion) {
|
||||
for _ in 0..2 {
|
||||
let m_2048 = -Mpz::from_str(
|
||||
"201493927071865251625903550712920535753645598483515670853547009\
|
||||
878440933309489362800393797428711071833308081461824159206915864\
|
||||
150805748296170245037221957772328044276705571745811271212292422\
|
||||
075849739248257870371300001313586036515879618764093772248760562\
|
||||
386804073478433157526816295216137723803793411828867470089409596\
|
||||
238958950007370719325959579892866588928887249912429688364409867\
|
||||
895510817680171869190054122881274299350947669820596157115994418\
|
||||
034091728887584373727555384075665624624856766441009974642693066\
|
||||
751400054217209981490667208950669417773785631693879782993019167\
|
||||
69407006303085854796535778826115224633447713584423",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let m_1024 = -Mpz::from_str(
|
||||
"-11208471744389096429663063172516742066731683613191418514476174383781\
|
||||
682509882427394963852743081347678693241523614532942268295868231081182\
|
||||
819214054220080323345750407342623884342617809879459211722505867733607\
|
||||
400509994975706778681543998242335468203860240586171413971485860382901\
|
||||
6409314686266660248501773529803183",
|
||||
)
|
||||
.unwrap();
|
||||
let group_1024 = GmpClassGroup::generator_for_discriminant(m_1024);
|
||||
let group_2048 = GmpClassGroup::generator_for_discriminant(m_2048);
|
||||
let (group_1024_clone, group_2048_clone) = (group_1024.clone(), group_2048.clone());
|
||||
c.bench_function("square 1024", move |b| {
|
||||
b.iter(|| group_1024_clone.clone().square())
|
||||
});
|
||||
c.bench_function("multiply 1024", move |b| {
|
||||
b.iter(|| &group_1024 * &group_1024)
|
||||
});
|
||||
c.bench_function("square 2048", move |b| {
|
||||
b.iter(|| group_2048_clone.clone().square())
|
||||
});
|
||||
c.bench_function("multiply 2048", move |b| {
|
||||
b.iter(|| &group_2048 * &group_2048)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_square);
|
||||
criterion_main!(benches);
|
16
crates/classgroup/build.rs
Normal file
16
crates/classgroup/build.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
let target = env::var("TARGET").expect("cargo should have set this");
|
||||
if target == "aarch64-apple-darwin" {
|
||||
println!("cargo:rustc-link-search=/opt/homebrew/Cellar/gmp/6.3.0/lib");
|
||||
} else if target == "aarch64-unknown-linux-gnu" {
|
||||
println!("cargo:rustc-link-search=/usr/lib/aarch64-linux-gnu/");
|
||||
} else if target == "x86_64-unknown-linux-gnu" {
|
||||
println!("cargo:rustc-link-search=/usr/lib/x86_64-linux-gnu/");
|
||||
} else {
|
||||
panic!("unsupported target {target}");
|
||||
}
|
||||
}
|
7
crates/classgroup/src/gmp/ffi.rs
Normal file
7
crates/classgroup/src/gmp/ffi.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use super::mpz::*;
|
||||
|
||||
#[link(name = "gmp", kind = "static")]
|
||||
extern "C" {
|
||||
pub fn __gmpz_fdiv_q(q: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
|
||||
pub fn __gmpz_cdiv_q(q: mpz_ptr, n: mpz_srcptr, d: mpz_srcptr);
|
||||
}
|
12
crates/classgroup/src/gmp/mod.rs
Normal file
12
crates/classgroup/src/gmp/mod.rs
Normal file
@ -0,0 +1,12 @@
|
||||
#![warn(deprecated)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
extern crate libc;
|
||||
extern crate num_traits;
|
||||
|
||||
mod ffi;
|
||||
pub mod mpz;
|
||||
pub mod sign;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
1035
crates/classgroup/src/gmp/mpz.rs
Normal file
1035
crates/classgroup/src/gmp/mpz.rs
Normal file
File diff suppressed because it is too large
Load Diff
7
crates/classgroup/src/gmp/sign.rs
Normal file
7
crates/classgroup/src/gmp/sign.rs
Normal file
@ -0,0 +1,7 @@
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
|
||||
pub enum Sign {
|
||||
Negative,
|
||||
Zero,
|
||||
Positive,
|
||||
}
|
||||
|
582
crates/classgroup/src/gmp/test.rs
Normal file
582
crates/classgroup/src/gmp/test.rs
Normal file
@ -0,0 +1,582 @@
|
||||
use super::mpz::mp_limb_t;
|
||||
use std;
|
||||
use libc::c_int;
|
||||
|
||||
#[link(name = "gmp", kind = "static")]
|
||||
extern "C" {
|
||||
static __gmp_bits_per_limb: c_int;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(unsafe_code)]
|
||||
fn test_limb_size() {
|
||||
// We are assuming that the limb size is the same as the pointer size.
|
||||
assert_eq!(std::mem::size_of::<mp_limb_t>() * 8,
|
||||
unsafe { __gmp_bits_per_limb as usize });
|
||||
}
|
||||
|
||||
mod mpz {
|
||||
use super::super::mpz::Mpz;
|
||||
use super::super::mpz::ProbabPrimeResult;
|
||||
use super::super::sign::Sign;
|
||||
use std::str::FromStr;
|
||||
use std::convert::{From, Into};
|
||||
use std::{i64, u64};
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
|
||||
#[test]
|
||||
fn test_set() {
|
||||
let mut x: Mpz = From::<i64>::from(1000);
|
||||
let y: Mpz = From::<i64>::from(5000);
|
||||
assert!(x != y);
|
||||
x.set(&y);
|
||||
assert!(x == y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_from_str_radix() {
|
||||
let mut x: Mpz = From::<i64>::from(1000);
|
||||
let y: Mpz = From::<i64>::from(5000);
|
||||
assert!(x != y);
|
||||
assert!(x.set_from_str_radix("5000", 10));
|
||||
assert!(x == y);
|
||||
assert!(!x.set_from_str_radix("aaaa", 2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_from_str_radix_lower_bound() {
|
||||
let _ = Mpz::from_str_radix("", 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_from_str_radix_upper_bound() {
|
||||
let _ = Mpz::from_str_radix("", 63);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_set_from_str_radix_lower_bound() {
|
||||
let mut x = Mpz::new();
|
||||
x.set_from_str_radix("", 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_set_from_str_radix_upper_bound() {
|
||||
let mut x = Mpz::new();
|
||||
x.set_from_str_radix("", 63);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq() {
|
||||
let x: Mpz = From::<i64>::from(4242142195);
|
||||
let y: Mpz = From::<i64>::from(4242142195);
|
||||
let z: Mpz = From::<i64>::from(4242142196);
|
||||
|
||||
assert!(x == y);
|
||||
assert!(x != z);
|
||||
assert!(y != z);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let x: Mpz = FromStr::from_str("40000000000000000000000").unwrap();
|
||||
let y: Mpz = FromStr::from_str("45000000000000000000000").unwrap();
|
||||
let z: Mpz = FromStr::from_str("50000000000000000000000").unwrap();
|
||||
|
||||
assert!(x < y && x < z && y < z);
|
||||
assert!(x <= x && x <= y && x <= z && y <= z);
|
||||
assert!(z > y && z > x && y > x);
|
||||
assert!(z >= z && z >= y && z >= x && y >= x);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_div_zero() {
|
||||
let x: Mpz = From::<i64>::from(1);
|
||||
let y = Mpz::new();
|
||||
drop(x / y)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_rem_zero() {
|
||||
let x: Mpz = From::<i64>::from(1);
|
||||
let y = Mpz::new();
|
||||
drop(x % y)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_div_round() {
|
||||
let x: Mpz = From::<i64>::from(2);
|
||||
let y: Mpz = From::<i64>::from(3);
|
||||
assert!((&x / &y).to_string() == (2i32 / 3).to_string());
|
||||
assert!((&x / -&y).to_string() == (2i32 / -3).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rem() {
|
||||
let x: Mpz = From::<i64>::from(20);
|
||||
let y: Mpz = From::<i64>::from(3);
|
||||
assert!((&x % &y).to_string() == (20i32 % 3).to_string());
|
||||
assert!((&x % 3).to_string() == (20i32 % 3).to_string());
|
||||
assert!((&x % -&y).to_string() == (20i32 % -3).to_string());
|
||||
assert!((-&x % &y).to_string() == (-20i32 % 3).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
let x: Mpz = From::<i64>::from(2);
|
||||
let y: Mpz = From::<i64>::from(3);
|
||||
let str5 = 5i32.to_string();
|
||||
assert!((&x + &y).to_string() == str5);
|
||||
assert!((&x + 3).to_string() == str5);
|
||||
assert!((&y + 2).to_string() == str5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sub() {
|
||||
let x: Mpz = From::<i64>::from(2);
|
||||
let y: Mpz = From::<i64>::from(3);
|
||||
assert!((&x - &y).to_string() == (-1i32).to_string());
|
||||
assert!((&y - &x).to_string() == 1i32.to_string());
|
||||
assert!((&y - 8).to_string() == (-5i32).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mul() {
|
||||
let x: Mpz = From::<i64>::from(2);
|
||||
let y: Mpz = From::<i64>::from(3);
|
||||
assert!((&x * &y).to_string() == 6i32.to_string());
|
||||
assert!((&x * 3i64).to_string() == 6i32.to_string());
|
||||
assert!((&y * -5i64).to_string() == (-15i32).to_string());
|
||||
// check with values not fitting in 32 bits
|
||||
assert!((&x * 5000000000i64).to_string() == 10000000000i64.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_str_radix() {
|
||||
let x: Mpz = From::<i64>::from(255);
|
||||
assert!(x.to_str_radix(16) == "ff".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_string() {
|
||||
let x: Mpz = FromStr::from_str("1234567890").unwrap();
|
||||
assert!(x.to_string() == "1234567890".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_str() {
|
||||
let x: Result<Mpz, _> = FromStr::from_str("foobar");
|
||||
assert!(x.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let a: Mpz = From::<i64>::from(100);
|
||||
let b = a.clone();
|
||||
let aplusb: Mpz = From::<i64>::from(200);
|
||||
assert!(b == a);
|
||||
assert!(a + b == aplusb);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_int() {
|
||||
let x: Mpz = From::<i64>::from(150);
|
||||
assert!(x.to_string() == "150".to_string());
|
||||
assert!(x == FromStr::from_str("150").unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_slice_u8() {
|
||||
let v: Vec<u8> = vec!(255, 255);
|
||||
let x: Mpz = From::from(&v[..]);
|
||||
assert!(x.to_string() == "65535".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_abs() {
|
||||
let x: Mpz = From::<i64>::from(1000);
|
||||
let y: Mpz = From::<i64>::from(-1000);
|
||||
assert!(-&x == y);
|
||||
assert!(x == -&y);
|
||||
assert!(x == y.abs());
|
||||
assert!(x.abs() == y.abs());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_div_floor() {
|
||||
let two: Mpz = From::<i64>::from(2);
|
||||
let eight: Mpz = From::<i64>::from(8);
|
||||
let minuseight: Mpz = From::<i64>::from(-8);
|
||||
let three: Mpz = From::<i64>::from(3);
|
||||
let minusthree: Mpz = From::<i64>::from(-3);
|
||||
assert_eq!(eight.div_floor(&three), two);
|
||||
assert_eq!(eight.div_floor(&minusthree), minusthree);
|
||||
assert_eq!(minuseight.div_floor(&three), minusthree);
|
||||
assert_eq!(minuseight.div_floor(&minusthree), two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mod_floor() {
|
||||
let one: Mpz = From::<i64>::from(1);
|
||||
let minusone: Mpz = From::<i64>::from(-1);
|
||||
let two: Mpz = From::<i64>::from(2);
|
||||
let minustwo: Mpz = From::<i64>::from(-2);
|
||||
let three: Mpz = From::<i64>::from(3);
|
||||
let minusthree: Mpz = From::<i64>::from(-3);
|
||||
let eight: Mpz = From::<i64>::from(8);
|
||||
let minuseight: Mpz = From::<i64>::from(-8);
|
||||
assert_eq!(eight.mod_floor(&three), two);
|
||||
assert_eq!(eight.mod_floor(&minusthree), minusone);
|
||||
assert_eq!(minuseight.mod_floor(&three), one);
|
||||
assert_eq!(minuseight.mod_floor(&minusthree), minustwo);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitand() {
|
||||
let a = 0b1001_0111;
|
||||
let b = 0b1100_0100;
|
||||
let mpza: Mpz = From::<i64>::from(a);
|
||||
let mpzb: Mpz = From::<i64>::from(b);
|
||||
let mpzres: Mpz = From::<i64>::from(a & b);
|
||||
assert!(mpza & mpzb == mpzres);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitor() {
|
||||
let a = 0b1001_0111;
|
||||
let b = 0b1100_0100;
|
||||
let mpza: Mpz = From::<i64>::from(a);
|
||||
let mpzb: Mpz = From::<i64>::from(b);
|
||||
let mpzres: Mpz = From::<i64>::from(a | b);
|
||||
assert!(mpza | mpzb == mpzres);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bitxor() {
|
||||
let a = 0b1001_0111;
|
||||
let b = 0b1100_0100;
|
||||
let mpza: Mpz = From::<i64>::from(a);
|
||||
let mpzb: Mpz = From::<i64>::from(b);
|
||||
let mpzres: Mpz = From::<i64>::from(a ^ b);
|
||||
assert!(mpza ^ mpzb == mpzres);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shifts() {
|
||||
let i = 227;
|
||||
let j: Mpz = From::<i64>::from(i);
|
||||
assert!((i << 4).to_string() == (&j << 4).to_string());
|
||||
assert!((-i << 4).to_string() == (-&j << 4).to_string());
|
||||
assert!((i >> 4).to_string() == (&j >> 4).to_string());
|
||||
assert!((-i >> 4).to_string() == (-&j >> 4).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compl() {
|
||||
let a: Mpz = From::<i64>::from(13);
|
||||
let b: Mpz = From::<i64>::from(-442);
|
||||
assert!(a.compl().to_string() == (!13i32).to_string());
|
||||
assert!(b.compl().to_string() == (!-442i32).to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pow() {
|
||||
let a: Mpz = From::<i64>::from(2);
|
||||
let b: Mpz = From::<i64>::from(8);
|
||||
assert!(a.pow(3) == b);
|
||||
assert!(Mpz::ui_pow_ui(2, 3) == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_powm() {
|
||||
let a: Mpz = From::<i64>::from(13);
|
||||
let b: Mpz = From::<i64>::from(7);
|
||||
let p: Mpz = From::<i64>::from(19);
|
||||
let c: Mpz = From::<i64>::from(10);
|
||||
assert!(a.powm(&b, &p) == c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_powm_sec() {
|
||||
let a: Mpz = From::<i64>::from(13);
|
||||
let b: Mpz = From::<i64>::from(7);
|
||||
let p: Mpz = From::<i64>::from(19);
|
||||
let c: Mpz = From::<i64>::from(10);
|
||||
assert!(a.powm_sec(&b, &p) == c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_popcount() {
|
||||
assert_eq!(Mpz::from_str_radix("1010010011", 2).unwrap().popcount(), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hamdist() {
|
||||
let a: Mpz = From::<i64>::from(0b1011_0001);
|
||||
let b: Mpz = From::<i64>::from(0b0010_1011);
|
||||
assert!(a.hamdist(&b) == 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_length() {
|
||||
let a: Mpz = From::<i64>::from(0b1011_0000_0001_0000);
|
||||
let b: Mpz = From::<i64>::from(0b101);
|
||||
assert!(a.bit_length() == 16);
|
||||
assert!(b.bit_length() == 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_probab_prime() {
|
||||
let prime: Mpz = From::<i64>::from(2);
|
||||
assert!(prime.probab_prime(15) == ProbabPrimeResult::Prime);
|
||||
|
||||
let not_prime: Mpz = From::<i64>::from(4);
|
||||
assert!(not_prime.probab_prime(15) == ProbabPrimeResult::NotPrime);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nextprime() {
|
||||
let a: Mpz = From::<i64>::from(123456);
|
||||
let b: Mpz = From::<i64>::from(123457);
|
||||
assert!(a.nextprime() == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gcd() {
|
||||
let zero: Mpz = From::<i64>::from(0);
|
||||
let three: Mpz = From::<i64>::from(3);
|
||||
let six: Mpz = From::<i64>::from(6);
|
||||
let eighteen: Mpz = From::<i64>::from(18);
|
||||
let twentyfour: Mpz = From::<i64>::from(24);
|
||||
assert!(zero.gcd(&zero) == zero);
|
||||
assert!(three.gcd(&six) == three);
|
||||
assert!(eighteen.gcd(&twentyfour) == six);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gcdext() {
|
||||
let six: Mpz = From::<i64>::from(6);
|
||||
let eighteen: Mpz = From::<i64>::from(18);
|
||||
let twentyfour: Mpz = From::<i64>::from(24);
|
||||
let (g, s, t) = eighteen.gcdext(&twentyfour);
|
||||
assert!(g == six);
|
||||
assert!(g == s*eighteen + t*twentyfour);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lcm() {
|
||||
let zero: Mpz = From::<i64>::from(0);
|
||||
let three: Mpz = From::<i64>::from(3);
|
||||
let five: Mpz = From::<i64>::from(5);
|
||||
let six: Mpz = From::<i64>::from(6);
|
||||
let eighteen: Mpz = From::<i64>::from(18);
|
||||
let twentyfour: Mpz = From::<i64>::from(24);
|
||||
let seventytwo: Mpz = From::<i64>::from(72);
|
||||
assert!(zero.lcm(&five) == zero);
|
||||
assert!(five.lcm(&zero) == zero);
|
||||
assert!(three.lcm(&six) == six);
|
||||
assert!(eighteen.lcm(&twentyfour) == seventytwo);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_multiple_of() {
|
||||
let two: Mpz = From::<i64>::from(2);
|
||||
let three: Mpz = From::<i64>::from(3);
|
||||
let six: Mpz = From::<i64>::from(6);
|
||||
assert!(six.is_multiple_of(&two));
|
||||
assert!(six.is_multiple_of(&three));
|
||||
assert!(!three.is_multiple_of(&two));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_modulus() {
|
||||
let minusone: Mpz = From::<i64>::from(-1);
|
||||
let two: Mpz = From::<i64>::from(2);
|
||||
let three: Mpz = From::<i64>::from(3);
|
||||
assert_eq!(two.modulus(&three), two);
|
||||
assert_eq!(minusone.modulus(&three), two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invert() {
|
||||
let two: Mpz = From::<i64>::from(2);
|
||||
let three: Mpz = From::<i64>::from(3);
|
||||
let four: Mpz = From::<i64>::from(4);
|
||||
let five: Mpz = From::<i64>::from(5);
|
||||
let eleven: Mpz = From::<i64>::from(11);
|
||||
assert!(three.invert(&eleven) == Some(four.clone()));
|
||||
assert!(four.invert(&eleven) == Some(three.clone()));
|
||||
assert!(two.invert(&five) == Some(three.clone()));
|
||||
assert!(three.invert(&five) == Some(two.clone()));
|
||||
assert!(two.invert(&four).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_one() {
|
||||
let onea: Mpz = From::<i64>::from(1);
|
||||
let oneb: Mpz = From::<i64>::from(1);
|
||||
assert!(onea == oneb);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bit_fiddling() {
|
||||
let mut xs: Mpz = From::<i64>::from(0b1010_1000_0010_0011);
|
||||
assert!(xs.bit_length() == 16);
|
||||
let mut ys = [true, false, true, false,
|
||||
true, false, false, false,
|
||||
false, false, true, false,
|
||||
false, false, true, true];
|
||||
ys.reverse();
|
||||
for i in 0..xs.bit_length() {
|
||||
assert!(xs.tstbit(i) == ys[i]);
|
||||
}
|
||||
xs.setbit(0);
|
||||
ys[0] = true;
|
||||
xs.setbit(3);
|
||||
ys[3] = true;
|
||||
xs.clrbit(1);
|
||||
ys[1] = false;
|
||||
xs.clrbit(5);
|
||||
ys[5] = false;
|
||||
xs.combit(14);
|
||||
ys[14] = !ys[14];
|
||||
xs.combit(15);
|
||||
ys[15] = !ys[15];
|
||||
for i in 0..xs.bit_length() {
|
||||
assert!(xs.tstbit(i) == ys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_root() {
|
||||
let x: Mpz = From::<i64>::from(123456);
|
||||
let y: Mpz = From::<i64>::from(49);
|
||||
assert!(x.root(3) == y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sqrt() {
|
||||
let x: Mpz = From::<i64>::from(567);
|
||||
let y: Mpz = From::<i64>::from(23);
|
||||
assert!(x.sqrt() == y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash_short() {
|
||||
let zero: Mpz = From::<i64>::from(0);
|
||||
let one: Mpz = From::<i64>::from(1);
|
||||
let two = &one + &one;
|
||||
|
||||
let hash = |x : &Mpz| {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
x.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
};
|
||||
|
||||
assert!(hash(&zero) != hash(&one));
|
||||
assert_eq!(hash(&one), hash(&(&two - &one)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash_long() {
|
||||
let a = Mpz::from_str_radix("348917329847193287498312749187234192387", 10)
|
||||
.unwrap();
|
||||
let b = Mpz::from_str_radix("348917329847193287498312749187234192386", 10)
|
||||
.unwrap();
|
||||
let one: Mpz = From::<i64>::from(1);
|
||||
|
||||
let hash = |x : &Mpz| {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
x.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
};
|
||||
|
||||
assert!(hash(&a) != hash(&b));
|
||||
assert_eq!(hash(&a), hash(&(&b + &one)));
|
||||
assert_eq!(hash(&(&a - &a)), hash(&(&one - &one)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_vec_u8() {
|
||||
let minus_five: Mpz = From::<i64>::from(-5);
|
||||
let minus_one: Mpz = From::<i64>::from(-1);
|
||||
let zero: Mpz = From::<i64>::from(0);
|
||||
let one: Mpz = From::<i64>::from(1);
|
||||
let five: Mpz = From::<i64>::from(5);
|
||||
let xffff: Mpz = From::<i64>::from(65535);
|
||||
let max_u64: Mpz = From::<u64>::from(u64::MAX);
|
||||
|
||||
assert_eq!(Into::<Vec<u8>>::into(&minus_five), vec!(5u8));
|
||||
assert_eq!(Into::<Vec<u8>>::into(&minus_one), vec!(1u8));
|
||||
assert_eq!(Into::<Vec<u8>>::into(&zero), vec!(0u8));
|
||||
assert_eq!(Into::<Vec<u8>>::into(&one), vec!(1u8));
|
||||
assert_eq!(Into::<Vec<u8>>::into(&five), vec!(5u8));
|
||||
assert_eq!(Into::<Vec<u8>>::into(&xffff), vec!(255u8, 255u8));
|
||||
assert_eq!(Into::<Vec<u8>>::into(&max_u64), vec!(255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_u64() {
|
||||
let minus_five: Mpz = From::<i64>::from(-5);
|
||||
let minus_one: Mpz = From::<i64>::from(-1);
|
||||
let zero: Mpz = From::<i64>::from(0);
|
||||
let one: Mpz = From::<i64>::from(1);
|
||||
let five: Mpz = From::<i64>::from(5);
|
||||
let max_u64: Mpz = From::<u64>::from(u64::MAX);
|
||||
|
||||
assert_eq!(Into::<Option<u64>>::into(&minus_five), None);
|
||||
assert_eq!(Into::<Option<u64>>::into(&minus_one), None);
|
||||
assert_eq!(Into::<Option<u64>>::into(&zero), Some(0u64));
|
||||
assert_eq!(Into::<Option<u64>>::into(&one), Some(1u64));
|
||||
assert_eq!(Into::<Option<u64>>::into(&five), Some(5u64));
|
||||
assert_eq!(Into::<Option<u64>>::into(&max_u64), Some(u64::MAX));
|
||||
assert_eq!(Into::<Option<u64>>::into(&(&max_u64 + &one)), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_i64() {
|
||||
let min_i64: Mpz = From::<i64>::from(i64::MIN);
|
||||
let minus_five: Mpz = From::<i64>::from(-5);
|
||||
let minus_one: Mpz = From::<i64>::from(-1);
|
||||
let zero: Mpz = From::<i64>::from(0);
|
||||
let one: Mpz = From::<i64>::from(1);
|
||||
let five: Mpz = From::<i64>::from(5);
|
||||
let max_i64: Mpz = From::<i64>::from(i64::MAX);
|
||||
|
||||
assert_eq!(Into::<Option<i64>>::into(&(&min_i64 - &one)), None);
|
||||
assert_eq!(Into::<Option<i64>>::into(&min_i64), Some(i64::MIN));
|
||||
assert_eq!(Into::<Option<i64>>::into(&minus_five), Some(-5i64));
|
||||
assert_eq!(Into::<Option<i64>>::into(&minus_one), Some(-1i64));
|
||||
assert_eq!(Into::<Option<i64>>::into(&zero), Some(0i64));
|
||||
assert_eq!(Into::<Option<i64>>::into(&one), Some(1i64));
|
||||
assert_eq!(Into::<Option<i64>>::into(&five), Some(5i64));
|
||||
assert_eq!(Into::<Option<i64>>::into(&max_i64), Some(i64::MAX));
|
||||
assert_eq!(Into::<Option<i64>>::into(&(&max_i64 + &one)), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sign() {
|
||||
let zero: Mpz = From::<i64>::from(0);
|
||||
let five: Mpz = From::<i64>::from(5);
|
||||
let minus_five: Mpz = From::<i64>::from(-5);
|
||||
|
||||
assert_eq!(zero.sign(), Sign::Zero);
|
||||
assert_eq!(five.sign(), Sign::Positive);
|
||||
assert_eq!(minus_five.sign(), Sign::Negative);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format() {
|
||||
let zero = Mpz::zero();
|
||||
assert_eq!(format!("{}", zero), "0");
|
||||
let zero = Mpz::from(-51213);
|
||||
assert_eq!(format!("{}", zero), "-51213");
|
||||
}
|
||||
}
|
90
crates/classgroup/src/gmp_classgroup/congruence.rs
Normal file
90
crates/classgroup/src/gmp_classgroup/congruence.rs
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#![forbid(unsafe_code)]
|
||||
use self::ffi::Mpz;
|
||||
use super::ffi;
|
||||
|
||||
/// Stores temporary values for congruence computations, to avoid
|
||||
/// repeated allocations.
|
||||
///
|
||||
/// It is allowed (but inefficient) to generate a fresh `CongruenceContest`
|
||||
/// for each call to `solve_linear_congruence`.
|
||||
///
|
||||
/// `self.solve_linear_congruence` can be called no matter what values
|
||||
/// this struct’s public members hold, so long as they are valid `Mpz` values.
|
||||
/// However, the values of these members after such a call must not be relied
|
||||
/// on.
|
||||
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
pub struct CongruenceContext {
|
||||
pub g: Mpz,
|
||||
pub d: Mpz,
|
||||
pub q: Mpz,
|
||||
pub r: Mpz,
|
||||
}
|
||||
|
||||
// #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
// struct NoCongruence;
|
||||
|
||||
impl Default for CongruenceContext {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
g: Mpz::new(),
|
||||
d: Mpz::new(),
|
||||
q: Mpz::new(),
|
||||
r: Mpz::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CongruenceContext {
|
||||
/// Solves `a*x = b (mod m)`, storing `x` in `mu`
|
||||
///
|
||||
/// This function may clobber any or all of `self`’s member variables.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the congruence could not be solved.
|
||||
pub fn solve_linear_congruence(
|
||||
&mut self,
|
||||
mu: &mut Mpz,
|
||||
v: Option<&mut Mpz>,
|
||||
a: &Mpz,
|
||||
b: &Mpz,
|
||||
m: &Mpz,
|
||||
) {
|
||||
ffi::mpz_gcdext(&mut self.g, &mut self.d, mu, a, m);
|
||||
if cfg!(test) {
|
||||
println!(
|
||||
"g = {}, d = {}, e = {}, a = {}, m = {}",
|
||||
self.g, self.d, mu, a, m
|
||||
);
|
||||
}
|
||||
if cfg!(debug_assertions) {
|
||||
ffi::mpz_fdiv_qr(&mut self.q, &mut self.r, b, &self.g);
|
||||
debug_assert!(self.r.is_zero(), "Could not solve the congruence ― did you pass a non-prime or a positive number to the command line tool?!");
|
||||
} else {
|
||||
ffi::mpz_divexact(&mut self.q, b, &self.g)
|
||||
}
|
||||
ffi::mpz_mul(&mut self.r, &self.q, &self.d);
|
||||
ffi::mpz_tdiv_r(mu, &self.r, m);
|
||||
if let Some(v) = v {
|
||||
if cfg!(debug_assertions) {
|
||||
ffi::mpz_fdiv_qr(v, &mut self.r, &m, &self.g);
|
||||
debug_assert!(self.r.is_zero(), "Could not solve the congruence ― did you pass a non-prime or a positive number to the command line tool?!");
|
||||
} else {
|
||||
ffi::mpz_divexact(v, &m, &self.g)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
340
crates/classgroup/src/gmp_classgroup/ffi.rs
Normal file
340
crates/classgroup/src/gmp_classgroup/ffi.rs
Normal file
@ -0,0 +1,340 @@
|
||||
// Copyright 2018 POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! FFI bindings to GMP. This module exists because the `rust-gmp` crate
|
||||
//! is too high-level. High-performance bignum computation requires that
|
||||
//! bignums be modified in-place, so that their storage can be reused.
|
||||
//! Furthermore, the `rust-gmp` crate doesn’t support many operations that
|
||||
//! this library requires.
|
||||
#![allow(unsafe_code)]
|
||||
pub use super::super::gmp::mpz::Mpz;
|
||||
use super::super::gmp::mpz::{mp_bitcnt_t, mp_limb_t};
|
||||
use libc::{c_int, c_long, c_ulong, c_void, size_t};
|
||||
// pub use c_ulong;
|
||||
use std::{mem, usize};
|
||||
// We use the unsafe versions to avoid unecessary allocations.
|
||||
#[link(name = "gmp", kind = "static")]
|
||||
extern "C" {
|
||||
fn __gmpz_gcdext(gcd: *mut Mpz, s: *mut Mpz, t: *mut Mpz, a: *const Mpz, b: *const Mpz);
|
||||
fn __gmpz_gcd(rop: *mut Mpz, op1: *const Mpz, op2: *const Mpz);
|
||||
fn __gmpz_fdiv_qr(q: *mut Mpz, r: *mut Mpz, b: *const Mpz, g: *const Mpz);
|
||||
fn __gmpz_fdiv_q(q: *mut Mpz, n: *const Mpz, d: *const Mpz);
|
||||
fn __gmpz_divexact(q: *mut Mpz, n: *const Mpz, d: *const Mpz);
|
||||
fn __gmpz_tdiv_q(q: *mut Mpz, n: *const Mpz, d: *const Mpz);
|
||||
fn __gmpz_mul(p: *mut Mpz, a: *const Mpz, b: *const Mpz);
|
||||
fn __gmpz_mul_2exp(rop: *mut Mpz, op1: *const Mpz, op2: mp_bitcnt_t);
|
||||
fn __gmpz_sub(rop: *mut Mpz, op1: *const Mpz, op2: *const Mpz);
|
||||
fn __gmpz_import(
|
||||
rop: *mut Mpz,
|
||||
count: size_t,
|
||||
order: c_int,
|
||||
size: size_t,
|
||||
endian: c_int,
|
||||
nails: size_t,
|
||||
op: *const c_void,
|
||||
);
|
||||
fn __gmpz_tdiv_r(r: *mut Mpz, n: *const Mpz, d: *const Mpz);
|
||||
fn __gmpz_sizeinbase(op: &Mpz, base: c_int) -> size_t;
|
||||
fn __gmpz_fdiv_q_ui(rop: *mut Mpz, op1: *const Mpz, op2: c_ulong) -> c_ulong;
|
||||
fn __gmpz_add(rop: *mut Mpz, op1: *const Mpz, op2: *const Mpz);
|
||||
fn __gmpz_add_ui(rop: *mut Mpz, op1: *const Mpz, op2: c_ulong);
|
||||
fn __gmpz_set_ui(rop: &mut Mpz, op: c_ulong);
|
||||
fn __gmpz_set_si(rop: &mut Mpz, op: c_long);
|
||||
fn __gmpz_cdiv_ui(n: &Mpz, d: c_ulong) -> c_ulong;
|
||||
fn __gmpz_fdiv_ui(n: &Mpz, d: c_ulong) -> c_ulong;
|
||||
fn __gmpz_tdiv_ui(n: &Mpz, d: c_ulong) -> c_ulong;
|
||||
fn __gmpz_export(
|
||||
rop: *mut c_void,
|
||||
countp: *mut size_t,
|
||||
order: c_int,
|
||||
size: size_t,
|
||||
endian: c_int,
|
||||
nails: size_t,
|
||||
op: &Mpz,
|
||||
) -> *mut c_void;
|
||||
fn __gmpz_powm(rop: *mut Mpz, base: *const Mpz, exp: *const Mpz, modulus: *const Mpz);
|
||||
}
|
||||
|
||||
// MEGA HACK: rust-gmp doesn’t expose the fields of this struct, so we must define
|
||||
// it ourselves and cast.
|
||||
//
|
||||
// Should be stable though, as only GMP can change it, and doing would break binary compatibility.
|
||||
#[repr(C)]
|
||||
struct MpzStruct {
|
||||
mp_alloc: c_int,
|
||||
mp_size: c_int,
|
||||
mp_d: *mut mp_limb_t,
|
||||
}
|
||||
|
||||
macro_rules! impl_div_ui {
|
||||
($t:ident, $i:ident, $f:expr) => {
|
||||
pub fn $i(n: &Mpz, d: $t) -> $t {
|
||||
use std::$t;
|
||||
let res = unsafe { $f(n, c_ulong::from(d)) };
|
||||
assert!(res <= $t::MAX.into());
|
||||
res as $t
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_div_ui!(u16, mpz_crem_u16, __gmpz_cdiv_ui);
|
||||
impl_div_ui!(u32, mpz_frem_u32, __gmpz_fdiv_ui);
|
||||
|
||||
/// Returns `true` if `z` is negative and not zero. Otherwise,
|
||||
/// returns `false`.
|
||||
#[inline]
|
||||
pub fn mpz_is_negative(z: &Mpz) -> bool {
|
||||
unsafe { (*(z as *const _ as *const MpzStruct)).mp_size < 0 }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mpz_powm(rop: &mut Mpz, base: &Mpz, exponent: &Mpz, modulus: &Mpz) {
|
||||
unsafe { __gmpz_powm(rop, base, exponent, modulus) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mpz_tdiv_r(r: &mut Mpz, n: &Mpz, d: &Mpz) {
|
||||
unsafe { __gmpz_tdiv_r(r, n, d) }
|
||||
}
|
||||
|
||||
/// Sets `g` to the GCD of `a` and `b`.
|
||||
#[inline]
|
||||
pub fn mpz_gcdext(gcd: &mut Mpz, s: &mut Mpz, t: &mut Mpz, a: &Mpz, b: &Mpz) {
|
||||
unsafe { __gmpz_gcdext(gcd, s, t, a, b) }
|
||||
}
|
||||
|
||||
/// Doubles `rop` in-place
|
||||
#[inline]
|
||||
pub fn mpz_double(rop: &mut Mpz) {
|
||||
if true {
|
||||
// slightly faster
|
||||
unsafe { __gmpz_mul_2exp(rop, rop, 1) }
|
||||
} else {
|
||||
unsafe { __gmpz_add(rop, rop, rop) }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mpz_fdiv_qr(q: &mut Mpz, r: &mut Mpz, b: &Mpz, g: &Mpz) {
|
||||
unsafe { __gmpz_fdiv_qr(q, r, b, g) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mpz_fdiv_q_ui_self(rop: &mut Mpz, op: c_ulong) -> c_ulong {
|
||||
unsafe { __gmpz_fdiv_q_ui(rop, rop, op) }
|
||||
}
|
||||
|
||||
/// Unmarshals a buffer to an `Mpz`. `buf` is interpreted as a 2’s complement,
|
||||
/// big-endian integer. If the buffer is empty, zero is returned.
|
||||
pub fn import_obj(buf: &[u8]) -> Mpz {
|
||||
fn raw_import(buf: &[u8]) -> Mpz {
|
||||
let mut obj = Mpz::new();
|
||||
|
||||
unsafe { __gmpz_import(&mut obj, buf.len(), 1, 1, 1, 0, buf.as_ptr() as *const _) }
|
||||
obj
|
||||
}
|
||||
let is_negative = match buf.first() {
|
||||
None => return Mpz::zero(),
|
||||
Some(x) => x & 0x80 != 0,
|
||||
};
|
||||
if !is_negative {
|
||||
raw_import(buf)
|
||||
} else {
|
||||
let mut new_buf: Vec<_> = buf.iter().cloned().skip_while(|&x| x == 0xFF).collect();
|
||||
if new_buf.is_empty() {
|
||||
(-1).into()
|
||||
} else {
|
||||
for i in &mut new_buf {
|
||||
*i ^= 0xFF
|
||||
}
|
||||
!raw_import(&new_buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn three_gcd(rop: &mut Mpz, a: &Mpz, b: &Mpz, c: &Mpz) {
|
||||
unsafe {
|
||||
__gmpz_gcd(rop, a, b);
|
||||
__gmpz_gcd(rop, rop, c)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn size_in_bits(obj: &Mpz) -> usize {
|
||||
unsafe { __gmpz_sizeinbase(obj, 2) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mpz_add(rop: &mut Mpz, op1: &Mpz, op2: &Mpz) {
|
||||
unsafe { __gmpz_add(rop, op1, op2) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mpz_mul(rop: &mut Mpz, op1: &Mpz, op2: &Mpz) {
|
||||
unsafe { __gmpz_mul(rop, op1, op2) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mpz_divexact(q: &mut Mpz, n: &Mpz, d: &Mpz) {
|
||||
unsafe { __gmpz_divexact(q, n, d) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mpz_mul_2exp(rop: &mut Mpz, op1: &Mpz, op2: mp_bitcnt_t) {
|
||||
unsafe { __gmpz_mul_2exp(rop as *mut _ as *mut Mpz, op1, op2) }
|
||||
}
|
||||
|
||||
/// Divide `n` by `d`. Round towards -∞ and place the result in `q`.
|
||||
#[inline]
|
||||
pub fn mpz_fdiv_q(q: &mut Mpz, n: &Mpz, d: &Mpz) {
|
||||
if mpz_is_negative(n) == mpz_is_negative(d) {
|
||||
unsafe { __gmpz_tdiv_q(q, n, d) }
|
||||
} else {
|
||||
unsafe { __gmpz_fdiv_q(q, n, d) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets `rop` to `(-1) * op`
|
||||
#[inline]
|
||||
#[cfg(none)]
|
||||
pub fn mpz_neg(rop: &mut Mpz) {
|
||||
assert!(mem::size_of::<Mpz>() == mem::size_of::<MpzStruct>());
|
||||
unsafe {
|
||||
let ptr = rop as *mut _ as *mut MpzStruct;
|
||||
let v = (*ptr).mp_size;
|
||||
(*ptr).mp_size = -v;
|
||||
}
|
||||
}
|
||||
|
||||
/// Subtracts `op2` from `op1` and stores the result in `rop`.
|
||||
#[inline]
|
||||
pub fn mpz_sub(rop: &mut Mpz, op1: &Mpz, op2: &Mpz) {
|
||||
unsafe { __gmpz_sub(rop as *mut _ as *mut Mpz, op1, op2) }
|
||||
}
|
||||
|
||||
/// Exports `obj` to `v` as an array of 2’s complement, big-endian
|
||||
/// bytes. If `v` is too small to hold the result, returns `Err(s)`,
|
||||
/// where `s` is the size needed to hold the exported version of `obj`.
|
||||
pub fn export_obj(obj: &Mpz, v: &mut [u8]) -> Result<(), usize> {
|
||||
// Requires: offset < v.len() and v[offset..] be able to hold all of `obj`
|
||||
unsafe fn raw_export(v: &mut [u8], offset: usize, obj: &Mpz) -> usize {
|
||||
// SAFE as `offset` will always be in-bounds, since byte_len always <=
|
||||
// byte_len_needed and we check that v.len() >= byte_len_needed.
|
||||
let ptr = v.as_mut_ptr().add(offset) as *mut c_void;
|
||||
|
||||
// Necessary ― this byte may not be fully overwritten
|
||||
*(ptr as *mut u8) = 0;
|
||||
|
||||
// SAFE as __gmpz_export will *always* initialize this.
|
||||
let mut s: usize = mem::uninitialized();
|
||||
let ptr2 = __gmpz_export(ptr, &mut s, 1, 1, 1, 0, obj);
|
||||
assert_eq!(ptr, ptr2);
|
||||
if 0 == s {
|
||||
1
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
let size = size_in_bits(obj);
|
||||
assert!(size > 0);
|
||||
|
||||
// Check to avoid integer overflow in later operations.
|
||||
if size > usize::MAX - 8 || v.len() > usize::MAX >> 3 {
|
||||
return Err(usize::MAX);
|
||||
}
|
||||
|
||||
// One additional bit is needed for the sign bit.
|
||||
let byte_len_needed = (size + 8) >> 3;
|
||||
if v.len() < byte_len_needed {
|
||||
return if v.is_empty() && obj.is_zero() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(byte_len_needed)
|
||||
};
|
||||
}
|
||||
let is_negative = mpz_is_negative(obj);
|
||||
|
||||
if is_negative {
|
||||
// MEGA HACK: GMP does not have a function to perform 2's complement
|
||||
let obj = !obj;
|
||||
debug_assert!(
|
||||
!mpz_is_negative(&obj),
|
||||
"bitwise negation of a negative number produced a negative number"
|
||||
);
|
||||
let new_byte_size = (size_in_bits(&obj) + 7) >> 3;
|
||||
let offset = v.len() - new_byte_size;
|
||||
|
||||
for i in &mut v[..offset] {
|
||||
*i = 0xFF
|
||||
}
|
||||
unsafe {
|
||||
assert_eq!(raw_export(v, offset, &obj), new_byte_size);
|
||||
}
|
||||
|
||||
// We had to do a one’s complement to get the data in a decent format,
|
||||
// so now we need to flip all of the bits back. LLVM should be able to
|
||||
// vectorize this loop easily.
|
||||
for i in &mut v[offset..] {
|
||||
*i ^= 0xFF
|
||||
}
|
||||
} else {
|
||||
// ...but GMP will not include that in the number of bytes it writes
|
||||
// (except for negative numbers)
|
||||
let byte_len = (size + 7) >> 3;
|
||||
assert!(byte_len > 0);
|
||||
|
||||
let offset = v.len() - byte_len;
|
||||
|
||||
// Zero out any leading bytes
|
||||
for i in &mut v[..offset] {
|
||||
*i = 0
|
||||
}
|
||||
unsafe {
|
||||
assert_eq!(raw_export(v, offset, &obj), byte_len);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn check_expected_bit_width() {
|
||||
let mut s: Mpz = (-2).into();
|
||||
assert_eq!(size_in_bits(&s), 2);
|
||||
s = !s;
|
||||
assert_eq!(s, 1.into());
|
||||
s.setbit(2);
|
||||
assert_eq!(s, 5.into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_export() {
|
||||
let mut s: Mpz = 0x100.into();
|
||||
s = !s;
|
||||
let mut buf = [0, 0, 0];
|
||||
export_obj(&s, &mut buf).expect("buffer should be large enough");
|
||||
assert_eq!(buf, [0xFF, 0xFE, 0xFF]);
|
||||
export_obj(&Mpz::zero(), &mut []).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_rem() {
|
||||
assert_eq!(mpz_crem_u16(&(-100i64).into(), 3), 1);
|
||||
assert_eq!(mpz_crem_u16(&(100i64).into(), 3), 2);
|
||||
}
|
||||
}
|
590
crates/classgroup/src/gmp_classgroup/mod.rs
Normal file
590
crates/classgroup/src/gmp_classgroup/mod.rs
Normal file
@ -0,0 +1,590 @@
|
||||
// Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#![deny(unsafe_code)]
|
||||
use super::ClassGroup;
|
||||
use super::gmp::mpz::Mpz;
|
||||
use super::gmp::mpz::ProbabPrimeResult::NotPrime;
|
||||
use num_traits::{One, Zero};
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
cell::RefCell,
|
||||
mem::swap,
|
||||
ops::{Mul, MulAssign},
|
||||
};
|
||||
use std::convert::TryInto;
|
||||
|
||||
mod congruence;
|
||||
pub(super) mod ffi;
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Debug, Clone)]
|
||||
pub struct GmpClassGroup {
|
||||
a: Mpz,
|
||||
b: Mpz,
|
||||
c: Mpz,
|
||||
discriminant: Mpz,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Clone, Hash, Debug)]
|
||||
pub struct Ctx {
|
||||
negative_a: Mpz,
|
||||
r: Mpz,
|
||||
denom: Mpz,
|
||||
old_a: Mpz,
|
||||
old_b: Mpz,
|
||||
ra: Mpz,
|
||||
s: Mpz,
|
||||
x: Mpz,
|
||||
congruence_context: congruence::CongruenceContext,
|
||||
h: Mpz,
|
||||
w: Mpz,
|
||||
m: Mpz,
|
||||
u: Mpz,
|
||||
a: Mpz,
|
||||
l: Mpz,
|
||||
j: Mpz,
|
||||
b: Mpz,
|
||||
k: Mpz,
|
||||
t: Mpz,
|
||||
mu: Mpz,
|
||||
v: Mpz,
|
||||
sigma: Mpz,
|
||||
lambda: Mpz,
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static CTX: RefCell<Ctx> = Default::default();
|
||||
}
|
||||
|
||||
impl GmpClassGroup {
|
||||
pub fn into_raw(self) -> (Mpz, Mpz) {
|
||||
(self.a, self.b)
|
||||
}
|
||||
|
||||
fn inner_multiply(&mut self, rhs: &Self, ctx: &mut Ctx) {
|
||||
self.assert_valid();
|
||||
rhs.assert_valid();
|
||||
|
||||
// g = (b1 + b2) / 2
|
||||
ffi::mpz_add(&mut ctx.congruence_context.g, &self.b, &rhs.b);
|
||||
ffi::mpz_fdiv_q_ui_self(&mut ctx.congruence_context.g, 2);
|
||||
|
||||
// h = (b2 - b1) / 2
|
||||
ffi::mpz_sub(&mut ctx.h, &rhs.b, &self.b);
|
||||
ffi::mpz_fdiv_q_ui_self(&mut ctx.h, 2);
|
||||
|
||||
debug_assert!(&ctx.h + &ctx.congruence_context.g == rhs.b);
|
||||
debug_assert!(&ctx.congruence_context.g - &ctx.h == self.b);
|
||||
|
||||
// w = gcd(a1, a2, g)
|
||||
ffi::three_gcd(&mut ctx.w, &self.a, &rhs.a, &ctx.congruence_context.g);
|
||||
|
||||
// j = w
|
||||
ctx.j.set(&ctx.w);
|
||||
|
||||
// s = a1/w
|
||||
ffi::mpz_fdiv_q(&mut ctx.s, &self.a, &ctx.w);
|
||||
|
||||
// t = a2/w
|
||||
ffi::mpz_fdiv_q(&mut ctx.t, &rhs.a, &ctx.w);
|
||||
|
||||
// u = g/w
|
||||
ffi::mpz_fdiv_q(&mut ctx.u, &ctx.congruence_context.g, &ctx.w);
|
||||
|
||||
// a = t*u
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.t, &ctx.u);
|
||||
|
||||
// b = h*u - s*c1
|
||||
ffi::mpz_mul(&mut ctx.b, &ctx.h, &ctx.u);
|
||||
ffi::mpz_mul(&mut ctx.m, &ctx.s, &self.c);
|
||||
ctx.b += &ctx.m;
|
||||
|
||||
// m = s*t
|
||||
ffi::mpz_mul(&mut ctx.m, &ctx.s, &ctx.t);
|
||||
ctx.congruence_context.solve_linear_congruence(
|
||||
&mut ctx.mu,
|
||||
Some(&mut ctx.v),
|
||||
&ctx.a,
|
||||
&ctx.b,
|
||||
&ctx.m,
|
||||
);
|
||||
|
||||
// a = t*v
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.t, &ctx.v);
|
||||
|
||||
// b = h - t * mu
|
||||
ffi::mpz_mul(&mut ctx.m, &ctx.t, &ctx.mu);
|
||||
ffi::mpz_sub(&mut ctx.b, &ctx.h, &ctx.m);
|
||||
|
||||
// m = s
|
||||
ctx.m.set(&ctx.s);
|
||||
|
||||
ctx.congruence_context.solve_linear_congruence(
|
||||
&mut ctx.lambda,
|
||||
Some(&mut ctx.sigma),
|
||||
&ctx.a,
|
||||
&ctx.b,
|
||||
&ctx.m,
|
||||
);
|
||||
|
||||
// k = mu + v*lambda
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.v, &ctx.lambda);
|
||||
ffi::mpz_add(&mut ctx.k, &ctx.mu, &ctx.a);
|
||||
|
||||
// l = (k*t - h)/s
|
||||
ffi::mpz_mul(&mut ctx.l, &ctx.k, &ctx.t);
|
||||
ffi::mpz_sub(&mut ctx.v, &ctx.l, &ctx.h);
|
||||
ffi::mpz_fdiv_q(&mut ctx.l, &ctx.v, &ctx.s);
|
||||
|
||||
// m = (t*u*k - h*u - c*s) / s*t
|
||||
ffi::mpz_mul(&mut ctx.m, &ctx.t, &ctx.u);
|
||||
ctx.m *= &ctx.k;
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.h, &ctx.u);
|
||||
ctx.m -= &ctx.a;
|
||||
ffi::mpz_mul(&mut ctx.a, &self.c, &ctx.s);
|
||||
ctx.m -= &ctx.a;
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.s, &ctx.t);
|
||||
ffi::mpz_fdiv_q(&mut ctx.lambda, &ctx.m, &ctx.a);
|
||||
|
||||
// A = s*t - r*u
|
||||
ffi::mpz_mul(&mut self.a, &ctx.s, &ctx.t);
|
||||
|
||||
// B = ju + mr - (kt + ls)
|
||||
ffi::mpz_mul(&mut self.b, &ctx.j, &ctx.u);
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.k, &ctx.t);
|
||||
self.b -= &ctx.a;
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.l, &ctx.s);
|
||||
self.b -= &ctx.a;
|
||||
|
||||
// C = kl - jm
|
||||
ffi::mpz_mul(&mut self.c, &ctx.k, &ctx.l);
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.j, &ctx.lambda);
|
||||
self.c -= &ctx.a;
|
||||
|
||||
self.inner_reduce(ctx);
|
||||
}
|
||||
|
||||
#[cfg_attr(not(debug_assertions), inline(always))]
|
||||
fn new(a: Mpz, b: Mpz, c: Mpz, discriminant: Mpz) -> Self {
|
||||
let s = GmpClassGroup {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
discriminant,
|
||||
};
|
||||
s.assert_valid();
|
||||
s
|
||||
}
|
||||
|
||||
#[cfg_attr(not(debug_assertions), inline(always))]
|
||||
fn assert_valid(&self) {
|
||||
if cfg!(debug_assertions) {
|
||||
let four: Mpz = 4u64.into();
|
||||
let four_ac: Mpz = four * &self.a * &self.c;
|
||||
assert!(&self.discriminant + four_ac == &self.b * &self.b);
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_normalize(&mut self, ctx: &mut Ctx) {
|
||||
self.assert_valid();
|
||||
ctx.negative_a = -&self.a;
|
||||
if self.b > ctx.negative_a && self.b <= self.a {
|
||||
return;
|
||||
}
|
||||
ffi::mpz_sub(&mut ctx.r, &self.a, &self.b);
|
||||
ffi::mpz_mul_2exp(&mut ctx.denom, &self.a, 1);
|
||||
ffi::mpz_fdiv_q(&mut ctx.negative_a, &ctx.r, &ctx.denom);
|
||||
swap(&mut ctx.negative_a, &mut ctx.r);
|
||||
swap(&mut ctx.old_b, &mut self.b);
|
||||
ffi::mpz_mul(&mut ctx.ra, &ctx.r, &self.a);
|
||||
ffi::mpz_mul_2exp(&mut ctx.negative_a, &ctx.ra, 1);
|
||||
ffi::mpz_add(&mut self.b, &ctx.old_b, &ctx.negative_a);
|
||||
|
||||
ffi::mpz_mul(&mut ctx.negative_a, &ctx.ra, &ctx.r);
|
||||
ffi::mpz_add(&mut ctx.old_a, &self.c, &ctx.negative_a);
|
||||
|
||||
ffi::mpz_mul(&mut ctx.ra, &ctx.r, &ctx.old_b);
|
||||
ffi::mpz_add(&mut self.c, &ctx.old_a, &ctx.ra);
|
||||
|
||||
self.assert_valid();
|
||||
}
|
||||
|
||||
fn inner_reduce(&mut self, ctx: &mut Ctx) {
|
||||
self.inner_normalize(ctx);
|
||||
|
||||
while if ffi::mpz_is_negative(&self.b) {
|
||||
self.a >= self.c
|
||||
} else {
|
||||
self.a > self.c
|
||||
} {
|
||||
debug_assert!(!self.c.is_zero());
|
||||
ffi::mpz_add(&mut ctx.s, &self.c, &self.b);
|
||||
ffi::mpz_add(&mut ctx.x, &self.c, &self.c);
|
||||
swap(&mut self.b, &mut ctx.old_b);
|
||||
ffi::mpz_fdiv_q(&mut self.b, &ctx.s, &ctx.x);
|
||||
swap(&mut self.b, &mut ctx.s);
|
||||
swap(&mut self.a, &mut self.c);
|
||||
|
||||
// x = 2sc
|
||||
ffi::mpz_mul(&mut self.b, &ctx.s, &self.a);
|
||||
ffi::mpz_mul_2exp(&mut ctx.x, &self.b, 1);
|
||||
|
||||
// b = x - old_b
|
||||
ffi::mpz_sub(&mut self.b, &ctx.x, &ctx.old_b);
|
||||
|
||||
// x = b*s
|
||||
ffi::mpz_mul(&mut ctx.x, &ctx.old_b, &ctx.s);
|
||||
|
||||
// s = c*s^2
|
||||
ffi::mpz_mul(&mut ctx.old_b, &ctx.s, &ctx.s);
|
||||
ffi::mpz_mul(&mut ctx.s, &self.a, &ctx.old_b);
|
||||
|
||||
// c = s - x
|
||||
ffi::mpz_sub(&mut ctx.old_a, &ctx.s, &ctx.x);
|
||||
|
||||
// c += a
|
||||
self.c += &ctx.old_a;
|
||||
}
|
||||
self.inner_normalize(ctx);
|
||||
}
|
||||
|
||||
fn inner_square_impl(&mut self, ctx: &mut Ctx) {
|
||||
self.assert_valid();
|
||||
ctx.congruence_context.solve_linear_congruence(
|
||||
&mut ctx.mu,
|
||||
None,
|
||||
&self.b,
|
||||
&self.c,
|
||||
&self.a,
|
||||
);
|
||||
ffi::mpz_mul(&mut ctx.m, &self.b, &ctx.mu);
|
||||
ctx.m -= &self.c;
|
||||
ctx.m = ctx.m.div_floor(&self.a);
|
||||
|
||||
// New a
|
||||
ctx.old_a.set(&self.a);
|
||||
ffi::mpz_mul(&mut self.a, &ctx.old_a, &ctx.old_a);
|
||||
|
||||
// New b
|
||||
ffi::mpz_mul(&mut ctx.a, &ctx.mu, &ctx.old_a);
|
||||
ffi::mpz_double(&mut ctx.a);
|
||||
self.b -= &ctx.a;
|
||||
|
||||
// New c
|
||||
ffi::mpz_mul(&mut self.c, &ctx.mu, &ctx.mu);
|
||||
self.c -= &ctx.m;
|
||||
self.inner_reduce(ctx);
|
||||
}
|
||||
|
||||
#[cfg_attr(not(debug_assertions), inline(always))]
|
||||
fn inner_square(&mut self, ctx: &mut Ctx) {
|
||||
if cfg!(debug_assertions) {
|
||||
let mut q = self.clone();
|
||||
q.inner_multiply(self, ctx);
|
||||
self.inner_square_impl(ctx);
|
||||
assert_eq!(*self, q);
|
||||
} else {
|
||||
self.inner_square_impl(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/// Call `cb` with a mutable reference to the context of type `Ctx`.
|
||||
///
|
||||
/// The reference cannot escape the closure and cannot be sent across
|
||||
/// threads.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if called recursively. This library guarantees that it will
|
||||
/// never call this function from any function that takes a parameter of
|
||||
/// type `&mut Ctx`.
|
||||
pub fn with_context<T, U>(cb: T) -> U
|
||||
where
|
||||
T: FnOnce(&mut Ctx) -> U,
|
||||
{
|
||||
let mut opt = None;
|
||||
CTX.with(|x| opt = Some(cb(&mut x.borrow_mut())));
|
||||
opt.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GmpClassGroup {
|
||||
fn default() -> Self {
|
||||
GmpClassGroup {
|
||||
a: Mpz::new(),
|
||||
b: Mpz::new(),
|
||||
c: Mpz::new(),
|
||||
discriminant: Mpz::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Borrow<GmpClassGroup>> MulAssign<B> for GmpClassGroup {
|
||||
#[cfg_attr(not(debug_assertions), inline(always))]
|
||||
fn mul_assign(&mut self, rhs: B) {
|
||||
let rhs = rhs.borrow();
|
||||
debug_assert!(self.discriminant == rhs.discriminant);
|
||||
GmpClassGroup::with_context(|ctx| self.inner_multiply(rhs, ctx));
|
||||
}
|
||||
}
|
||||
|
||||
impl super::BigNum for Mpz {
|
||||
fn probab_prime(&self, iterations: u32) -> bool {
|
||||
let reps: i32 = iterations.try_into().expect("Iterations fits into i32");
|
||||
self.probab_prime(reps) != NotPrime
|
||||
}
|
||||
|
||||
fn setbit(&mut self, bit_index: usize) {
|
||||
self.setbit(bit_index)
|
||||
}
|
||||
|
||||
fn mod_powm(&mut self, base: &Self, exponent: &Self, modulus: &Self) {
|
||||
ffi::mpz_powm(self, base, exponent, modulus)
|
||||
}
|
||||
}
|
||||
|
||||
impl super::BigNumExt for Mpz {
|
||||
fn frem_u32(&self, modulus: u32) -> u32 {
|
||||
ffi::mpz_frem_u32(self, modulus)
|
||||
}
|
||||
fn crem_u16(&mut self, modulus: u16) -> u16 {
|
||||
ffi::mpz_crem_u16(self, modulus)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Borrow<Self>> Mul<B> for GmpClassGroup {
|
||||
type Output = Self;
|
||||
#[inline]
|
||||
fn mul(mut self, rhs: B) -> Self {
|
||||
self *= rhs.borrow();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, B: Borrow<GmpClassGroup>> Mul<B> for &'a GmpClassGroup {
|
||||
type Output = GmpClassGroup;
|
||||
|
||||
#[inline(always)]
|
||||
fn mul(self, rhs: B) -> Self::Output {
|
||||
let mut s = Clone::clone(self.borrow());
|
||||
s *= rhs;
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
impl ClassGroup for GmpClassGroup {
|
||||
type BigNum = Mpz;
|
||||
|
||||
/// Normalize `self`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if called within a call to `Self::with_context`.
|
||||
fn normalize(&mut self) {
|
||||
Self::with_context(|x| self.inner_normalize(x))
|
||||
}
|
||||
|
||||
#[cfg_attr(not(debug_assertions), inline(always))]
|
||||
fn inverse(&mut self) {
|
||||
self.assert_valid();
|
||||
self.b = -self.b.clone();
|
||||
}
|
||||
|
||||
fn serialize(&self, buf: &mut [u8]) -> Result<(), usize> {
|
||||
self.assert_valid();
|
||||
if buf.len() & 1 == 1 {
|
||||
// odd lengths do not make sense
|
||||
Err(0)
|
||||
} else {
|
||||
let len = buf.len() >> 1;
|
||||
ffi::export_obj(&self.a, &mut buf[..len])?;
|
||||
ffi::export_obj(&self.b, &mut buf[len..])
|
||||
}
|
||||
}
|
||||
|
||||
fn from_bytes(bytearray: &[u8], discriminant: Self::BigNum) -> Self {
|
||||
let len = (ffi::size_in_bits(&discriminant) + 16) >> 4;
|
||||
let a = ffi::import_obj(&bytearray[..len]);
|
||||
let b = ffi::import_obj(&bytearray[len..]);
|
||||
Self::from_ab_discriminant(a, b, discriminant)
|
||||
}
|
||||
|
||||
fn from_ab_discriminant(a: Self::BigNum, b: Self::BigNum, discriminant: Self::BigNum) -> Self {
|
||||
let mut four_a: Self::BigNum = 4u64.into();
|
||||
four_a *= &a;
|
||||
let c = (&b * &b - &discriminant) / four_a;
|
||||
Self {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
discriminant,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the discriminant of `self`.
|
||||
#[inline(always)]
|
||||
fn discriminant(&self) -> &Self::BigNum {
|
||||
&self.discriminant
|
||||
}
|
||||
|
||||
fn size_in_bits(num: &Self::BigNum) -> usize {
|
||||
ffi::size_in_bits(num)
|
||||
}
|
||||
|
||||
/// Reduce `self`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if called within a call to `Self::with_context`.
|
||||
fn reduce(&mut self) {
|
||||
Self::with_context(|x| self.inner_reduce(x))
|
||||
}
|
||||
|
||||
fn deserialize(buf: &[u8], discriminant: Self::BigNum) -> Self {
|
||||
let len = buf.len();
|
||||
debug_assert!(len != 0, "Cannot deserialize an empty buffer!");
|
||||
debug_assert!(len & 1 == 0, "Buffer must be of even length");
|
||||
let half_len = len >> 1;
|
||||
Self::from_ab_discriminant(
|
||||
ffi::import_obj(&buf[..half_len]),
|
||||
ffi::import_obj(&buf[half_len..]),
|
||||
discriminant,
|
||||
)
|
||||
}
|
||||
|
||||
/// Square `self`.ClassGroupPartial
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if called within the scope of a call to `with_context`.
|
||||
fn square(&mut self) {
|
||||
Self::with_context(|ctx| self.inner_square(ctx))
|
||||
}
|
||||
|
||||
fn unsigned_deserialize_bignum(buf: &[u8]) -> Self::BigNum {
|
||||
buf.into()
|
||||
}
|
||||
|
||||
/// Square `self` `iterations` times.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if called within the scope of a call to `with_context`.
|
||||
fn repeated_square(&mut self, iterations: u64) {
|
||||
Self::with_context(|ctx| {
|
||||
for _ in 0..iterations {
|
||||
self.inner_square(ctx)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn generator_for_discriminant(discriminant: Self::BigNum) -> Self {
|
||||
let one: Mpz = One::one();
|
||||
let x: Mpz = &one - &discriminant;
|
||||
let mut form = Self::new(2.into(), one, x.div_floor(&8.into()), discriminant);
|
||||
form.reduce();
|
||||
form
|
||||
}
|
||||
|
||||
fn pow(&mut self, mut exponent: Mpz) {
|
||||
self.assert_valid();
|
||||
debug_assert!(exponent >= Mpz::zero());
|
||||
let mut state = self.identity();
|
||||
loop {
|
||||
let is_odd = exponent.tstbit(0);
|
||||
exponent >>= 1;
|
||||
if is_odd {
|
||||
state *= &*self
|
||||
}
|
||||
if exponent.is_zero() {
|
||||
*self = state;
|
||||
break;
|
||||
}
|
||||
self.square();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Ctx {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
negative_a: Mpz::new(),
|
||||
r: Mpz::new(),
|
||||
denom: Mpz::new(),
|
||||
old_a: Mpz::new(),
|
||||
old_b: Mpz::new(),
|
||||
ra: Mpz::new(),
|
||||
s: Mpz::new(),
|
||||
x: Mpz::new(),
|
||||
congruence_context: Default::default(),
|
||||
w: Mpz::new(),
|
||||
m: Mpz::new(),
|
||||
u: Mpz::new(),
|
||||
l: Mpz::new(),
|
||||
j: Mpz::new(),
|
||||
t: Mpz::new(),
|
||||
a: Mpz::new(),
|
||||
b: Mpz::new(),
|
||||
k: Mpz::new(),
|
||||
h: Mpz::new(),
|
||||
mu: Mpz::new(),
|
||||
v: Mpz::new(),
|
||||
sigma: Mpz::new(),
|
||||
lambda: Mpz::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn do_compute(discriminant: Mpz, iterations: u64) -> GmpClassGroup {
|
||||
debug_assert!(discriminant < Zero::zero());
|
||||
debug_assert!(discriminant.probab_prime(50) != NotPrime);
|
||||
let mut f = GmpClassGroup::generator_for_discriminant(discriminant);
|
||||
f.repeated_square(iterations);
|
||||
f
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#![allow(unused_imports)]
|
||||
use super::*;
|
||||
#[test]
|
||||
fn normalize() {
|
||||
let mut s = GmpClassGroup::new(
|
||||
16.into(),
|
||||
(-23).into(),
|
||||
5837_3892.into(),
|
||||
(-0xdead_beefi64).into(),
|
||||
);
|
||||
let mut new = GmpClassGroup {
|
||||
b: 9.into(),
|
||||
c: 5837_3885.into(),
|
||||
..s.clone()
|
||||
};
|
||||
s.normalize();
|
||||
assert_eq!(s, new);
|
||||
|
||||
s = GmpClassGroup {
|
||||
a: (1 << 16).into(),
|
||||
b: (-76951).into(),
|
||||
c: 36840.into(),
|
||||
..s
|
||||
};
|
||||
new = GmpClassGroup {
|
||||
b: 54121.into(),
|
||||
c: 25425.into(),
|
||||
..s.clone()
|
||||
};
|
||||
s.normalize();
|
||||
assert_eq!(s, new);
|
||||
}
|
||||
}
|
251
crates/classgroup/src/lib.rs
Normal file
251
crates/classgroup/src/lib.rs
Normal file
@ -0,0 +1,251 @@
|
||||
// Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#![deny(unsafe_code)]
|
||||
use num_traits::{One, Zero};
|
||||
use std::ops::{Mul, MulAssign, Rem, ShlAssign};
|
||||
|
||||
pub mod gmp;
|
||||
|
||||
pub mod gmp_classgroup;
|
||||
pub use self::gmp_classgroup::{
|
||||
do_compute,
|
||||
ffi::{export_obj, import_obj},
|
||||
};
|
||||
pub trait BigNum:
|
||||
Zero
|
||||
+ One
|
||||
+ Clone
|
||||
+ PartialOrd
|
||||
+ std::fmt::Debug
|
||||
+ Rem
|
||||
+ ShlAssign<usize>
|
||||
+ for<'a> MulAssign<&'a Self>
|
||||
+ std::ops::Sub<u64, Output = Self>
|
||||
+ std::ops::Add<u64, Output = Self>
|
||||
+ std::convert::From<u64>
|
||||
+ for<'a> std::convert::From<&'a [u8]>
|
||||
+ std::ops::Shl<usize, Output = Self>
|
||||
+ std::ops::Shr<usize, Output = Self>
|
||||
+ std::ops::Neg<Output = Self>
|
||||
+ std::str::FromStr
|
||||
+ for<'a> std::ops::Div<&'a Self, Output = Self>
|
||||
+ Eq
|
||||
+ std::hash::Hash
|
||||
{
|
||||
fn probab_prime(&self, iterations: u32) -> bool;
|
||||
fn setbit(&mut self, offset: usize);
|
||||
fn mod_powm(&mut self, base: &Self, exponent: &Self, modulus: &Self);
|
||||
}
|
||||
|
||||
pub trait BigNumExt: BigNum {
|
||||
fn frem_u32(&self, modulus: u32) -> u32;
|
||||
fn crem_u16(&mut self, modulus: u16) -> u16;
|
||||
}
|
||||
|
||||
pub trait ClassGroup:
|
||||
Sized + Clone + for<'a> MulAssign<&'a Self> + for<'a> Mul<&'a Self> + PartialEq + std::fmt::Debug
|
||||
{
|
||||
type BigNum: BigNum;
|
||||
|
||||
/// Produces a `Self` from `a`, `b`, and a discriminant.
|
||||
fn from_ab_discriminant(a: Self::BigNum, b: Self::BigNum, discriminant: Self::BigNum) -> Self;
|
||||
|
||||
/// Unmarshals a `Self` from a byte array and discriminant.
|
||||
///
|
||||
/// The byte array will be in the format of two big-endian byte sequences
|
||||
/// concatenated together.
|
||||
fn from_bytes(bytearray: &[u8], discriminant: Self::BigNum) -> Self;
|
||||
|
||||
/// Computes the identity element of `Self` for a given discriminant.
|
||||
///
|
||||
/// If the discriminant is not valid, the result is unspecified.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This may panic (but is not required to) if the discriminant is not
|
||||
/// valid. If this function does not panic, the results of future
|
||||
/// operations are unspecified: they will not invoke undefined behavior,
|
||||
/// but may panic, loop forever, or just compute garbage.
|
||||
///
|
||||
/// In debug builds, this will always panic if the discriminant is invalid.
|
||||
fn identity_for_discriminant(discriminant: Self::BigNum) -> Self {
|
||||
Self::from_ab_discriminant(Self::BigNum::one(), Self::BigNum::one(), discriminant)
|
||||
}
|
||||
|
||||
/// Serializes `self` to a byte array. Returns `Err(s)` if there
|
||||
/// is not enough space in the buffer.
|
||||
///
|
||||
/// The data must be serialized in twos-complement, big-endian format.
|
||||
fn serialize(&self, buf: &mut [u8]) -> std::result::Result<(), usize>;
|
||||
|
||||
/// Deserializes a bignum from raw bytes. The bytes **must** be interpreted
|
||||
/// as a big-endian unsigned integer.
|
||||
fn unsigned_deserialize_bignum(_: &[u8]) -> Self::BigNum;
|
||||
|
||||
/// Reduce `self` in-place.
|
||||
fn reduce(&mut self);
|
||||
|
||||
/// Squares `self`, modifying it in-place.
|
||||
///
|
||||
/// A default implementation is provided, but implementations are suggested
|
||||
/// to override it for performance reasons.
|
||||
fn square(&mut self) {
|
||||
let s = self.clone();
|
||||
self.mul_assign(&s)
|
||||
}
|
||||
|
||||
/// Normalize `self`.
|
||||
fn normalize(&mut self);
|
||||
|
||||
/// The length of `num` in **bits**
|
||||
fn size_in_bits(num: &Self::BigNum) -> usize;
|
||||
|
||||
/// Gets the discriminant of `self`.
|
||||
fn discriminant(&self) -> &Self::BigNum;
|
||||
|
||||
/// Computes the identity element of a `ClassGroup`.
|
||||
fn identity(&self) -> Self {
|
||||
Self::identity_for_discriminant(self.discriminant().clone())
|
||||
}
|
||||
|
||||
/// Generates a *generator* for the class group of `Self`, given a
|
||||
/// discriminant.
|
||||
///
|
||||
/// If the discriminant is not valid, the result is unspecified.
|
||||
///
|
||||
/// # Relation to `Self::identity_for_discriminant`
|
||||
///
|
||||
/// This is *not* the same as `Self::identity_for_discriminant`: the
|
||||
/// identity element is *never* a generator for *any* group. This follows
|
||||
/// from their definitions: the identity element, when multiplied by another
|
||||
/// element, always gives that other element, whereas *every* element in the
|
||||
/// group is some power of a generator.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This may panic (but is not required to) if the discriminant is not
|
||||
/// valid. If this function does not panic, the results of future
|
||||
/// operations are unspecified: they will not invoke undefined behavior,
|
||||
/// but may panic, loop forever, or just compute garbage.
|
||||
///
|
||||
/// If the global allocator panics on running out of memory, then this
|
||||
/// function may panic in the same situation, but it may also just abort the
|
||||
/// program instead.
|
||||
///
|
||||
/// In debug builds, this will always panic if the discriminant is invalid.
|
||||
fn generator_for_discriminant(discriminant: Self::BigNum) -> Self {
|
||||
Self::from_ab_discriminant(2.into(), One::one(), discriminant)
|
||||
}
|
||||
|
||||
/// Replaces `*self` with its inverse.
|
||||
fn inverse(&mut self);
|
||||
|
||||
/// Squares `self` repeatedly in-place.
|
||||
///
|
||||
/// Implementors of this trait are encouraged to override this
|
||||
/// with a more efficient implementation, if one exists.
|
||||
fn repeated_square(&mut self, iterations: u64) {
|
||||
for _ in 0..iterations {
|
||||
self.square()
|
||||
}
|
||||
}
|
||||
|
||||
/// Exponentiation
|
||||
fn pow(&mut self, exponent: Self::BigNum);
|
||||
|
||||
/// Deserialization
|
||||
fn deserialize(buf: &[u8], discriminant: Self::BigNum) -> Self;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufRead, BufReader},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use super::{gmp_classgroup::GmpClassGroup, ClassGroup};
|
||||
use super::gmp::mpz::Mpz;
|
||||
|
||||
fn split_into_three_pieces(line: &str, c: char) -> [&str; 3] {
|
||||
let mut iter = line.split(c);
|
||||
let fst = iter.next().expect("bad test file");
|
||||
let snd = iter.next().expect("bad test file");
|
||||
let thd = iter.next().expect("bad test file");
|
||||
assert!(iter.next().is_none(), "bad test file");
|
||||
[fst, snd, thd]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiplication_is_correct() {
|
||||
let manifest_path =
|
||||
std::env::var("CARGO_MANIFEST_DIR").expect("cargo should have set this");
|
||||
let mut path = PathBuf::from(&manifest_path);
|
||||
path.push("tests/multiply.txt");
|
||||
let mut f = BufReader::new(File::open(path).expect("test file missing or unreadable"));
|
||||
let mut buffer = String::new();
|
||||
loop {
|
||||
let bytes_read = f
|
||||
.read_line(&mut buffer)
|
||||
.expect("could not read from test file");
|
||||
assert!(bytes_read == buffer.len());
|
||||
if bytes_read == 0 {
|
||||
break;
|
||||
}
|
||||
if buffer.ends_with('\n') {
|
||||
buffer.pop();
|
||||
}
|
||||
if buffer.ends_with('\r') {
|
||||
buffer.pop();
|
||||
}
|
||||
let mut current_discriminant: Option<Mpz> = None;
|
||||
let q: Vec<_> = split_into_three_pieces(&buffer, '|')
|
||||
.iter()
|
||||
.map(|i| {
|
||||
let k = split_into_three_pieces(i, ',');
|
||||
|
||||
let a = Mpz::from_str_radix(k[0], 10).expect("bad test file");
|
||||
let b = Mpz::from_str_radix(k[1], 10).expect("bad test file");
|
||||
let c = Mpz::from_str_radix(k[2], 10).expect("bad test file");
|
||||
let mut discriminant: Mpz = &b * &b;
|
||||
let mut minuand: Mpz = (4u64).into();
|
||||
minuand *= &a * &c;
|
||||
discriminant -= &minuand;
|
||||
assert!(discriminant < Mpz::zero());
|
||||
// takes waaaay too long
|
||||
// assert!(discriminant.probab_prime(20) !=
|
||||
// gmp::mpz::ProbabPrimeResult::NotPrime);
|
||||
if let Some(ref q) = current_discriminant {
|
||||
assert_eq!(q, &discriminant, "mismatching discriminant in test files");
|
||||
} else {
|
||||
current_discriminant = Some(discriminant.clone());
|
||||
}
|
||||
GmpClassGroup::from_ab_discriminant(a, b, discriminant)
|
||||
})
|
||||
.collect();
|
||||
assert_eq!(q.len(), 3);
|
||||
if q[0] == q[1] {
|
||||
let mut i = q[0].clone();
|
||||
i.square();
|
||||
assert_eq!(i, q[2]);
|
||||
}
|
||||
assert_eq!(&q[1] * &q[0], q[2], "multiplication not valid");
|
||||
assert_eq!(&q[0] * &q[1], q[2], "multiplication not valid");
|
||||
buffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
100
crates/classgroup/tests/multiply.txt
Normal file
100
crates/classgroup/tests/multiply.txt
Normal file
@ -0,0 +1,100 @@
|
||||
10000018491751458060893889018190756675058808109876974330719629294415871248770716417843542202672894233523533522085426391611508488462673577289978500560291881560964103822003262872704649110111368415677918460552197008588860300461769848797788221536509692873112178498610293735717449110462487732034905273446995235572,6192881975696225786035966982664995064937044822044587534644251299449043731778362309709151420033302511678628887337754750911692576543520793791684926797453257880919340267222510512181015985728296989735175472866965866872698457694161211487470544291337368825900113948256559852781942460432108372735686602775132351861,447562623961213317971342646547297454284223350038133828902656285846421695114449573517005802064814603287280139301229441755696758326577197667784458131993559071961595818908854193681416803619972011522725445624820104005456169532111411278882533391024720916070194718519556110684723979632586634811370262763099820931946|10000018491751458060893889018190756675058808109876974330719629294415871248770716417843542202672894233523533522085426391611508488462673577289978500560291881560964103822003262872704649110111368415677918460552197008588860300461769848797788221536509692873112178498610293735717449110462487732034905273446995235572,6192881975696225786035966982664995064937044822044587534644251299449043731778362309709151420033302511678628887337754750911692576543520793791684926797453257880919340267222510512181015985728296989735175472866965866872698457694161211487470544291337368825900113948256559852781942460432108372735686602775132351861,447562623961213317971342646547297454284223350038133828902656285846421695114449573517005802064814603287280139301229441755696758326577197667784458131993559071961595818908854193681416803619972011522725445624820104005456169532111411278882533391024720916070194718519556110684723979632586634811370262763099820931946|19255554116382770161579383715714909264782708765539029964624834623077914838241374452996111823462588737699221151887520236764901217774034554643488538519529924118839366411749516259835028878669578401436677730193218203890014064720579917095034628468204338354122803225577022412929359504950608508400413031048217497926,15092837287167018117143864462870004173493326087323162483214185994683512256473920528820058682931229518373567536566141901399624393736734616696317492646832399845295961581562413238135817545423153806714585874605091134049460217739322207059368564835209958877374166810803213938557201936549078491894191793263450700347,234893006768044042788914260913118901546740453084924505628085298368208613193607118822477736613870586900826160773678687890939302953916150044522278344184471658898873737893277827322372416620559784208443693756270533224257971092005354126278524692768704444715469609790946460097751182675767317515935452615150233004184
|
||||
10000041052183522790242850644893154590720039288612095879016416132777489378534703527529316376767361213758229530778215090392226004364711343494340009516684351602465954563523094253968698993441741189497557646486818525059302740665570749018871945434231968929038967533223013692831944903924891259290137962329173675618,1902993169831098968408340994163042640289698812843652994188396853325597449053613940738900681358483309978075948057374939279288006967407927201371876070720282077185512088102089011109098339510946105167168603912904329219763993441428070797711607939058596983469167495985136256807429373538982995591135613664471290691,648679116947253221704188706776650677211463611636395838310356904951972039958552218839434071543988637793619482253205477878855250277635662749169650536657554110192985236141029049474956216985923614316507072329807839408341849104680142145376380471455107520480114830913820742685234228885993868983705228973767491332409|10000041052183522790242850644893154590720039288612095879016416132777489378534703527529316376767361213758229530778215090392226004364711343494340009516684351602465954563523094253968698993441741189497557646486818525059302740665570749018871945434231968929038967533223013692831944903924891259290137962329173675618,1902993169831098968408340994163042640289698812843652994188396853325597449053613940738900681358483309978075948057374939279288006967407927201371876070720282077185512088102089011109098339510946105167168603912904329219763993441428070797711607939058596983469167495985136256807429373538982995591135613664471290691,648679116947253221704188706776650677211463611636395838310356904951972039958552218839434071543988637793619482253205477878855250277635662749169650536657554110192985236141029049474956216985923614316507072329807839408341849104680142145376380471455107520480114830913820742685234228885993868983705228973767491332409|11014730391994022921548019318564443238610906141262076480168925966763126765751815894971319798676750825680596366806816953155468468927850506963854768575341863098700465049052526243803093026353195834059474734029876952052212354875982568724849333989940233032713622829273608000126280643959163722728068472850088622786,10741667368771260991465304819723549356187315169745538829427954074292104964386739024958802023185700235860418655331632400858711212007319896932342251013222776723172845936147563193613725240374195945000924112718166206035243862199173787901602224623957181722190890413718871860292878014198837725481829866947825981913,591458717193488352905603034790202837072660316706237076413003353962226001987681937225165602501036312777007571264636495875979803481147253392478958512772229202313701414596984055959140281478236518410326724468820458881999271606689529119264353275033892327553507658401114443924515886686374958949587811834733084613494
|
||||
10000381915681932465973261183425742883776417480816046593820159088331265076946313439425523314444345253320002870252043057595684488140407211015115892705028395378796407813776706176594457902083795049968208905578343034404017956993894296039160788337679442024505335413399442760803039586109332233036553257459967307992,4817573728667361865336022581228097408185105735439009440346088109945423944514625700845976724084897576632126538284617885680024575350161902075565426943435359103696435860065323384485576321976518692508202982451179520762630115309722600967720404130152140308793673263051352095721900258702511325402177650727880246935,669873650881721761367318894015191721808238052876596531632606045247446982615721443478227885999211090819818334947786875090863090531638122013530669226521626152920347047659485744946461307259365312735407042929006458450763753134816736952808194188478460912675596404179851630644942038849386883091149385220764843706257|10000381915681932465973261183425742883776417480816046593820159088331265076946313439425523314444345253320002870252043057595684488140407211015115892705028395378796407813776706176594457902083795049968208905578343034404017956993894296039160788337679442024505335413399442760803039586109332233036553257459967307992,4817573728667361865336022581228097408185105735439009440346088109945423944514625700845976724084897576632126538284617885680024575350161902075565426943435359103696435860065323384485576321976518692508202982451179520762630115309722600967720404130152140308793673263051352095721900258702511325402177650727880246935,669873650881721761367318894015191721808238052876596531632606045247446982615721443478227885999211090819818334947786875090863090531638122013530669226521626152920347047659485744946461307259365312735407042929006458450763753134816736952808194188478460912675596404179851630644942038849386883091149385220764843706257|15406883651839353468888340788129827256524366500559993343402492794080742895081542466902089892082975781941021139173750937371748781682695257732868858255213590996446142784059996942302405311028161097993332331718537383888482114789770414489490580461393020737016788325059322912336073066124099655242000162998144490191,4360823987526422964670528620808397080272081276432190896883401768539814490180903410645821165307382339042226562722529652661460320310396511517028476587614669988004410806997734064375576646534713644939599630073534432499720811712867334091133681123961660738588960398432344316577526812821260889068523826290764750305,434737123855318232136803285518736106774596594589476825779021338309188039202684276728719741767739900154018854551253981210446831263812934806367418646532886786527458187655685060926749423401952358398253824964655841491692769761412354811289837062586506164527515355144754089246394187279961001728737349715244065290684
|
||||
10000382084844819863091735393428537123796094124029988695624509543701671917373805547793586171907452267004536696714359178508237591675470611568215269390130161491021123479579310299191808477715227540644280867131359924216029489859205866802370878621090778893635118109144685744213704279596306855259529008805569484738,-444155911792016461297666514223280647275019670279235098115904524278820479908555182212414682305357120850467322036353999623022556562078881846242421627622835673248504490647482104203937046492778180626801172318868765508903156634858880238203680354870853572676123032093150013906751911065758499256507194503286999359,567054671672969689387757610046141412714538710354002952292665369546607156429867011238555624731427279061383543924144630291236714076290759079492403352598432624404020019598559946194717566760077730429172494635087510893397235439040191683342313758118884331110227782487142203190483880485876667351431228811762752414559|10000382084844819863091735393428537123796094124029988695624509543701671917373805547793586171907452267004536696714359178508237591675470611568215269390130161491021123479579310299191808477715227540644280867131359924216029489859205866802370878621090778893635118109144685744213704279596306855259529008805569484738,-444155911792016461297666514223280647275019670279235098115904524278820479908555182212414682305357120850467322036353999623022556562078881846242421627622835673248504490647482104203937046492778180626801172318868765508903156634858880238203680354870853572676123032093150013906751911065758499256507194503286999359,567054671672969689387757610046141412714538710354002952292665369546607156429867011238555624731427279061383543924144630291236714076290759079492403352598432624404020019598559946194717566760077730429172494635087510893397235439040191683342313758118884331110227782487142203190483880485876667351431228811762752414559|25233315598122077418065976820332071042466787077699487654424387918664961172156179342884760885536120785360009215201873305025819279551843543582105904004062292352688557410351568671077765651689593128194982886401323218888273326531345494420553999096902303332712335656165115841742118280506588108873800795844703864919,-21589572107561067243363628128888045942080137348693403707950771695641329996718935854060105037586070646944119604332897696206540905887323628203932721112852139156892903280775223036949323848394414919310082155940615053363132829628799672709557839434529964085755781777411447385312731490258576057970445296620960747711,229349228584333455202515805454481561086661761655883453088894599746824713549123206719584169689814830025633382253625181015273278307916408839487283320828823538420290774632766998050162873483736921565586622385485530453983863042070274251829142359266901387980967335820672065096008596106715431022577378179753339164658
|
||||
10000535283948766913969186677763146947350893764133523013624566402396075467775122389351423347627366996308717336970472190566686266526440447170486872996146388310569838407203380788397656952824650289706008150444069157387402604479170310815759950456001810768733293842505752683896727400110806658910272623240889276302,3517715128667026666780257130236186883393464552180724243651182669587910084592324227192755249223315343739548139286489599592680626480533511441942660471947189354661549994487257423179947475122454624754426244988595239282883275819687054584105503928955994194464535141072191228405010641132986293339925974908519502951,570034118010650587062470713310391834950695503036920240298132931861980289236162947574989015145270228575455513419386383991154247888350856213235253786311087987346865298158646949041224197372582390632868027286119802250763817862749191433673344918830453654023465432067298969962772419746088402608223812814936545467246|10000535283948766913969186677763146947350893764133523013624566402396075467775122389351423347627366996308717336970472190566686266526440447170486872996146388310569838407203380788397656952824650289706008150444069157387402604479170310815759950456001810768733293842505752683896727400110806658910272623240889276302,3517715128667026666780257130236186883393464552180724243651182669587910084592324227192755249223315343739548139286489599592680626480533511441942660471947189354661549994487257423179947475122454624754426244988595239282883275819687054584105503928955994194464535141072191228405010641132986293339925974908519502951,570034118010650587062470713310391834950695503036920240298132931861980289236162947574989015145270228575455513419386383991154247888350856213235253786311087987346865298158646949041224197372582390632868027286119802250763817862749191433673344918830453654023465432067298969962772419746088402608223812814936545467246|59075354970692991755903146214605554332637224507205941847466515241658938543685224447213353186403252887052183944064961699964728259961938411627544944845776708313892390437907961447141588832103578886894741951168483053303302416173045780507296127716028825436246283574600092245162214148065236680479535423660537547914,6142586061770095737227904853540455719428485301510321654081360726874454746843797212863006221294314976215484969948774214251692404250673117267549442037815482195083213974160653516820675375995512277154295678704255795063545010227709473438581077714090470093020228882800682332012139884210689872621538573295925265993,96605184581646361029373732724432135349175091555904351927012123488431445097722589746711095342410196584277564279992867684018993498546178659279293376777551513451631505380655431533215245951077120355215801949799249196142928522335615942042353764886891560316955633828555662725473411497902686741832487630568702990486
|
||||
10000992092359348487480681816729833858083850458212481718635084324812805161168823645716695515173763020806162121153711923870750015861003941980870964102569907660333270160386745314618020099129085566179786211585530303068327607946822258160299176181360948584855686949828385515610423848592364973361809055890165682387,1387707194943048769069000645578034755727575677682880147095892736572338185330919801102067876481652092034533316677281336622039276010947331496276488954193596489132454018768653574924396409513550904384989555254933742194365096022768325215822785577085941233088045260998209615597763890732713200353258054623633203363,717334904486111082107761816895355357018690502858423612748563938578649989943228419203563081094256539563484346776479991186971459579979441405718434993605445911043337999222596585935065011724285592737227690661183256354762587476450143021573235732571046140183664111033663616265739167081365443050278073128430130275044|10000992092359348487480681816729833858083850458212481718635084324812805161168823645716695515173763020806162121153711923870750015861003941980870964102569907660333270160386745314618020099129085566179786211585530303068327607946822258160299176181360948584855686949828385515610423848592364973361809055890165682387,1387707194943048769069000645578034755727575677682880147095892736572338185330919801102067876481652092034533316677281336622039276010947331496276488954193596489132454018768653574924396409513550904384989555254933742194365096022768325215822785577085941233088045260998209615597763890732713200353258054623633203363,717334904486111082107761816895355357018690502858423612748563938578649989943228419203563081094256539563484346776479991186971459579979441405718434993605445911043337999222596585935065011724285592737227690661183256354762587476450143021573235732571046140183664111033663616265739167081365443050278073128430130275044|46482666589787057164981427600152979028584675170625944424946407599960201881805307116957471661211638766618134840736062752900079748534826618093953946800313092285412874757225443617416186449293441503680335786478712016820930243711850679772176006938838607901709770799483635364697553013258865109416434882051210741449,3101717798468321538599785648396208464189816894621339325506629294456148802654755640066207376362353269286149982363784579708988481769754035006891067923386713257060529140906313751403507998251605485836475302614223762235407657418301209467207199741940328204824018102771458491705342260612142478146285653246057987987,154379792819937466421655387360779358004857339117994029103954006768201464432625988196022580370956875717212647779858597489967018623693936133011607398083022906238217469025231498041115162395196295497816525433748189786409656276394144968660209259259055129261299657708619246489632848864169630941858852164482792598772
|
||||
100016993550415829135262361263254459069906572411523652885898601946150332160005753209165983241360621518247046578246408973951913750019427396230791395391900464740479884371689964652672891087059763533492805056734857093926525888370387953270730195624561287530833550654825448807998575583518751690880145682614320134626,97867808093652711513661030354940855898834960524171083907471520733521588237588575528935854367900557849089129501606401645574828485643984844895342166280487749477320616345326562522776423978127616648618120061233592736634312164206210712776242358394865817287600812334839844119000151584498625451416447766525556737091,101546865178620340984298080630771114165409461904937118589108835750643335026750315119287055941177105859697880165662377691746530085636458948369814197349790717060438350144172923110723731589639766266300381349821152919234474715235659078426677984814293485454727036020005038295982154861599467045526190910921111647828|100016993550415829135262361263254459069906572411523652885898601946150332160005753209165983241360621518247046578246408973951913750019427396230791395391900464740479884371689964652672891087059763533492805056734857093926525888370387953270730195624561287530833550654825448807998575583518751690880145682614320134626,97867808093652711513661030354940855898834960524171083907471520733521588237588575528935854367900557849089129501606401645574828485643984844895342166280487749477320616345326562522776423978127616648618120061233592736634312164206210712776242358394865817287600812334839844119000151584498625451416447766525556737091,101546865178620340984298080630771114165409461904937118589108835750643335026750315119287055941177105859697880165662377691746530085636458948369814197349790717060438350144172923110723731589639766266300381349821152919234474715235659078426677984814293485454727036020005038295982154861599467045526190910921111647828|38112895924354771000755967523257705692975308805226188158888846989042277994318034233632572801944291367363544635160689172507870767350780603573652174702847837195353422410303076999489362677424810242035375507542324255582549804459073498689456734177829753341266635299826832746075600445484602669454902196797110414268,29514825972671498452469428270002667581396743351651746797469797047436108385118786112979101930068512381300796319538713657519350359618509818562580593402643136639943548729030802553674984090829042397520519175389582956780710082733565916489480248905811215441925467758974481931055406921284703112579763389522667256173,209369197456369085510398489829077224010383063845121124974155708663637684112727148688124840116395472316273115362880530986565561714461662746456509765896943657967931982155109566457128704664240543108345283001161566864139257311910823070822151712032036583892036613154176268529246135956533435036580269691993608092680
|
||||
10001857278272414635783742468687626112156223003835485801536389954295572560863634462501676022563000509436968020300398791815574826898175032553202096799719821296404518525211113962533485614199031043964942385615363652892938675160040173449995570062547675787656647030050979129677693759900885701969029983016110814344,4689276451232458601825639665209988136946233783317430787463374655024892705415877731372938558103104801918261384975590626995047805878141047994265820723310810966786623993284261416684874325742989563037963206467146622805115830511715873009621433988190289268680824928937364349844265466118648518849937971040073290847,417151168234058306514924962236880342366392470330250088900617117412557071558608977094869379187282436222898630224671275148160961737937513168266914431807498623302460140528881877180166348694674662748849360025138764269398178107070427436885941278328572218964052739099341639294288244256170434477924203033934350673327|10001857278272414635783742468687626112156223003835485801536389954295572560863634462501676022563000509436968020300398791815574826898175032553202096799719821296404518525211113962533485614199031043964942385615363652892938675160040173449995570062547675787656647030050979129677693759900885701969029983016110814344,4689276451232458601825639665209988136946233783317430787463374655024892705415877731372938558103104801918261384975590626995047805878141047994265820723310810966786623993284261416684874325742989563037963206467146622805115830511715873009621433988190289268680824928937364349844265466118648518849937971040073290847,417151168234058306514924962236880342366392470330250088900617117412557071558608977094869379187282436222898630224671275148160961737937513168266914431807498623302460140528881877180166348694674662748849360025138764269398178107070427436885941278328572218964052739099341639294288244256170434477924203033934350673327|39512406098482423779120312488933213318036506673065796538336022993655638182250527755522829589375917826833348984821059004871245970343092490834408525776732580142621174939994986501353324355190007207510458548320626445520306240377159533568686613898702507848891809938754441261902406274233712558160571614302439957131,33458680315871522230740954658476053975126560151398110919331173177225767029941330426356821906446363070251030468052516656211641983986229753635879608148342626307073260672093693099423083101538134818421873088154104042575469404107414196063491342206675483762419581621360672445423968155195195983917204254937268665705,112538323552595379512976869360963431325956968605739748467981199043411580278581204995308070112281536994589175551282469490999392089726267157369534414758432876571069898487221813246689682731800084089695271351717243345819033451481449481940560204129785884663224360555776373560572513249146398346919605386672664225732
|
||||
10001885848475688153826124264809818246080666151576830718882253306412201821167674972767046901596625026072385280166547579462646990262300818624039744400633121727773879619930855094164710044647150456604915949836019563376717637829785627004484641494826695600821088683607312916171680087163211415876920408834836303184,-6401849646396930994521658626667447090190354097997530993450466589091600058118189817231880440719330366452128426380645424906405833189843064340607355709362044588398581812540592198712107929843518387144633043143678667045861106413931254718474764939962100744640406024944116893338624373426827575556627557030324975185,729010733894420808263762284440227341447693348621882426869722779163540379242011358298248405166128119693780872987746515732812024832371695093716504877119416045933332381529307504733200317114594647306152268108402837078447121693601055930678151182644443827620435481034522157377127949376404692708089215142290715182147|10001885848475688153826124264809818246080666151576830718882253306412201821167674972767046901596625026072385280166547579462646990262300818624039744400633121727773879619930855094164710044647150456604915949836019563376717637829785627004484641494826695600821088683607312916171680087163211415876920408834836303184,-6401849646396930994521658626667447090190354097997530993450466589091600058118189817231880440719330366452128426380645424906405833189843064340607355709362044588398581812540592198712107929843518387144633043143678667045861106413931254718474764939962100744640406024944116893338624373426827575556627557030324975185,729010733894420808263762284440227341447693348621882426869722779163540379242011358298248405166128119693780872987746515732812024832371695093716504877119416045933332381529307504733200317114594647306152268108402837078447121693601055930678151182644443827620435481034522157377127949376404692708089215142290715182147|29744618895999892950369062264736486891947372089326189805787662049365991492371249728993520356943689392647109012744687302300685788536119433016012855224253957313263294648625309856809103016565484862180956099939466843259337398301571034092060768935310042949815131108676382925915723778520018870120465703148469427226,-10209285996871914054868241646783255177966316197845761911887894869148957597460422378515655227929008210712234487944652632986850515682880041083632277387837772452379138668071836676947710588769042538916436601704393264463866941375385749221300434945563044575029802713999893603873804815268692854499670177122342861333,245667750146427110150677187685482906099978771660913415239953145936955067540313763536644215438217145059701666728130321490946010447912027178133916738527033418368981585094936292739042791746985193177096407440545894318127458296684680664341938696795502212145624334822453802110708189609055956050992529688916696742439
|
||||
10002016107047298540914373810554280751018084476212026169532336244000095667290766720576480147453702781819098831501724861337484902920323127318735651635800283580581543246660775103367813382337363027395892342097619966629022106712471908155888170784651450900253429516651100879214540932985016853993115133868182018064,3932953570343042122021312972484149360925874859667466184891542534824273073163448674737029662190753442883970728845641115381889397609743429783435425637213409939798177187589001177019943245975437142488968879145205618985792078085357316999616817143927979980310665100836939307474346180730761675171280731347158671449,501820428787763072597412186811130523406055528535842317937667844140331895435375780110188856271616785538949009425271158566975765518229735762290911833082144356638560737127790858277137050097833066958564259261818227652665496782587799644931796940046040067871968056722480981736692953918030967693251282638067356406145|10002016107047298540914373810554280751018084476212026169532336244000095667290766720576480147453702781819098831501724861337484902920323127318735651635800283580581543246660775103367813382337363027395892342097619966629022106712471908155888170784651450900253429516651100879214540932985016853993115133868182018064,3932953570343042122021312972484149360925874859667466184891542534824273073163448674737029662190753442883970728845641115381889397609743429783435425637213409939798177187589001177019943245975437142488968879145205618985792078085357316999616817143927979980310665100836939307474346180730761675171280731347158671449,501820428787763072597412186811130523406055528535842317937667844140331895435375780110188856271616785538949009425271158566975765518229735762290911833082144356638560737127790858277137050097833066958564259261818227652665496782587799644931796940046040067871968056722480981736692953918030967693251282638067356406145|64735528603519488065780804878324224417188886620278284672701068126880574848630151784368770212266476848015707656767389613750457721321054695685260658278678665196373574627583845291930832489025699028328049591231345912341357077706665618380075933900907723135182099099317242925058024706513979297237254597076227095551,4676767511975502628189775967741301363073348373643615464321451471292999156583060169457486234222367809825517380380305131875518326506653500784620820595247817795436795668446618561421217197076229074005115884048096800861583629462266306937502121558685767398985500271610752282597009278306418521631471902811873963535,77558909729073708624985274700160896365175589183029958928607160881016530406365743721430360419631842295388705380922110512036514218268293799548453381932743351256518434510701744265175175287358735767897041689462764452869200380851139430193325516047764774954110200096814808839955087651569998366318539183831351467636
|
||||
10002034549022819403076408239222347017099550415714472028923655065363879242538082883332046406086443448767298655226522786685511031384602322251464988942315474592768020948704552969250388174426697733005815698500285576084348657180234667772665672224649309035191988841439951539719672753703757656633080728573515972292,2010796810968504378931299158317582090146742925585241000850486049458701149088072887117382202081460750175074877155829037914121263394655667323321997117300425990805089503958548860857023509792455388955490579562907955528791083522774450681564161379845706643578690350999966442870934289738064461129972772676090524913,558321669961648887847428632824052548431625768519625138834794746205714201508858412984925892097351057558062620149468106508584560558388430324467000609767675063271492932614039773497135546738436362846803805003389182782828963768739992366197919348230812882254139576244708687275965273358081737826555824405654768290694|6826578859626734597480939133878569229694460186644971629457853526114421649076835335603573751879988329839397104649987465835398566386002039755592773568446984903389961798459390528478761929712163120494037385730792909171532085167309911050308445263496353865937264941597436020907055251736048076644006844409202248304,5916703632910582851125880793132408903816292476260991242513549737921610794279828040608017189829216974970365350284663821730060215581487763067707193344265376739551991053238254698337087591646614840450823227220261123886424801128338724411047128491092060105475853943890821103779036774500319107460531685286202841441,819164879939066316247739921674596158995075399415076526828586576697986820808489862654252316603348700696267835592140978359698748448462852314742485570195189002909951418034161212683212111469166114805395316595157859568773382000204444562394625047968122644730117571140576687713835978983039148632840884180063353321919|24525593055568742416097249604269483346856874441455178370798633512644823613408551383898889724136436641596007886888916843304556505396562460452498580122367837296026711996552032327466172455184570034171840642876125912558571322892683749487069829210684821264854566376842632617791479252532263566234814371052354893484,-1533308789349159850456496166928278185899248924637820082743446320631452265558278807739507468009525157831824183682096795742851767532204899527778707496003773066153051313109361171305769881696175185189326727846932831915940721252274125841396183853650527186995865126146441484052102425089961043364891055445991541807,227677657081722376213157149142023336288707753333770972277638057778548802624067098792373455123375286502620159760351354502534495438446400227420867854824820469572948638801811562066346273782346907474917163347261714943740349452378338981756888788776146521650040273657711500699241321825395413707817445618060462480902
|
||||
10002074125017355975599743151046242846511112798798396053226619327592735057422378177948114365284430939135093491265336806767482478919758311098907293451660632908142687429542305038471993566061112091142254674235636984969318093242303552823770654042157452160266396125764144057012639465935378258561790879307671193782,-2677875592705731980082114894429792995071386706298929334230749772186164127600272370546755010431170895608048375369668020170159823760294147973474095537503850192302837032131733237064875342982073993793395058782971441692000690573793255526540716486233592692407763281116363187020386252791667246848349317822548915689,648635985571325401692595356147567233561468612108663071405974903212101924183730392746938934107001054497457734923399698902258386855829500228588241165821030031659482670628135844118612829510920403042586089191580683729603024542404607259365592152472123612035976391470864076397175842526847201114587386293478162448846|10002074125017355975599743151046242846511112798798396053226619327592735057422378177948114365284430939135093491265336806767482478919758311098907293451660632908142687429542305038471993566061112091142254674235636984969318093242303552823770654042157452160266396125764144057012639465935378258561790879307671193782,-2677875592705731980082114894429792995071386706298929334230749772186164127600272370546755010431170895608048375369668020170159823760294147973474095537503850192302837032131733237064875342982073993793395058782971441692000690573793255526540716486233592692407763281116363187020386252791667246848349317822548915689,648635985571325401692595356147567233561468612108663071405974903212101924183730392746938934107001054497457734923399698902258386855829500228588241165821030031659482670628135844118612829510920403042586089191580683729603024542404607259365592152472123612035976391470864076397175842526847201114587386293478162448846|67949938415113064293161178659030590691132496955041316494045733862875749417850747302562113500007310852668303846586641135508462313201852828769777121178050596003427926460422904475476244906898063142012649435038037100034350908875980928269206397866321214852019966694130786407505714074230941338096203488261864055662,53288668959102688425004591339691466327049075866255869214424335604117440952293373897678874847548640712084573721941183729796456325294146528429835461394439973255133211226526484818899123041166158632993340470979352834271983572524972059884357370847142645448863117621210245351327485761671145696210503054900410821273,105899036571802576293359771771735244647493044658191270723159384029727618422730315689072753328136534522456073200532359330590111785906447289835484981246848193838501538977975954024004079425925298710095769756420575788761877694146481988831153103750420171232975154220500803062063592047512891980560706613446433318602
|
||||
1000253663479701075381410901780503799818388911512704954335021374915858764824090995263167708417293347017273433263645587016366542848367626143993424043714190337762737334693150155289579305664876408056173092807453213218218789600598025704962632695206955492435575043105375877466941810990278101450609180156411393563,66294252873466406327783927757894402143872047742685585398248434686370376436933447604037129338463580005900665059990247763362159976852149607009612276330769317942643706356713296053874697713940805071384498697200382739281769000631492714220560824564622672983217861541737814215572898066821664279189734871952442485,7449081821920052343907585734636804107890073716887030220252146886374375473495388497829441955869708386804952455148603275078999958645575875758803250484635047415319443379977946970239132988474813562402674036138638943113227930164450433318295035974410121827732702738775533740738542926454278142700154894632584181276846|1000253663479701075381410901780503799818388911512704954335021374915858764824090995263167708417293347017273433263645587016366542848367626143993424043714190337762737334693150155289579305664876408056173092807453213218218789600598025704962632695206955492435575043105375877466941810990278101450609180156411393563,66294252873466406327783927757894402143872047742685585398248434686370376436933447604037129338463580005900665059990247763362159976852149607009612276330769317942643706356713296053874697713940805071384498697200382739281769000631492714220560824564622672983217861541737814215572898066821664279189734871952442485,7449081821920052343907585734636804107890073716887030220252146886374375473495388497829441955869708386804952455148603275078999958645575875758803250484635047415319443379977946970239132988474813562402674036138638943113227930164450433318295035974410121827732702738775533740738542926454278142700154894632584181276846|24568037830590216352984530012697330969024585773239190902318728852976076281369516446912320948078334220155283803919583544158932277992855289960471883436534381687899324079630011764816867889328310023423094633012275199876596315083044545869380586009580913007036860399795245680314963399389559624688311082823805090231,5319068676363461453927187061672827259672166236556729558696928212559807675749791870496620364221934584448485936117599756917409724038460841591469075162277678937851596763739958878425260723977292640004766308405052660448827954872311329092739598965306131405515429262746842239243566030717413542127898656259746125971,303566913138393892567904204367686915490068122814370585780506941778399006742359108535463859108136357801343091343038391472615790503246239776473238906631454625779972045236751565874336398670607783613554147722203607531035833062634596664836955674449545888313212125443460195013735390947268982347767364377764736422042
|
||||
10002641226772515081987795211537787929272477458505554463354638964352971364408874452069546961937801811210947177338408164991078687591091465516969203874900752888301636133298179753283838003443413422949614854305289101035884523695670918489325845677592608946818353360132477183288514801318828834214935649039394032252,-8793160452550363276528664072517898739234784407606709040941098303790678596260001324417462973553168029853952326856848991111004093395583096302100461452777142804629182141499607986715453131122448708636069213611853518781262192482364818383993101471525466753092118188242931192181704912063647353300605222746836800483,492078265126922274690434467399394077805701275647322071646319840779745006934618899651871133218190471317339124114044099413606811819906582945782428482112475530640807894231223382852644187084233002016394775416098135698147532762509163053201184493973160623592655199338520312133914851239167130412730662124292772722504|10002641226772515081987795211537787929272477458505554463354638964352971364408874452069546961937801811210947177338408164991078687591091465516969203874900752888301636133298179753283838003443413422949614854305289101035884523695670918489325845677592608946818353360132477183288514801318828834214935649039394032252,-8793160452550363276528664072517898739234784407606709040941098303790678596260001324417462973553168029853952326856848991111004093395583096302100461452777142804629182141499607986715453131122448708636069213611853518781262192482364818383993101471525466753092118188242931192181704912063647353300605222746836800483,492078265126922274690434467399394077805701275647322071646319840779745006934618899651871133218190471317339124114044099413606811819906582945782428482112475530640807894231223382852644187084233002016394775416098135698147532762509163053201184493973160623592655199338520312133914851239167130412730662124292772722504|33269093498653459355911056721677057317009942094586213583836482429509057025072754420372439736248690513834971332175814464148672813487558426999636798377556094849446738441259743858358991688742216573871382813744898911570710319471125784318155373816902285919608190930249032332855663246217414413642466621378338134637,-10949330241414165733888189262458140426986707558351886540903470879800574033213186052244846799127577601176842705714647638204280400911455131674484085082600626371557414203990940725212684526037217982855212341310843343357217588085473017983047320842712153347738590477893040712557903922232099275263522420010197087053,148267471797952946823163847078479485183284021963476657656706944246030488584019895488346778002211592139277760491813666056346782934726026456786554441575227882221237740554377749215785707126496176370984922985820419829339644729974154901755996939823200818910973576565060260711661905159023290114040762532541467088824
|
||||
100032603932113584190385248548088424648269645571686859576017823592423034520849963520508387815309023735382902503732005885189155388332561494704539042592634007656219743816845911733895132144423102052942452746877943975353248517709377531317937542644854604549820822373960740354167669496547979026679046866602436687763,-99537978095529356699713913260068351078290498972088228356731296595606062051578098868796341286417844471545193824704430742131836251590438154579238324251435089098889846479244366361006756968943661462663756515208457066560709300104052348033879750430334191090716067038009316021882909761152311655341491437691827562957,100461141672958569681488420113742834080404730978030677210672600173957843011309217083950874294428866093615815291020711039763544235459696431813304652678133959812856917140520431023445877504376180839416510225066460002908711498876105285713692498849763216560421523587971326926569083287005470828615251682690932454480|100032603932113584190385248548088424648269645571686859576017823592423034520849963520508387815309023735382902503732005885189155388332561494704539042592634007656219743816845911733895132144423102052942452746877943975353248517709377531317937542644854604549820822373960740354167669496547979026679046866602436687763,-99537978095529356699713913260068351078290498972088228356731296595606062051578098868796341286417844471545193824704430742131836251590438154579238324251435089098889846479244366361006756968943661462663756515208457066560709300104052348033879750430334191090716067038009316021882909761152311655341491437691827562957,100461141672958569681488420113742834080404730978030677210672600173957843011309217083950874294428866093615815291020711039763544235459696431813304652678133959812856917140520431023445877504376180839416510225066460002908711498876105285713692498849763216560421523587971326926569083287005470828615251682690932454480|83415806280351408759589239958761219329310176984650613508633653230456890652830525586600995644504636518476026029385588047137454270096528621205370620292951275504650266248010650846690600983384462303830915876850693795019055500604246841544238285169828416374845816289496545562107780789460316448092131365832361151375,-74625562140946530658296843057459607794092129677035083950600450768713067569753818651802415894941493999582236546770594323673470134033058099517659971836561944651594028658674853294680303580112276880640835753725828631472628486095723473976221487197988748307970291488083264976555432132424815586850501052682570560083,107469811246399151523671670639445335406080264077456915839785825558020206498489889359444002816596192076606675057819088885526103113392920720840544571898931473254561406865074149733521627542981016723238264871496686055481103379945620155327472162297506458535202575738651893005921523712726080367985636694514383291872
|
||||
10003476324006195750203056589672528920142608070881173628253070002202847822896965018507956629750620754180015153597378490052619698657641883238019501085375230761464051022240631149609917748136390010621917552270797301343624990317089853119601059038653584566960989367701622621948512038032835888249299441269693147481,8948477894687501835769347042476812359286265266925800130378128090450514350343716170849427570408163707014128103924229513747579348337292452228930399170228437675863524232253003114523522760158376999688617602181401251377230973508602086745348949552684443228687100653278976227886870750067529496753791759215379958009,452977737155070764205462061852384767406000511527628419268926246340664360293838298755195741559726771936393803381121945775594031166662560564547853061983512305458290529662211961236299108870033900884457317683226459798783650763565076645131166564022405125204306354508519035128680777341173496414054336245228904798396|10003476324006195750203056589672528920142608070881173628253070002202847822896965018507956629750620754180015153597378490052619698657641883238019501085375230761464051022240631149609917748136390010621917552270797301343624990317089853119601059038653584566960989367701622621948512038032835888249299441269693147481,8948477894687501835769347042476812359286265266925800130378128090450514350343716170849427570408163707014128103924229513747579348337292452228930399170228437675863524232253003114523522760158376999688617602181401251377230973508602086745348949552684443228687100653278976227886870750067529496753791759215379958009,452977737155070764205462061852384767406000511527628419268926246340664360293838298755195741559726771936393803381121945775594031166662560564547853061983512305458290529662211961236299108870033900884457317683226459798783650763565076645131166564022405125204306354508519035128680777341173496414054336245228904798396|5651402082864001341383043857276519034370923662130513841623791595519661596270558403629904832806805434101124739144545597592273345291679321664787896528184481483087832442891723960004144034071036416654549567647433046035924426144596821847342448417665300158067728473706875334422169591609969538712389716925515442159,1090636869023214934530000512317584955330428598448445756182897777909589608376391586933678383330159027516570062459675025398064909568706408769200853022274439337235651672149891920445243421589467522791785184925567074521782213195039081340473683210796200673383772228925769534634646704414996683315287011695982045215,798320586788500330131894474104550120349737015590338005277237799938184156294041064946603812109197024144698401875127120433554460509300984485272200798966972702950997831115495437993447800151856526214460125938349981191215783025651707239371732305323555609927700663473758594406982664526774948117622844814657936546368
|
||||
10003857993456427654260743531593175331844381828365670865226962439897092670436459982112189381696267158765639464830025128699564487196364496581401927783840749033897594251479939418637644343310965529659395490594160241233118920895398385679767173659034336248678548857485551806702464695049628038493630764757131936433,499412956562517742917849279756715433309262335746117865845799881793024584024558389384536935608560698495018673505480555335883339312289660314988198774876439555916228389426783735627572745304130362478355104078356335948823975431983850031098878540627311553089477219658101715631431867688289331308014437329410794367,428065574132217643458625663050023831718642242887566540643235772550790937328471994487142052675941441071975523602876098842203000859003355118835451924426231099194913042875268766884651796522017073832982218720474562973379560560341143898312656272368395693435837758889298389279644428917154166725285871991579086938078|10003857993456427654260743531593175331844381828365670865226962439897092670436459982112189381696267158765639464830025128699564487196364496581401927783840749033897594251479939418637644343310965529659395490594160241233118920895398385679767173659034336248678548857485551806702464695049628038493630764757131936433,499412956562517742917849279756715433309262335746117865845799881793024584024558389384536935608560698495018673505480555335883339312289660314988198774876439555916228389426783735627572745304130362478355104078356335948823975431983850031098878540627311553089477219658101715631431867688289331308014437329410794367,428065574132217643458625663050023831718642242887566540643235772550790937328471994487142052675941441071975523602876098842203000859003355118835451924426231099194913042875268766884651796522017073832982218720474562973379560560341143898312656272368395693435837758889298389279644428917154166725285871991579086938078|5985067419244985135241171028798929574240680468883302468191968098879216438700233164875805694297003438862738484975665356224507623680806342430269752869889205306990703427045634087633153837909332034829737848013329051690528535659192743560129505700514703339932109459152656849997168043791609090148125676966411164474,-3013789663785982033470828503772197819235935022596925513202295899674251698616743229507943605240952571134961898221616756365279257136756498538053825862952363683344784599061589171181375336294364884944425024815089748650913141333142482818080242503626668488451409454453378105252995530177887117956522924628476106577,715867557387629444794828253143137494171652360384349041477991757900406478237922421388389881678979412011018924778952400351577186261046593876844081918575484239857072969176632122684840733871691016063878843026835488228409619596420110671483199617250854032506474798364927317129700200264636864303167131823097056257391
|
||||
100039629164915279615632745626755403195135344051296300065703707540722103090866387847978086519807842461360227602981314815898651188162817881999812578911179147999641525372151514639575701701027057192828570924656410854140601616073626299097374452319600612002632648030238739679305929396591878384845108611708173073473,-99956757702796747144330474031362091634322580823618978945421296776762235722820502139320048823797118970112849105309821058917042066320137328941305079762427354700730983116887319872947138001541985096571674792479594585340751798952938060950882542376800246430517653157385999869147535721348848735105635711972964679549,102428094420528235210038473992722778047449595066683562474358311327561453376741151333873834215335094090938635116665776111534217214948922896682406927145735733279560659220902423840693623822669973775960053647983979336042821226775972118591820157680473747907152458057697531888053067296726895267408102940444171410942|100039629164915279615632745626755403195135344051296300065703707540722103090866387847978086519807842461360227602981314815898651188162817881999812578911179147999641525372151514639575701701027057192828570924656410854140601616073626299097374452319600612002632648030238739679305929396591878384845108611708173073473,-99956757702796747144330474031362091634322580823618978945421296776762235722820502139320048823797118970112849105309821058917042066320137328941305079762427354700730983116887319872947138001541985096571674792479594585340751798952938060950882542376800246430517653157385999869147535721348848735105635711972964679549,102428094420528235210038473992722778047449595066683562474358311327561453376741151333873834215335094090938635116665776111534217214948922896682406927145735733279560659220902423840693623822669973775960053647983979336042821226775972118591820157680473747907152458057697531888053067296726895267408102940444171410942|59758487461561694442379025688208789272805646117766841371919206129104643340187013959248829747415979662207515324483234883850993532329266696739297473585807619628400010464577117227971680163239657561855113693233183544551556435408658445465178524557249837569329921343630595316681776567395248915519114258200940556334,-22671153376331064045596883212849524458683137875144383539728632975135493675352244172470558064096651200683764074233134897430860850593927295220691708458835598930765635309529560060316074048705829611628256591181426206810132007799209323907835404383161225433151628885627129593154801395506335278453552670824539376361,131822706075099232761447085662042248387269214384273446870979850351593187356535380305031128889463232587293325792397508871970239127171842305342534211852386333093595103295196214505820601536505750244236747510387243858827641299979267104558491688743963318805624534666949772263803599250156326714304699457238299478944
|
||||
10004832714804908103723742535198592770160203517705805986990840545592954373052531534772757807185128680232142411531940850138353354052288042367716414491900227710660117192168358032143450533265736882961031789512953512836372805323721228539257249690634554067409180163736018674169229333523619015614939108311094404955,-4106122534013672070279170985250180991164806091813516237606357362858804809149171076685686783446662860787711693312632306442369721226548746949829113367814838200945066703674460902843843266912498986340273761329459609877828321975866552396500360382623866557971900410837449507727615090091955001901337773500512564083,735528321490864741305341471765335107420487103909921951579694743548116478766357351448185791472115882125120532716552174779001460694927011404974670401193452353207309236668713919095870342289746072100419468138261516298395168201040490324057099586440436334562163475983175689744239719212727501982130267247535538654526|10004832714804908103723742535198592770160203517705805986990840545592954373052531534772757807185128680232142411531940850138353354052288042367716414491900227710660117192168358032143450533265736882961031789512953512836372805323721228539257249690634554067409180163736018674169229333523619015614939108311094404955,-4106122534013672070279170985250180991164806091813516237606357362858804809149171076685686783446662860787711693312632306442369721226548746949829113367814838200945066703674460902843843266912498986340273761329459609877828321975866552396500360382623866557971900410837449507727615090091955001901337773500512564083,735528321490864741305341471765335107420487103909921951579694743548116478766357351448185791472115882125120532716552174779001460694927011404974670401193452353207309236668713919095870342289746072100419468138261516298395168201040490324057099586440436334562163475983175689744239719212727501982130267247535538654526|49571248488801947323762143907209086317313166403240424924024453432101823875387693931106394388064932448674243115016411805337571297304108452331736192767907165219921775519019524307831072755876229558621548399009624087618962075649066655387832586784423916396427426550173498305707525522262009377144776100617511504479,-29828959784506381554151288596212589266056524896738496309595862456247322273883550277461362725785642216517361460931008602989968457887994880159243708746757201494721079152033527869271494859280160324467867179845744346034683576782637256359631403582150391967236780147449482496203963125132702633751829108018063107905,152851999786112534607728017818026345885853920855328921975341927606898018268835818661916681924713268354620755264611816045133624308753790454966902035653944158070765154497702110731650604894939030177902410742021315843443639601716505769494787447868225921446367758854610060178076102048397807948745556177069401434816
|
||||
10005026798525081885012940723882427584501711356233986451433820326862561577003483273848888665415005023331324845917111198606297565890343057122006058437816088078150993643095110440273546307247953190370321453395387856022986496964659738868016549698302294761145902566546443562453064814285197415999088360521895892448,-2012773415393071452341702894100369945009950648974284842979647951404344133571843387257391629610481617222572984474542523680934261770552452770758419481294248980432288030428538457156536090278813518012614750771478130023297469887908317305397718948039728500945544029263259198696111632370324283021118376979818613221,535224191733498084376882360698126323023228440191548650672747703583096856785431353632400792141685069598130344590929419053715450660967162173014581599286976146407034427713180051638727241035734570695485508350936098840329272631647750135734419630658939038108543820389342159392044477918576834926838103968922627914592|10005026798525081885012940723882427584501711356233986451433820326862561577003483273848888665415005023331324845917111198606297565890343057122006058437816088078150993643095110440273546307247953190370321453395387856022986496964659738868016549698302294761145902566546443562453064814285197415999088360521895892448,-2012773415393071452341702894100369945009950648974284842979647951404344133571843387257391629610481617222572984474542523680934261770552452770758419481294248980432288030428538457156536090278813518012614750771478130023297469887908317305397718948039728500945544029263259198696111632370324283021118376979818613221,535224191733498084376882360698126323023228440191548650672747703583096856785431353632400792141685069598130344590929419053715450660967162173014581599286976146407034427713180051638727241035734570695485508350936098840329272631647750135734419630658939038108543820389342159392044477918576834926838103968922627914592|22336292342012135551012779505885821083546735296581603650297115029465681138287871430168423025904988089547671399414611655350486697669350669877738276496552244732628186316333718561702084292478964766694437983324796248956801158028485684181499933232337147261336601523192790302252474972512181980447183622505293176152,-11674427075188626733931744428592651339949229796533683950532721050654863919331228509781516498261584604218739331608896593403871873856541410150113580209210756699310754431102708096662231135908839829374052715278169746619957236796967122303020947804850902024480676480363166504231340429878256710974972888619078138229,241221441172507985920847839600569201674621990755660781190984844223834501365279182693592593623964679309297220103180052193705500388401906318363940879681334805954355205327811300356578283407461158222974345862172435329520610152326479352290565487656045066487426033103805627728579179611865031310778705197856088085583
|
||||
10006672794990347502279526000879267078734551177313370372283212271611928222796898904661389050998596001740140300896360857122349676163698172929644657861948036337955651058773337605834505825285215111994884147090626904932283811767278804138486301736275150746935294318794069137540121225700303083939876242601120625682,-9838237801085818249924597009069669407425270661770560087620729925196161025957715438545136585598174869667669532449305460474170293173380362768481774634876936899174710462784386243070041206971463923591073715195084153396862556329146939171493281676244388685209328525900813769124322086835985741784348578408662428059,491155226409710325351546145673359292444301383692142579605004960553566299358747456958419756937691174297624212871558627081110141997099054271399339089662075140351079784991312987158527194379830582795343003721494456884032748354538831215203553329779263289722351779436025499608302937937453427548391343898256662436681|10006672794990347502279526000879267078734551177313370372283212271611928222796898904661389050998596001740140300896360857122349676163698172929644657861948036337955651058773337605834505825285215111994884147090626904932283811767278804138486301736275150746935294318794069137540121225700303083939876242601120625682,-9838237801085818249924597009069669407425270661770560087620729925196161025957715438545136585598174869667669532449305460474170293173380362768481774634876936899174710462784386243070041206971463923591073715195084153396862556329146939171493281676244388685209328525900813769124322086835985741784348578408662428059,491155226409710325351546145673359292444301383692142579605004960553566299358747456958419756937691174297624212871558627081110141997099054271399339089662075140351079784991312987158527194379830582795343003721494456884032748354538831215203553329779263289722351779436025499608302937937453427548391343898256662436681|31407608254280798910068647236171832681250921019767339322092058225211898617080663268645257485291372241381998253211825069099135787304279471888561584499577479790815455728926265455210044341705458408895536936732959677488304976642419035897631658694309182269500334892813396007185893728237634667266625229835842258012,-22092195466303851660176460286320107196721548719910482849923927669374860570040607441847880914766942886335893807802817619964909625774361248243281497972957437956640995020582500875700785617741050040570062784832399237969854446892064368205401494750753136317996032567462911904310221537322445611817601703460856421217,159599806073129555202146898538117276396235868652725582464386632067108341746813360586970644466851546908557689300426749066266037355857824949308514825360431584985378792225819436535456535877098069496677684472533670862820828085751117871568305588734769334428789980131666205325600082215182496839515396421731764800737
|
||||
10007655975072154117483238977535537637081635031134550457387493208328357153313126763724056490057039627482071052486779071595119245261713445964779121986765033599055846695490518512461118572219672259974233020703702627262496120864385268977830794693731299984872419878272800221037178910859958719636556859814167846842,-8361996877393239419962455468169075798408150795370677399435249551651328619535668258497248839588331109071829636371568824578953377032648893445576430394495769342785817892484051892349027624952023346102193243274713308717688268734992258026540569970994360123565176304254781068869111211172521527332383420931814632155,527575030718114283859783398581144142162250986653324445494333022369741458612967189239531512810665999743981788039851897018720856433180698951454061341786291502239652788707044944021930279936172715091766668769968367606820938741461139670556714129528610125247077397188304136573449554427712758172626387820770141650206|10007655975072154117483238977535537637081635031134550457387493208328357153313126763724056490057039627482071052486779071595119245261713445964779121986765033599055846695490518512461118572219672259974233020703702627262496120864385268977830794693731299984872419878272800221037178910859958719636556859814167846842,-8361996877393239419962455468169075798408150795370677399435249551651328619535668258497248839588331109071829636371568824578953377032648893445576430394495769342785817892484051892349027624952023346102193243274713308717688268734992258026540569970994360123565176304254781068869111211172521527332383420931814632155,527575030718114283859783398581144142162250986653324445494333022369741458612967189239531512810665999743981788039851897018720856433180698951454061341786291502239652788707044944021930279936172715091766668769968367606820938741461139670556714129528610125247077397188304136573449554427712758172626387820770141650206|34241072322144183964883259292388971270387490908021459682602920713448556112203521610314068181522265567865990070656464669642401927077378188525809052299062988871029831250362663444310773841166814396928628138166361702759595641474414467093470838454994055079747035830130336863078894622890889652436509718402679470062,1655044484629008994406707658240182084237566731635262662670986570402287449045651466425429233810999012995111207637792772902737734854633738760139439026788661518884592067665179528199667479368791803292009159500093938626059289257062277449763464663360562677734593664715953368375153510854218241931074507165471380277,153704107279914282661047729774770107006301606465000116416112632832793659221845961744254897413922500063463878032418234980336383112232225712099359203910269544199247014938285831933417628129448739918915220344920675471322163945672122675565456045357008398369947791399948189771245653263744530465795945375711800221494
|
||||
10007966435478170058236863959453072022400241955644959598691575049123018331553853255192930054734316870465371869338898000445140839711278341717767617282979890871322011741629926128943966839416929813730135095452717804664810492420201325502018871240152164282158649420833075991948508448454814819879697083763652090752,7668231477440831839423530692551370703245159224024821557501520508935072774934016430350932340192015949812739085292897564854127442271354000519287430094037838940253057942410525639491576166138997981100229304259461266977184946214511723634011266273522059488169041964372462366036564169749432744133670979109152595493,447718029574060000854039425364603339241323607028045749886344661853336043472604487444001370995744392053933719052361283419535725001600963164946166051448582948801443754508763343722896658178932382756498803522119159379373755295799841416904795415386643502857959662236798809639975132008241096398997653679085633708897|10007966435478170058236863959453072022400241955644959598691575049123018331553853255192930054734316870465371869338898000445140839711278341717767617282979890871322011741629926128943966839416929813730135095452717804664810492420201325502018871240152164282158649420833075991948508448454814819879697083763652090752,7668231477440831839423530692551370703245159224024821557501520508935072774934016430350932340192015949812739085292897564854127442271354000519287430094037838940253057942410525639491576166138997981100229304259461266977184946214511723634011266273522059488169041964372462366036564169749432744133670979109152595493,447718029574060000854039425364603339241323607028045749886344661853336043472604487444001370995744392053933719052361283419535725001600963164946166051448582948801443754508763343722896658178932382756498803522119159379373755295799841416904795415386643502857959662236798809639975132008241096398997653679085633708897|40511141969971494931196941724119791194752303140317604712667802312789797258087471388916305711860938934695113621471555129205767772174234194577636062024449049659844773057153826765602668788474097413358584157199226050803019714953337366130977602640661927789662051175267419967969752702153115129111296636218703221612,-10457935161594282983478001185436442312204066321569717319909561123122508532580035425990850447859762708795499274494409851573173766858979090795797351580839052039648316518437023326040967891533445612383815607198257699325318317220032705269084861881246335591645639989108557010113256147197407668582018981690523309277,110917353905486580092614272588489684725195855203152146381960572034045032865176004516881779898341056044802327638909692940931520745099129277448149432184154526338845672459752333598562775198340962552587031950250223610238795938815226253408453715102541267901432200534831078606195360844918970056237910632079232669397
|
||||
10008244313737062814090386880777002042274406310106728621588663972235471114422710824990333652789716385198940169070112715764189602790244309290680116655115170883594213904067142922764109544956215574952085160301875958128721493047843010586892757750339772804652221926614373576181872540979939178502806140149454950631,-2481333037464667013966629436643252131544342493286852105020088420979287811035788180793459525355154058635281869829040750298007562342275673082167816644462962921681726865943832615136603374637684966019868013077849325437190351276393203980513956812271998916894664710817164796538864396449149557648172823426916063171,517388856778664723601259064328056938198839891258102587545663260307743028813773980886782766877880248247356976487931222165792012525513693034189039784629831615801247177080220119155265743113547860287043754078724492811312457109356002302194457816150319735657096232303313256118001093875043014711306978887626524797260|10008244313737062814090386880777002042274406310106728621588663972235471114422710824990333652789716385198940169070112715764189602790244309290680116655115170883594213904067142922764109544956215574952085160301875958128721493047843010586892757750339772804652221926614373576181872540979939178502806140149454950631,-2481333037464667013966629436643252131544342493286852105020088420979287811035788180793459525355154058635281869829040750298007562342275673082167816644462962921681726865943832615136603374637684966019868013077849325437190351276393203980513956812271998916894664710817164796538864396449149557648172823426916063171,517388856778664723601259064328056938198839891258102587545663260307743028813773980886782766877880248247356976487931222165792012525513693034189039784629831615801247177080220119155265743113547860287043754078724492811312457109356002302194457816150319735657096232303313256118001093875043014711306978887626524797260|64779254867032834011440641150787867084487920384040666681242863744168381419066139445297813847374258248415619741363374551837200937516385938256833819108665346550630274436247175069020139650724403378810927075885582938267576954742862532587966930483553143703545329576408261048628895456023143683431401990598479630366,24927519754546965921961831708915463327214053646451495956699845075284971443847002280078538714647321447563383780925628397892739377674787824980025060340980938596623558107083184245064110657008379362919768477366918649506291628246060968841505524504481964062641513562929769991452205428879332678008403472520391251145,82309686205222727769575596923556209136176331852352419263671129190093456370915941776219688571948801625823542691573133895930427074460493264530457559070546811793879069016319253690636501038391024472030629593224593147217100960263693987497514077967804017050957134551364124670419141176242216681820543629095623072541
|
||||
10008352850657920583191404584913972319002983012580386292746025042416454380781500166787911252581886951373899680476686789855174455691633284341038191233672952065406558892215211615248443825941676410729187290225060888418790745853338806784833379906941049072152726050837490871126796612653775780560679723194628349029,-9709060422739575026005372809573612137660920177893029425373199378974797630708961048789082569968621509437270608151157000245230087521990222886335775421061577025607819009612244487407314145511220306148818899675596604132364981950337516654200767452148218615182517964628917157152074917236803799933149738760713914115,671115082942262350108425488433280481526339397188879799636007596624691786030758042881307602706684291172315374822828497006497958099138318651797094407888149790626224845978208367284081376364107905539290535619502916118224586762249253502377439399087435554291997555942600131361589961111751560971988821471576625969886|10008352850657920583191404584913972319002983012580386292746025042416454380781500166787911252581886951373899680476686789855174455691633284341038191233672952065406558892215211615248443825941676410729187290225060888418790745853338806784833379906941049072152726050837490871126796612653775780560679723194628349029,-9709060422739575026005372809573612137660920177893029425373199378974797630708961048789082569968621509437270608151157000245230087521990222886335775421061577025607819009612244487407314145511220306148818899675596604132364981950337516654200767452148218615182517964628917157152074917236803799933149738760713914115,671115082942262350108425488433280481526339397188879799636007596624691786030758042881307602706684291172315374822828497006497958099138318651797094407888149790626224845978208367284081376364107905539290535619502916118224586762249253502377439399087435554291997555942600131361589961111751560971988821471576625969886|16114275461489124968204609015452254643913218363912153828520620336762113684215205643094736684144935580728436126433843432822838401301502605946365466722979644980151185661620762014580187078928560591048729719792010275975517300898462040047538702188845074821092289043342754604938854931775373800424648368644203310763,13547284929895770484441101131779787363607604008853234716726800689182086390631494419380414868563006093483607315075063367989733593307441496946636597309123175793027336201138908596859844194042146843338047555922226658114601025214153360367295508810902077991437858537936819515034120605401664389985997179289268252367,418205108772032981216907044691421436420223410030163644353520139623926934302604091399665635789664245218369914570143791026851295152484545480995319870729672449287479092631425718630481935403940901614139408947960419781742920397934070995211934874602805252466775364873888815295833211854864682623780313523183909895620
|
||||
10008513012069041332156344897527216827073553214887592180214088737934259014714007486627977262733380816543933881903835772165306652083392244023687978336905351870998572186485570559256669905157006164174099943880073052263685924132434457096891529676454801384608866315724043225840413063557160938985851639441472622874,4312440429846754396035977404383353442711216523950513352151701783462030788529545110163564186199448542666033789397218053312248834710387435083551347290942668449155398673665487605130911092851155993391138549740383991056332072450757325017931588809593307558375428030693435084458386227675282989067613496797817920303,522058710434436061847099419719287842052400501259816466826452187248685474462894015989166683733824910524432920930163132078895575756633553848962708405953874665062957204347147145554667232000278570561581943016274309565656027423053224928776350261510971295444303769013653510888595366416887399411638422346190508715452|10008513012069041332156344897527216827073553214887592180214088737934259014714007486627977262733380816543933881903835772165306652083392244023687978336905351870998572186485570559256669905157006164174099943880073052263685924132434457096891529676454801384608866315724043225840413063557160938985851639441472622874,4312440429846754396035977404383353442711216523950513352151701783462030788529545110163564186199448542666033789397218053312248834710387435083551347290942668449155398673665487605130911092851155993391138549740383991056332072450757325017931588809593307558375428030693435084458386227675282989067613496797817920303,522058710434436061847099419719287842052400501259816466826452187248685474462894015989166683733824910524432920930163132078895575756633553848962708405953874665062957204347147145554667232000278570561581943016274309565656027423053224928776350261510971295444303769013653510888595366416887399411638422346190508715452|56624718412625747746001342620243125157932460809156476585686153252078788391585133765039303843105555487145302765475232301210334902069549060211140618709834572969221737838704380629832808447436726398836532031324189279819743594568958857642880728907272717965484249241620624993448126533648876371412676969976240808091,11251560979241989333315174860442827950692807971893794693178074029555222489351465658673586544289854384482236484135520000810924047294537285452423708542539424019529971512734796753346419671011832872098038047241101770150064698634673955572614027093346044433647412285209492755021945840975963737352969268461227245507,92751569706316371333649854241258112606711033359078430605766627827390581284909646252513959841970681664755979852330064323247275252913920697545008377769665486889671185641317526987823359091775252097776601502427528886408060350050959249578998479135473207338710170069765535652326679605884886200884837141964865764438
|
||||
10008863920545293758159888428446364046156260276486716019468090049016703539043486840953638396736429084536043888977532647111473229479529562166982909202873868243789742163658153824593686536088450915373691535781953841623992587097366077922476705574496276542011226471851020760887612018025249445972903686455787297913,2645740853855108763896589086717998001934973089513790734148937968197932490008236360599464772889429848037464262397763532307275971891237738829761101393275168415676294997564886931379267812086428886706751772215615432393366054082725778686112559307784475932288658665407220266586240637350907136870607040913290590611,793400754874236243676721564968016542454513488899050997526586540816446069760957715423992612546686769171106427349384375943641326144133116588670645501231299064478777846694278704641598622565613076600211712243453441442617903127555189233115008530187155578099336294750097716133611190867259168037807083105588642566246|10008863920545293758159888428446364046156260276486716019468090049016703539043486840953638396736429084536043888977532647111473229479529562166982909202873868243789742163658153824593686536088450915373691535781953841623992587097366077922476705574496276542011226471851020760887612018025249445972903686455787297913,2645740853855108763896589086717998001934973089513790734148937968197932490008236360599464772889429848037464262397763532307275971891237738829761101393275168415676294997564886931379267812086428886706751772215615432393366054082725778686112559307784475932288658665407220266586240637350907136870607040913290590611,793400754874236243676721564968016542454513488899050997526586540816446069760957715423992612546686769171106427349384375943641326144133116588670645501231299064478777846694278704641598622565613076600211712243453441442617903127555189233115008530187155578099336294750097716133611190867259168037807083105588642566246|27460683971089209913632788439277008206698726108421557048449583612748157436343375175859322164187154644764726127789104341389062435393682455959407312665088265825287372841830854948020646918675509930411197475014852013755108095396665264198600695220092526372517655520066812589582003333706156211987354238157895214440,-18754257799889030610388359385148211437538401837086321292345976113516028840634213460141894145979065231860481969629551490782467029876512509259774443102990636739699402915097564612184570929798790707857065137355337741260683852677325380877763634549633686621832440525952151518844155190936539038380094790162128388423,292316854113502420768516012912807278549304319263771926401370626456917590670162968070277533769157336622178624301667258725748409713154982300194605653065586096039574795291737865145837966259393195694514901162748686464295686525957546330665390520676177065848461958642958875916650558856747431365214941153816669348325
|
||||
10009505680139870683354483014980979080857116598143181111545123603173294088551257446784978515102956309603131729036042239470868522730508351640411841336927180142285333130556003408088825172687266397290471685595705033772539426652454509785808561354205994913107889793645231496289597484325916247643676615653797810040,-3204245228048542338423395469208468824364162898707311656951717207097770099550386735738728259011638956652924858793824233816950950613612534337274326306432643930039092581092193180132506302083387198832944317276664858711681950020725043153356848379502277900787129851654969895020729278524823784274520152043485072291,452691911613679447746063326513639174263793060004909642518772775706171480163325072807358357220816303993075973139644460675947299910587502105955195991864534504547078402941938298035649970749378328953718405749778603278187778609058449113337901162098857859007739511955733974919843773983479386171581120876366473480535|10009505680139870683354483014980979080857116598143181111545123603173294088551257446784978515102956309603131729036042239470868522730508351640411841336927180142285333130556003408088825172687266397290471685595705033772539426652454509785808561354205994913107889793645231496289597484325916247643676615653797810040,-3204245228048542338423395469208468824364162898707311656951717207097770099550386735738728259011638956652924858793824233816950950613612534337274326306432643930039092581092193180132506302083387198832944317276664858711681950020725043153356848379502277900787129851654969895020729278524823784274520152043485072291,452691911613679447746063326513639174263793060004909642518772775706171480163325072807358357220816303993075973139644460675947299910587502105955195991864534504547078402941938298035649970749378328953718405749778603278187778609058449113337901162098857859007739511955733974919843773983479386171581120876366473480535|57325550832595720002282991260198520855619892385753125887287449562869890287547556782700649421653735594090065432438621527792246214244092693717739414731384442034231735428582082971424584764012096459469280873967739009228670210741931717901688698237272251048307176343047617528247235108742851430347676100126914108357,40951175564652222245195473979961933400303424050552593889813171845223826940735103640121837889061263540857785714549429721536079825338211400035410823730435714524768011703151474601155984454456549759808694516594213778747991012336774365782807914607474811422076337673527879293888167855766653181026300408358374972063,86312387529619002943462127766854108620725875072481894074267557421849877085810739137001331161310595596779531729111999016553742317053715695938778491822422663861385491102185170957066107188324354310777066756950531425606616940837381593339739089909995724195482868610730939023987110641593221757790669575104910938446
|
||||
1000951516029909402241580153254201911805533650981363847468064026947791885513152190496939080952901855372998038682278000380636609527998130327379270561313029246942896140134101369621908911346125374976926115893278132230058065500703131104226075681633220114919188893134454475954292791954736302126634675741318978601,-932129972046203740107893826647984861393190609401184260933369527488206703962436872059299754006964658145411135715285131543309666916261147162906324852866784469362588174806798886084835311322495644384917815753456114043848321591684728503353583125390553182460085266457044328481386164295062361453557198381234996483,7741880922056878066612714130026240867522108473639420974553105203701418374724364127305856418938534523230858044879263234730427059699274843010051016880192588782731180142670836033616687676672699018701220814586539096635490574816118709819174615703862984275251303192202153140463446907523629847791487096446425558516238|1000951516029909402241580153254201911805533650981363847468064026947791885513152190496939080952901855372998038682278000380636609527998130327379270561313029246942896140134101369621908911346125374976926115893278132230058065500703131104226075681633220114919188893134454475954292791954736302126634675741318978601,-932129972046203740107893826647984861393190609401184260933369527488206703962436872059299754006964658145411135715285131543309666916261147162906324852866784469362588174806798886084835311322495644384917815753456114043848321591684728503353583125390553182460085266457044328481386164295062361453557198381234996483,7741880922056878066612714130026240867522108473639420974553105203701418374724364127305856418938534523230858044879263234730427059699274843010051016880192588782731180142670836033616687676672699018701220814586539096635490574816118709819174615703862984275251303192202153140463446907523629847791487096446425558516238|15746368080076547639613112548931198412928034872598867786846558772081390410891968919792236071990423045407820022126215168896502300352310051471939494022340800892491023480415508952796942181491516127339639471207019480870149174572084740672853889392694282271865099892527052018243852819055812247442628083006705785149,-1817913436531155250968687681482056128774282329369952888473920830262042372654938097136436607889208234812116291336524382413655603485552821293038078939629653209114696856829043835764482596948782168253580822692634503701439593841617763234039276530741649509861202111285883608345674200240173376261557395276050534745,492167869580416546150864341469450817106189778801161330939305290046708175512988010176297694665433672849671984872726657705850871343875774836983621356338570200418265577466209423429850230482380970478840847989123705290014954835386530282830688430538273550828822069628430975922343455045834201595340872511606366704728
|
||||
10009614232615212022005150149343932420969657134336251266196874043830583063114875468409344410544755395263952674188421355541706476649104687178621105860662213481607819203924674901060643908339267017280510002551378392012520463262809409257654601850085574494274200629627329653203473234690149811173235149360768384838,836267856629353024976937718074908246524235283001080657657057590803147642759710349203535369107634985057019274642907780561827986871269168282562729482602832882014993174240061797035451659603107102838592209619951864142851506020290496133563766536500833473922797379921857659870104796371847757654270012370698502999,784213921791375719854653276558811892255578032965532623567863494564671611248783758720878204565462346000781224582747048981949572160149632172258392213554094289354008679022701865566865099047150582908470578815534139684037571258726801746576984534581957278215217261339431677162978264928931155436559875241964125506266|91259641317840920388592572245493602418223311736654347455817117920969722081887399519379251381184940824844626111264019221904601665534920622151118371387906395484279959508114917794568416938471005687918332893135141888811509257566326226278046422522746020345472499138217410394253037717517813153026786742476211897426,65560628471815349730768404773504307627679453655870244754876894481952096786914419991524915369113837577161059316635270325176467655387763062001209403412378388608286732350937986269983898741335821089925199082458466627097168531389395465235586971316043725352106687336132311388859476958068300601993983492409770068953,97787509018580500559531280765247530593654008165836933101614934455794219747727474184974783904602569289723706867556213004773348953706945069163461128745310430174496134494281188144065521418637123474052338785100571778752720085930925320282428718659058820028049740359320116709840549247824331580105759766861379891210|75062088452630474843888448210053283462706588708992115575383926339301467347310815006622009334498696501710113137263962332974627478074375539845396462501277814094889463218705190380441269364077952749970929670210201903809188825244244127139203763727765293010747505303529125943832432756718681546490336041697468666190,5541281329506174033291380410034395388042944047800558435987093009948507724655465795692214345462752044394730637949505190953507095375192582819240934021514991426264136507386865262105651669874195906257084096658225527132816732104755767839079135854552727988309212343735183861434005237105894184406202983254934534757,104675750550793205502943520352684154101269712315945996783868759572927470248283594480842218327785617106312969404704918354113342765451442832450177716298160659447475598063377646514258038986139271814855804490712610499304684910754302950004231911223315677097295880861233808821150324765848314271787214250899197923793
|
||||
10009735080309013514440203870605983374104835055250399704317172848646825795572764221124512471397022599041102696110601760496809311877056400885225531243115647095694305859001567326435058426543669680082356076887117616533496794600222886637873441727978976019755009690240085029104982970925792121991104293242809524644,6716504442878527910519807778046246423810093302344836517925018933141102172400301207571530237654753113978791017298256211048865142019514745459130820608857728114059755451415522450033212605102272496818594519931368393561070233092047087381778868100623694505448318327728934167707696920045126563192647607794472189195,721610628334648695598193480418084731432879897882901829331594044580759141755040057210356863808123513214754128306537665937117531576524824114459745892010308401743734165555223754018460218362992047097741240949227118743681363740856040612578898979577195958019157067541288613303223475902295909138865214617457058483843|10009735080309013514440203870605983374104835055250399704317172848646825795572764221124512471397022599041102696110601760496809311877056400885225531243115647095694305859001567326435058426543669680082356076887117616533496794600222886637873441727978976019755009690240085029104982970925792121991104293242809524644,6716504442878527910519807778046246423810093302344836517925018933141102172400301207571530237654753113978791017298256211048865142019514745459130820608857728114059755451415522450033212605102272496818594519931368393561070233092047087381778868100623694505448318327728934167707696920045126563192647607794472189195,721610628334648695598193480418084731432879897882901829331594044580759141755040057210356863808123513214754128306537665937117531576524824114459745892010308401743734165555223754018460218362992047097741240949227118743681363740856040612578898979577195958019157067541288613303223475902295909138865214617457058483843|27431399959730041618757181598450126761864467783308250953166653158864868050165660437728250584906458406104160649372946064796764756251284036703521851065427172085011598154374858106257477054034049690307574700876194576753048475242472071051384544187235302865991596395901667453599382886279428660852987448092730327814,-12178152192814077151051956033210165813331619111090720689608458837738277955478946125067643676733373652534546194632007566276305197498317660468910084573634326652156582085984031315753626693903214933704476608819110626280721237157346811918265527840918335083118991187163668918374733603234110068582400025069332861471,264256662843741154538126874284653325441730644362235064492791411891511464369737085603945845443869261733906715033378896197504349395743395072323232105722154314007209047495860245950090828739984743068229024820070744102308175917924790982043751500738655732108120833669083027766207125418432774798887679934336031211189
|
||||
100097767925729329322181122349613179670027446504792908817095637890752573498574361347439148152051968207056866825997618536117991814714859714673883034645066867063812091504212589938420469209673745687587262010655197327448038749016704401923718318821311108473542621283106029369259039074767836862058509435455755610726,-100049042457569505632055807384899059068938967940837318894350268996535213352709148936435708901083176589583550587767198440304487034715449239754368855557475044885723026390661018171437823688972174609609018769743817618355306963644565862125983532960059011062792908538954329635940471395263688377520252608542030523093,101825233069512741038457795802309532831632092007485080725676678162290037786417230184436300741781748657320031840082727976574819880666874823641143033563613526015930298529985774382970686476257558271965201142223855170907771875249088691707619925926120372987467772228909661019762594761741996613700919454999805975044|100097767925729329322181122349613179670027446504792908817095637890752573498574361347439148152051968207056866825997618536117991814714859714673883034645066867063812091504212589938420469209673745687587262010655197327448038749016704401923718318821311108473542621283106029369259039074767836862058509435455755610726,-100049042457569505632055807384899059068938967940837318894350268996535213352709148936435708901083176589583550587767198440304487034715449239754368855557475044885723026390661018171437823688972174609609018769743817618355306963644565862125983532960059011062792908538954329635940471395263688377520252608542030523093,101825233069512741038457795802309532831632092007485080725676678162290037786417230184436300741781748657320031840082727976574819880666874823641143033563613526015930298529985774382970686476257558271965201142223855170907771875249088691707619925926120372987467772228909661019762594761741996613700919454999805975044|84308318710770953640248175476462028139373764391035194691231680218526343685551415536853656437464155941615590227223191821309564306137129412203074445224501367988293836354108333795252385654176431244360276218862523025987282479232565449230085787098609814824691928891608841637881937218976744434331438048491668714172,78229471895771291032128733343240907956513700512674961776679342047382405281968278678548353708794851883965121941126776164617402656831058062037098035411278996202926380143407188337949264849125051865072631849969234447888440699755954052452126159543200468837557873802507174337535425627611660644229281086936050355075,109360363649395746265656497473367613906192696966623732296103764282264963662145240362278977792876351026988778202744708027814748063715992412060773465595050876884872367497101878287000352814221891140816680001766329736587915177644869655423120132329944663172310205372239088325795595410385678741576083941746461375629
|
||||
1000990088197024747059083499592558231720263720277516776155079181049136503434198702340667607714363713879340855424897665647049377714485771691188931707633550660945052279457196551479047254741496420585602556120439906566870228385196796680534214981451257503126475671546702014976009092407415021171352670275245814728,725466386677782932169006961452587026457506864587404408874444216403861787891316322821563900402539391905854377725716394516795127638578550566829765062852138101610829715414344025748861390095121907615243675775588453320217679236986850051456109259336757301010447881360582473998540771452509411313781955577190588933,5517508390471385461294072894661016222336566054567430728481305159339660984012399389945095200514405410813099792232460346983221900276173777626934161693012967410321899909279792957271372152068664807744591895618427921351514391226515490690862669088614356482368865242803422288159831017511240290921861425877221350767081|1000990088197024747059083499592558231720263720277516776155079181049136503434198702340667607714363713879340855424897665647049377714485771691188931707633550660945052279457196551479047254741496420585602556120439906566870228385196796680534214981451257503126475671546702014976009092407415021171352670275245814728,725466386677782932169006961452587026457506864587404408874444216403861787891316322821563900402539391905854377725716394516795127638578550566829765062852138101610829715414344025748861390095121907615243675775588453320217679236986850051456109259336757301010447881360582473998540771452509411313781955577190588933,5517508390471385461294072894661016222336566054567430728481305159339660984012399389945095200514405410813099792232460346983221900276173777626934161693012967410321899909279792957271372152068664807744591895618427921351514391226515490690862669088614356482368865242803422288159831017511240290921861425877221350767081|46386382398471210654004936862977280764038033260370855702299152174715903684807635787033726061221737095817373565974565953991423132816014499962739297327315390959305555345973541148973281098200177613839273688191655843120140926599099288046020383471244522466342336148402764983519506510433171993666037668400990623062,30909786208868059159308250284546387617592958673051467586322533557805038169619650467442753505158926723729781335720702109207080121759415266351938588413071223894526233303271669156163543157906212613065654926067039001367294657463422342698879421926602847752406836893005886958919719183994605725308548242138957881171,124210879529497457542798731661855988692615123385567383434289407838970666113795793650595394981286850762118704131523110658152541154934468138859842609878663166338576053338898592108554591614195107201143517584467526852469899754023757894264352510613574752993978429183938806214485060920755151052534935466538850750938
|
||||
10010004064090651409010594639848304417245586560948860214310742766846249258119176243618948796060231286565945627267454791543296430719743208401586187196864109595450365240377376347430379493062158659135705093920261708675191488141331016387425285934969492844933812420736541635790559026628543841128935951718908539896,-1498575286639922441240963650822632036400568058110825911189335188996116649771598943688044499782411654295552472829397529434461014441578505662359180553723401992140786537396607735356416120600823531080136067285152784381639454281243980298334520221160338176676576774798710776186339169032737324810281860916038070823,768468744922072210410085870438045813460934852024069843981629956982064663744441536899640311347039303574749086761908444837858696612124820590763553776868490058405671131188766507451909827840059264627966884129949211264617246300058675643121776631374263858887287691658300066890342985411108805960696775940061827501049|10010004064090651409010594639848304417245586560948860214310742766846249258119176243618948796060231286565945627267454791543296430719743208401586187196864109595450365240377376347430379493062158659135705093920261708675191488141331016387425285934969492844933812420736541635790559026628543841128935951718908539896,-1498575286639922441240963650822632036400568058110825911189335188996116649771598943688044499782411654295552472829397529434461014441578505662359180553723401992140786537396607735356416120600823531080136067285152784381639454281243980298334520221160338176676576774798710776186339169032737324810281860916038070823,768468744922072210410085870438045813460934852024069843981629956982064663744441536899640311347039303574749086761908444837858696612124820590763553776868490058405671131188766507451909827840059264627966884129949211264617246300058675643121776631374263858887287691658300066890342985411108805960696775940061827501049|28314042997988233306636589016992476577770908296597830278146083272521268550372497996517202454826620755010065709821222609305573779332296860088326682557505516615132304908709189030516196077907461669993069872444768482204126654812645619744037494119483770734571472757955818228427379193994724836630122637837874512512,-3910830326710790111629753186982470489266159472894461132493344186147852161393575078274643639038642275689976708947162470525418556533103511874282953768387384089989557162835543128542264012421515524615699954054931189762734554550136613958599656445264920707571157499612722532218838749658906057952745224391208374423,271795782638036641105135359411824479015439355083041167763715963674151201738370794758665358014925962658456682314365819593590637317922383444961883165716906142863933218099402568928834160919844733051508148071302780085990761872080854429570287769745420760134784589649743625063761926379339662449726354233483569572692
|
||||
10010469709639397131321593392335940518221591944212653476848636010049901173327189141010003266402662587851391795365145565853592244249890218572600240492819519129624586319882991468883851157495158734614747790710618700576914513912845835699748008363226744953360119054075282875557290214809856164142199477757165509164,7505657900398833324827399204281082596119737445028635348485466721806081208043020690125518041418692182505619967598743043368451311836537618411006688337064144530591029793349206581566058245087905481171249541532084530428115422022022771262499445387394812364092046818720427959757560293344117843608115308687123143421,553113242511887630245562923692119334560619363555162251614925548023827683747558857060226873484593892808999168052131745589052836855443167606888604202950573221560622773360660465500305832700518144444548624823481416168401044677399877530532448619602616847965589554700283201541685397541240490155576228110029131773379|63201743899616470908035016615759783248572310773988939570648682086965508954735585744990615463863202134213890574490859916770336808958389758836363215334497075053557112818568576204445815232807749791417195377923291221271056534552496867547808556556792554364734430966783089440150789750091730879530896624414277659061,-55856955103087382729788364385235549210397677016869607285896429414455503436682728351867754944498329815149524455764192011560832811681933262606199210273482312024649522293283703849873542800068494104680666316436079341962770915103078184937312059708038123793720277348890693601123206211567358221715195838805665244815,99725721230004762208212433032530958477513183167215245049998941633413237167002350956483975841846292547322289722635488222088283425749457741260773683563042470151127137265045721725293085765918300826804733069413639039496778512157339321750973991239393851776816288547058721349853339439566413417882881431596395398482|10058483900212848371336105395105034597443877759659095074874545915088017898536154919284167493951088960283199509655255215299440632845548287448716500241460028925186589031890037337660582657444623147488470508614291087038125788600526809670994940639159256871538287711131658514500837340353796975836990505301624273881,-157799394991431658935500911446539445587307591494655221580870826914115793039596841571933100144135016253304167518063315606333327146563644719359095984750603598277704663545389186967829006269785943764149594510946914419779083189746476236548753466257639182993421200334901817261951648692278188884421732061466347929,549073390680838282030926276806663190640362547475399531148862958328951733805907419890212210186161292258493318221366553074237370828617692229205217240695895636477792753409007387702564155250318872755670718485591591748806803837858464359711143468897253705933551825195496604931204015549587680036788025676123194339726
|
||||
10010496751485016737255498721953568674323163915462879922384146496780957659766649785727318078913117215770623612059774196084160730194502430474210832948012098222392905483059314666266093994762308130821733627116456649448335020123456572070799012785074345756980230844151670979497392292798505519219012749959532875338,799688122820510610823764584829566759424107985411345815493636913295490164723810636027858758547620320075665083037412723404618585417481351642215686069179403481765070501469154817238059870792625025657772680475594951623612932084444307492923899340395814785386177783715246947669812896758158101579611206283404125383,756465676775987727565397432418408198121332665761199779426305954315978948084770158074763521327096161584122642931162604561074895576932338265005852611804594502809713943064130145585384616864112057298562543101439879468994210857521510834193578678095039312141817959445372442666042645305218271194929494814070515333525|10010496751485016737255498721953568674323163915462879922384146496780957659766649785727318078913117215770623612059774196084160730194502430474210832948012098222392905483059314666266093994762308130821733627116456649448335020123456572070799012785074345756980230844151670979497392292798505519219012749959532875338,799688122820510610823764584829566759424107985411345815493636913295490164723810636027858758547620320075665083037412723404618585417481351642215686069179403481765070501469154817238059870792625025657772680475594951623612932084444307492923899340395814785386177783715246947669812896758158101579611206283404125383,756465676775987727565397432418408198121332665761199779426305954315978948084770158074763521327096161584122642931162604561074895576932338265005852611804594502809713943064130145585384616864112057298562543101439879468994210857521510834193578678095039312141817959445372442666042645305218271194929494814070515333525|88526457805417802579401128655636200680578875592064917653502726799402631022732331707242469404309708934422669188417199074013672835521067841289769648786519913947468121765630841991231363845393790849492596901524640146832343923907202043034825750225542103503647484110551329413090031876302117118017242617457435270440,-55270872554503717308092985383981103433537850547649491053003970562528650386510337748001788465211336165026556518877922750831164872435215600571701093825986357449663403092607944719717658773706993903771608486872517959780200593880280040497747294339054563275578214457748886755324708980839180036767067720944832209613,94165686390158171873356770999242344439144784888928297429784348143756989501060133555039087406934644294830253094462126060631940792293289142829036758298101067851753964448066092115935075783351846337421975097419550731994478824011482838934049698582968608287926659413694080435137971696387627102349753238458722293238
|
||||
10010579112627452164700751672418124874438960016155391309411143579238371993812216949415371161492459719515415809121706298625750585115724165801767312632070537335293199529430577590690991572481217905708780746070115008642386973910356482808275744430781549387996153714070117005169542728240082244119738613459581149403,2350957735421970008675187616979703886327431020247822920032684793437439591770682963150195069182216167082120247951141628182676139493494439884424368912802413855370850694844333281369444099710260137140856858089878674493931790511953123605380418199403899915269505474711266010465371671818915910810005642457030207323,611423654589890839284741885001129722618409625326976389817674733477626186444470464645132913394627656053210319902647997769502456733804852681598112059600692683589494771437615834703370743285630660946188840487388799145726650756609808617614030574039934664771328233896579676781994740365464050319193605788676121096976|10010579112627452164700751672418124874438960016155391309411143579238371993812216949415371161492459719515415809121706298625750585115724165801767312632070537335293199529430577590690991572481217905708780746070115008642386973910356482808275744430781549387996153714070117005169542728240082244119738613459581149403,2350957735421970008675187616979703886327431020247822920032684793437439591770682963150195069182216167082120247951141628182676139493494439884424368912802413855370850694844333281369444099710260137140856858089878674493931790511953123605380418199403899915269505474711266010465371671818915910810005642457030207323,611423654589890839284741885001129722618409625326976389817674733477626186444470464645132913394627656053210319902647997769502456733804852681598112059600692683589494771437615834703370743285630660946188840487388799145726650756609808617614030574039934664771328233896579676781994740365464050319193605788676121096976|8039922802491265414309990967793279613501148402448480465019122506003939256870540144853780285033203931808455458595860030453208550342558408097242925918803433428637982781245121194507511100106884732787332881816376538778408183713312626895063525916116529477067428617194552870724443468826009500481151973572267660629,7782542056885878734681190877592906346631460224605439140627247356888850052165135682978538906914658013311431434956582299659243906965976772069489496351182726287233109256230929112390639759813836413367620416284403736856845659506160807594525033721234682734219240024280033734701579761670420320393555156688458386939,763000498381829086301710784279931419423976764939217073711509076091719761279556145759370750276614372372724227557071534934449510558501017918011817000937860419860520748646784487080323157808376840620794576624474012291138723116851111311356377966880000941424814810860193927148425226557672422373368027666445875216544
|
||||
10011186832308679529580531778689417394449477080570215256255872899524060756354513251052234139190381882237674326102549194541918465150411281044342531791718191209528218579215954684479017629118919205540336463087633388203942961094184672710469514635568862008937176486425382826532999400454876885123467677882356280867,-9760739041412831860016040329300538464595968662597654195818825742388623357499061055114241473465244979572894681398742727120008689894660036669893911021076723092236596538937507422477033501397620347314916527511417876669224922540378674704881346598392965888769411037021701309263621236037226524490335501235413158317,618797456627391285757491837806082074086781183030320963821992656495001963414332567515207750538267219197978733813073360730643354769504354220428586481088489050423524166052003546758616279336334294024003134192912678054276268653141558092399335706944717740861723542047714673114465932057975066598256237991004833528194|10011186832308679529580531778689417394449477080570215256255872899524060756354513251052234139190381882237674326102549194541918465150411281044342531791718191209528218579215954684479017629118919205540336463087633388203942961094184672710469514635568862008937176486425382826532999400454876885123467677882356280867,-9760739041412831860016040329300538464595968662597654195818825742388623357499061055114241473465244979572894681398742727120008689894660036669893911021076723092236596538937507422477033501397620347314916527511417876669224922540378674704881346598392965888769411037021701309263621236037226524490335501235413158317,618797456627391285757491837806082074086781183030320963821992656495001963414332567515207750538267219197978733813073360730643354769504354220428586481088489050423524166052003546758616279336334294024003134192912678054276268653141558092399335706944717740861723542047714673114465932057975066598256237991004833528194|16023810805641333724336357094511552886496985977223317205804900540875359074549841799895438359675279197334185032768159914670757201278192258514539721858337894442748764924011517017369466984819970583389409069776399176053947560735257602992978470081403520015409641979689232868403667818818613535419071872687266278871,-7532673756475565262302348084703438182578166716950696747316478761861175843795966574151023129542515752521204794815061142348575304950316771972303577053107419061405627955596801577300288807854600908796497666677601605740930719732644371749303298593761133443055158847238113190613766743442416892398264321417028494683,386004572289283022539377207289773679498488550299986782511093221618938108821853499898482934516175608928422720022347987369229961237741779367136076661442684969604660313702194515039707016073494920297591526290529740277402244949703587380758181579357976708139982649833967127198595634906215849970601175752843362414638
|
||||
10011352260197967961196723001882777157351136553686255118590538903088960848511094106778638364952379274889738636611531352467905470187088001978395724543759615578178012440339389212117360666565610883522821465968556183822388268042856072812425704980952391373927012924156734141733616109526841203308615171993851798580,-7221676671346271775547094631755878098073875121922187404285664906337078018452572717764275630077273635227060270555255283560769931807823554231983067592327106941484374528295871153247243771907559825959222732921231505238074239141672724791953035282099263068621712554135551648164407808630494744659356436708196075003,491103641942430897255353076452858177434280940975186423223949785500010643311551520732003340225232164561507795653594281473147298622615199173589020255105363616020518202959139902358320338695214760426102498591057589117988289772846024859991303086757574971564242450863802854515962057480781826855732055129393601722620|10011352260197967961196723001882777157351136553686255118590538903088960848511094106778638364952379274889738636611531352467905470187088001978395724543759615578178012440339389212117360666565610883522821465968556183822388268042856072812425704980952391373927012924156734141733616109526841203308615171993851798580,-7221676671346271775547094631755878098073875121922187404285664906337078018452572717764275630077273635227060270555255283560769931807823554231983067592327106941484374528295871153247243771907559825959222732921231505238074239141672724791953035282099263068621712554135551648164407808630494744659356436708196075003,491103641942430897255353076452858177434280940975186423223949785500010643311551520732003340225232164561507795653594281473147298622615199173589020255105363616020518202959139902358320338695214760426102498591057589117988289772846024859991303086757574971564242450863802854515962057480781826855732055129393601722620|47792242549528045573835222090102709180753366247917233792162207697772127315858077638348932444421521322861739464396186442116808539325522348191328660258855448870212049194866543072912231226457359914737534217070905308248553545640574239424386722275092722710319161088562287826715987711727881278079923845948791676890,8254269885969125051120540706292376386106399376632912551223385556280906209369492834220174830708813086153383708455555132979546664334186800724505969898808175578003259356450761612161617233904190263463404177018953974392386560633539661122851396041321655235390273818809845177966554527106703090511634271703426366333,102958270685953367083211535309354861429334576908033521565612066728144639011805671376037609804664223083707360606267980895711740633481159521495849279040716328723662579233841335201356070651023351445332747117601073346257424542725915546556026838056238556081287286460939074972020327613774707117438966240554700925838
|
||||
10011859648773232442448733215609838143695842496672408041181163963731715385957428830906426802116840506850796500226397482148532808790741216756533590408501689411024510944680051255986998627975919616236379312627952364824369227089618523233361113970064976301643797723660966748317498805671195280559795030489377669812,1389268097793948084201915587623858469968349389719030883277892933626050552994624565080658001697742466760286196070343106937791393185285082388402785127475337008454634105961822228566730985518119778298380464943436464040236734762976514693785454254940058632017513195975469702286256915116671279121716893380760195997,798259439380551890168577021365722645610234093426080631569938818141778075039283575889046619146360005141391892307832892070793699590106322160142086889812498495186005607708401945977916695847229243650515563078729723204186390753029064543583093290363210178756937751032079469629502953157831010865389293997646642560816|10011859648773232442448733215609838143695842496672408041181163963731715385957428830906426802116840506850796500226397482148532808790741216756533590408501689411024510944680051255986998627975919616236379312627952364824369227089618523233361113970064976301643797723660966748317498805671195280559795030489377669812,1389268097793948084201915587623858469968349389719030883277892933626050552994624565080658001697742466760286196070343106937791393185285082388402785127475337008454634105961822228566730985518119778298380464943436464040236734762976514693785454254940058632017513195975469702286256915116671279121716893380760195997,798259439380551890168577021365722645610234093426080631569938818141778075039283575889046619146360005141391892307832892070793699590106322160142086889812498495186005607708401945977916695847229243650515563078729723204186390753029064543583093290363210178756937751032079469629502953157831010865389293997646642560816|42206894030530619844844137895190664968269730414499521872109243265156383878372533066719066634351278056931106119952256575854241753055519807843572490047146976978089248439736200704784039417511594978273239033477711961360762067155137236184651290217781497985287933853456015958183471535758824703982061917287661765041,40970642478148233733033585114396071242748464687693709425944631778683899124773146938566992970029345645063087493796799166205427214444613129772321140093187953348169602638764727669726146858903079780374349625954437240902856681427277267635228715453381995681831199770224812459964590952867744306421769761996026104513,199285626990423651406783664663645910990492228214328517061400776387771491511391310851645339521126305819574623301901411324234792418046438608476979083398394165188934652648732128312553721596148859379616564443828216278968549632096439205379175627317399435861673444161870109940456991316291287290279435962880377080302
|
||||
10011942112859072995258791154733863477789940396938883213028206575320538554823437297402241742896497695874369416027516907850508925314968512498072222974096801648178807861791486753853486254133021354211722209138812867027895370716192265840613761606054294753819681190630045043947858812851889188252918713433862450937,-5571668968866828804921046721301654575883923332633233994134906673281267773210784380932788963105885600448276206900049033963090555880641132208787100277713410661373854250945949489885604664165828601242508315193830303811886340805084372525080806602568264342555171074951419758002241352180046540480238252242954050299,447717522759824444351173111605711384841786993787566688069178368722388364402515540644758414533643421974927299526439953604872416797996604293432960735663438930460329264500528581210531189312463600150764233828882749159851806734992346380036786298515789780808132282396713107095426662454069422796780131140784450873310|10011942112859072995258791154733863477789940396938883213028206575320538554823437297402241742896497695874369416027516907850508925314968512498072222974096801648178807861791486753853486254133021354211722209138812867027895370716192265840613761606054294753819681190630045043947858812851889188252918713433862450937,-5571668968866828804921046721301654575883923332633233994134906673281267773210784380932788963105885600448276206900049033963090555880641132208787100277713410661373854250945949489885604664165828601242508315193830303811886340805084372525080806602568264342555171074951419758002241352180046540480238252242954050299,447717522759824444351173111605711384841786993787566688069178368722388364402515540644758414533643421974927299526439953604872416797996604293432960735663438930460329264500528581210531189312463600150764233828882749159851806734992346380036786298515789780808132282396713107095426662454069422796780131140784450873310|27084975518223203685159476564968667757147005650320881882446538924664746760650597697153771281773275150298344920435750377585362202361041033907635631944580948271756519774659017735803323446011519248098440794538345241902148398434473456015090213973679829939390143526742895252747749904765235510343943624603085395760,-12790519385524034711380512698893130061457017090294213212099271214034680483663421242204264773620969593678221374876014811278470247764306480672296083402927981473695204988274213121345880281894543363725179804965957322222445321774678314607579703404237389600553993220560492758375020231080071561518133534954466259951,166721966963161057002408800656254458745347212698279982813080522419206471402712564010508086006697422863841361930966373632778322663543126671570353059325275245779405843551444614505569300692917404907917428765459530333591345110277642064762234238705296425159456946404870175457906061825086330206230526422507612458697
|
||||
10011955414042796957539613462833567748978021174979466353940011258968857683495843510716962870026112990120612239420094468274757074371715099897797764809018818677244411173050607051965491060861928470702220861911485527125770697960299381766502895029523905888655809759985815187019718331529320273577105879315557816044,-2903598288233181369386909069725761325455718972241715705067575929894098338713960225913955377920698582104810776546675110854231130224088963639880575858411672466883767586627134811452446768341259728766799505769981364639560814489840847334997666650046443822662727211952763808116443820225341403833059567092278686013,716711840847237503666263684416016435149389642949031161572660687058464860752744538837256522716160171257335781518708196625364621151126528577774399883526209845714231475374012476325785739496418344991482641972669482173664514234171584896006659617692101904655946713038460582513645370686741753929246439907983936752037|10011955414042796957539613462833567748978021174979466353940011258968857683495843510716962870026112990120612239420094468274757074371715099897797764809018818677244411173050607051965491060861928470702220861911485527125770697960299381766502895029523905888655809759985815187019718331529320273577105879315557816044,-2903598288233181369386909069725761325455718972241715705067575929894098338713960225913955377920698582104810776546675110854231130224088963639880575858411672466883767586627134811452446768341259728766799505769981364639560814489840847334997666650046443822662727211952763808116443820225341403833059567092278686013,716711840847237503666263684416016435149389642949031161572660687058464860752744538837256522716160171257335781518708196625364621151126528577774399883526209845714231475374012476325785739496418344991482641972669482173664514234171584896006659617692101904655946713038460582513645370686741753929246439907983936752037|83377818300427508414411209474182765418541299931790991979162498055814470115047955070666996621536705209820738216257135146862349180486198221400982101436215575798938096836021071281557720129695222554778979084677391347787960453403954349664348198928269790759939576077051077722913333980873848885097124565249932890109,-30688215255611971606034471669429848439589330363616017559694024730487742561639314516549592500671986661135255749032859202031979689977991786343363266117721953715761747898795102634113940122259396542403236218273245556434610755838474462460273735366438965428724794482250645649141152999575795556913839603294733616297,88860815315671630897460232604076507207530961201107386907073059232104245557771716637121266612833291311086440284416177092484049670682110328081485080434205469417936503447466464463362446293805166057694349242947508206617775986775538756539497474332372390720218420029346868304694279430904189373022716924576015411382
|
||||
10012228673376152026567450992902390970336864997567041834794435762949115261281228493411090141625349816927161690458296667158108080969724709444972658280448694411038715631967371509920701285876643071095813601274276803568595952200658716678278724478871970783503276566469041579910541903097002012017970816393023705126,-1525621196152714906745704861653134857598506051934926836340086172347518826544771422485438019089512861580045344082067612865732790885320087313117232977161635917848068594652072218066650842997301426696286712170439049522381084448274527064469835335059461198790200539335886996343589558210546809155519571241608841115,566490489998797306378193876913958339109032806676495000099448643263727848667893470101258216128095777975779077696408017781065855401798377205019264716443061687881268372472869438487229092017706767156974596159933038800310353717032995999433855144018018195220506116678554717313645342356609548972497509792111447080303|10012228673376152026567450992902390970336864997567041834794435762949115261281228493411090141625349816927161690458296667158108080969724709444972658280448694411038715631967371509920701285876643071095813601274276803568595952200658716678278724478871970783503276566469041579910541903097002012017970816393023705126,-1525621196152714906745704861653134857598506051934926836340086172347518826544771422485438019089512861580045344082067612865732790885320087313117232977161635917848068594652072218066650842997301426696286712170439049522381084448274527064469835335059461198790200539335886996343589558210546809155519571241608841115,566490489998797306378193876913958339109032806676495000099448643263727848667893470101258216128095777975779077696408017781065855401798377205019264716443061687881268372472869438487229092017706767156974596159933038800310353717032995999433855144018018195220506116678554717313645342356609548972497509792111447080303|43590031232680232081751882157307176889837208488946678228473969287186808910765585247541543237267000539198165783309913805801898560564494504170518670105700488271939383325260531063287350050801106407955825720824399992214830540252117419097263989404727460007269455161541372200543947623309137659512638261713267690824,-14075226919726761245118463757100097494169008867441262054574698130139530299753414803053777844415814847468435199262862690860015506966052100586678181635131495519430715844772863497248903106204345001653326109572317033217334530762155783910231739525445183612742122146838723561339801552140211476495875670393868085081,131240521940112916676543723913094551994900810880147949771730918304609983182487804507629012504949522364314455047343021279573082629269863237002108329413796491307563278912051552679953053070493799302202693873331428377723854674840449409246578209307981263784655485960382622975619701504230119584672038533695429676088
|
||||
1001288292714450803721216442216625955625371798611921786124245018047248562264647981975960215285171753909781321204807230585425114478278803844011930274438946371170816602064333453376960652483578633927890649034364140705267107257789492504807548712851379509812488664968862197781823935761608178854275129769647589581,118977223991225808492576983063622698908224268079465629025347336989392083161221074952362214752172730464574518166801398443928377167452950936101606770394549907364810511870992758058622270316795961219734709916323416843582267371642230512848102350867740488489154654911017481701711273952134350507762249130961129603,4253782247854217005640367062054391551273020323289717198551116404593406680781947315659948108589518702797872582317228254446273819182123102223859859093093126618316964313793208051942159218633324159151062222504543999694994085787779078206117679218461273671966899590739444942724001001618068559652898782396232628519674|1001288292714450803721216442216625955625371798611921786124245018047248562264647981975960215285171753909781321204807230585425114478278803844011930274438946371170816602064333453376960652483578633927890649034364140705267107257789492504807548712851379509812488664968862197781823935761608178854275129769647589581,118977223991225808492576983063622698908224268079465629025347336989392083161221074952362214752172730464574518166801398443928377167452950936101606770394549907364810511870992758058622270316795961219734709916323416843582267371642230512848102350867740488489154654911017481701711273952134350507762249130961129603,4253782247854217005640367062054391551273020323289717198551116404593406680781947315659948108589518702797872582317228254446273819182123102223859859093093126618316964313793208051942159218633324159151062222504543999694994085787779078206117679218461273671966899590739444942724001001618068559652898782396232628519674|28938807607695569686193558386017186559599585089880944105080644798657187851944851177349121001670507484268388813019981112914318210410185959709469975835597908447130200721022330232315439534240435891776843814205222365393996713243986623555128903274366840091822641672516816965782305494688964249039137567600077936606,24347068586442893587653361936682544233359974224524919385561963293036974216353969467745312829316424149479715944098504674533950906586338239024243122404600846692591968993298391467756407074710363297328032595080001517924404972784909440292445668484007116372818768610926770836254572445727057593300358575616247842763,152302535148483948223815371530668367432578267200771233287129083802472440010529096619024512937585549897229409792244544585546299937914900082139679373959823145377421946865824314455823557999559223736926801877211472988708620154393053288483777738533792797643686229459318486035573754517579909390578108894692032268889
|
||||
10012892006475941528884203206760641995368133321794055404979199342382084602756352644705532078779012887564604213637869579074484075768567055417796954674356138026767547529561933792018043105730958440781327057508393480700527196787164950646236383499370902496883935791129999602941562207002549251300455418372635519273,1454009605238489140114391427335527519147008275556174452371701295849315335234637169205945347453687617440824028465168238395128115858746597274081455839498538752590048744221995446875637484166488769782049750872805524958169087781809205120801537577068712904423342748390795604976651954642488089689583155223913397665,647808943230731060739626381975524675037163647891128462337945233305926315404323308376753006196333731632781667393569616294591379982170007646969372304454389485880137478967587874806562743050788204733473153064889810620961745850926397404102543921057382519028198560438333275110757811110797391594327323261044640054976|10012892006475941528884203206760641995368133321794055404979199342382084602756352644705532078779012887564604213637869579074484075768567055417796954674356138026767547529561933792018043105730958440781327057508393480700527196787164950646236383499370902496883935791129999602941562207002549251300455418372635519273,1454009605238489140114391427335527519147008275556174452371701295849315335234637169205945347453687617440824028465168238395128115858746597274081455839498538752590048744221995446875637484166488769782049750872805524958169087781809205120801537577068712904423342748390795604976651954642488089689583155223913397665,647808943230731060739626381975524675037163647891128462337945233305926315404323308376753006196333731632781667393569616294591379982170007646969372304454389485880137478967587874806562743050788204733473153064889810620961745850926397404102543921057382519028198560438333275110757811110797391594327323261044640054976|62940556237396653206223780718542562667295386352158429493270469961690767724114029222148067827069562399174914339449248246366326268552997433890745884344199015208364859348865726612586847277646257664344896903583225600388420348724002194132332892190932637136851080726053181726410409254132012307744554948406613929323,-48701511676436282890206508014619418354003032902027055232648782348677470406094053907961181547187251236573045647699655583258566497581891423764342023041779904338115306722370857935574573523817812044494597510209680776289279513137149479122384803569185846747971729826779306714510975413862168549755168167117700353327,112469164343071489234368373987004423456191302343816707379444012274611228263948855290569720261858996544051020707105809245289927202553907369725233852283792575569835413308417689095793467463934173594106404637573580430116767215310604286894257928685108943559541701617509990028119392117707508006024253191362515564488
|
||||
10012909351086759965456044227627057711408098785482672328633074337493434448564318338609803059310568728348413958910299881715937715018572879175542723270961874435550327968633029584188957768139340259030454592302362749027465867807734115139476094923287105973980458884201581736181829195017361330152871853820144480008,4004735351364710265644908449319598352103612215188460925760295665563484237162745827742855116753659687319941982652183152982522805963387540988424745778802028813186258777373064074552858455437921359277118582292259532327491507456668283228943221341315392967683928177537547570473748486481294902027111753951887811107,625070500924631773027293646808528931297961990338169633089637061010766445639876245993583660254312851352153995204943188734825803541904480394551165674837469282411059121521375161737576421883549419892239480294917943542161102975888315623576549465990742662361177906359742645436834392762941048730926726541953775339985|10012909351086759965456044227627057711408098785482672328633074337493434448564318338609803059310568728348413958910299881715937715018572879175542723270961874435550327968633029584188957768139340259030454592302362749027465867807734115139476094923287105973980458884201581736181829195017361330152871853820144480008,4004735351364710265644908449319598352103612215188460925760295665563484237162745827742855116753659687319941982652183152982522805963387540988424745778802028813186258777373064074552858455437921359277118582292259532327491507456668283228943221341315392967683928177537547570473748486481294902027111753951887811107,625070500924631773027293646808528931297961990338169633089637061010766445639876245993583660254312851352153995204943188734825803541904480394551165674837469282411059121521375161737576421883549419892239480294917943542161102975888315623576549465990742662361177906359742645436834392762941048730926726541953775339985|50884288706475165946257509654999208555658693396648687044835752784386552584102384977309647778026166442592405819250800637374065583324042092667913200394806282864115429746583280943890188029227669788614986056318825797041482189685920834253378958370006347565609320222176974991924753600658153514244660657255122224708,38124750578737274821917753227232162791003089617481557231259566762030985520934492451354616032457170217275564281951330766101660738724598191687885679545346283525262542724874642642872748420737930473130307644519437933305026842012536784886496944579276550709211116316390318564020889816097235068462785319614865578597,130062522389522343683740057432381314776477134408262105090740417520527750971142246152091337403925616258740469387086918783120971977871460574454924803144389152275224257452330149332865693355986252454785361887191345579925263888502541640915087986171712168495464223258466766753612088491549102305993177855419426172515
|
||||
10012949731508230844521554364973074187572984168621445800774150709798807735949381704091845966274845524513566631062798752350499554699759712145607818652191568463373664709797900265336143905874117568859521742454341137224521191983729963831041097053387797083787709902762145306866562987693831491238763225325353128845,-7151999616242866495807184767334673387014110620932054515899434747323053830494035687486485101495361247552977403879925385683437335608704813457204456533123612810231681288244199329093278043176840326889166441056953674708680650112341950599518566211501622893081961748190383051196092405691509055911825933224776999729,728959856841002416924230811929428724002543698647639902715200337469187398607311841753203087774058534727465005007422722827247541795373827101651083024979629054119806748202357685733330535940416577507509240075110229140018035405816024445205831928017961602089222683008780078758377712656395593651285944681456109357272|78605684766061357400507779695495682929810684632437884872357120089392494231881706222602069457907886449103098011256954019318391632581377073457287658351584831830230683661446071913790640516272177525020187886119102997352695696049059080937602038841787771510139456284931095360062636771451048097974369276252684666749,12001075534855282519055781006726767731199194746822836204491410167536180166431388377323739159072959927587441133024108242424202303987846968293631866746295774320809136575432861690259530718674237632206265488487198601880322884976030897140623633254152458705315742157972429278484090634288310049511931491105240527901,93151749819352486101012886560489221249552002889236789406862251708880381277922290057447780576080950571200028266859881169907512608303652032886801146810143008245384785580165444902988038417617761865310968792125862316413739796643982228185896004498606219961899388723793207292461251691711779811000343374670531988570|95620961524949716684140097524982794699249535271050516669544121744125934159117898820120095869213277316814159636331359612088008309956314498753337898007810553303289522178449103493384329227781778413500531168007453332099452587335790687068580171335323542117871903087433014777736086345342400718427907876478857651725,93982690612240904950679627999951286744516720026289165825378439518867065181987722717690665329424786689958612327347934970490613914683496125042910877240489318265091859294188434182919729530207613831730142844292090902152344156800509267822168626995816691703927249712872762026654985358484494213663737589506902782009,99292425117587212531473852181491241954331600716435740239461638370783102438068248269577051049726048567729703659744591520045688390816935889052570162756642088994924462717034854539966002991020871080627249804440896263676225604896518999268622239261793212314602300584784534836058487675621509713476733501463323785340
|
||||
10013285697697981291514875192049827757071760177573323421009966878146856227693938310986650067592898605619488251263628358029535725840627847357496217367653253065239804661689467675594407401100934372130923704422822224913415836705341468552018728686468194407664564227575182128302559705354560745061529474614082985076,6561642167054255252332139226189226301150630422474494620863616714017817447379372804603010573956570809208555270847201719676149529315047658055027624866235618098171962008631941847341271231615706090718182990766223922159167490454724094386151343698580819149354278973243680974477529170554988807127882542455236037061,528470097447394031501467541165507900676972213983504375431777006857690508074506764381712795328953309294516807977445847891975262681647237636757123951794958241571326610288116591734368211279530252114133992576937361883752806300690109922381969083425358175983601420535008716582685323406262131690670391327047692590496|10013285697697981291514875192049827757071760177573323421009966878146856227693938310986650067592898605619488251263628358029535725840627847357496217367653253065239804661689467675594407401100934372130923704422822224913415836705341468552018728686468194407664564227575182128302559705354560745061529474614082985076,6561642167054255252332139226189226301150630422474494620863616714017817447379372804603010573956570809208555270847201719676149529315047658055027624866235618098171962008631941847341271231615706090718182990766223922159167490454724094386151343698580819149354278973243680974477529170554988807127882542455236037061,528470097447394031501467541165507900676972213983504375431777006857690508074506764381712795328953309294516807977445847891975262681647237636757123951794958241571326610288116591734368211279530252114133992576937361883752806300690109922381969083425358175983601420535008716582685323406262131690670391327047692590496|34436981724331071994857876336695803178232447897168183469251879445354282383737983320261577504714614276116113259188008664067129808039959751651485877586471601565784430914037035998508212337945584341667506911125463475285113792006322617814372685212577273915390962094210529917778766692621996665878783549527139893242,32421657027122874777191628085590775058881834171831914535958291812982208823927027425208685420460283486647223529499620732980942837410329269106357656112224843439688604221190662744374320594231296457180058248568608247918397639378809724702503728912863511608290047988244839274296444657984762607288102260430546556327,160982437047557923662754621724904101004108273738876884592163845288132647289990060919034667221490978793506721749816537966400403944327808168366534024580437483775879522831741601830069730429889808208871000895202628107312664119771131677027106136972021612902580949354880064038858290748071858588504931122717671875719
|
||||
10013409568078797146570807857755720961248912529367151061974511181033586582464029378963193763825696350496154303179345126636835517120186897096948192379786846194127995559270109497428813513500508574813803534331316886434340387606885978254975074973425350503976585044856706375756665039166645930515210729176181994797,6863076338634175024934436723026392698236823689304369693969685928390616820215350991816780229964708018996782742906430454861638727991380590099557403163016242141034822837520016392592164770889783961757225608245037212056737255646000577024303400659319142788815209178052443133447533618473993771130005829940742472843,518144219445747450843112374880923475954988909716176430338161904285754222207619744119028881545602958596524518340559183715691125114950676034953086100367357569860971147170398898521979791627387469550508096062409978585338647803044577182942437027156401628087522267601972713267759073787404132654921721043098478369296|10013409568078797146570807857755720961248912529367151061974511181033586582464029378963193763825696350496154303179345126636835517120186897096948192379786846194127995559270109497428813513500508574813803534331316886434340387606885978254975074973425350503976585044856706375756665039166645930515210729176181994797,6863076338634175024934436723026392698236823689304369693969685928390616820215350991816780229964708018996782742906430454861638727991380590099557403163016242141034822837520016392592164770889783961757225608245037212056737255646000577024303400659319142788815209178052443133447533618473993771130005829940742472843,518144219445747450843112374880923475954988909716176430338161904285754222207619744119028881545602958596524518340559183715691125114950676034953086100367357569860971147170398898521979791627387469550508096062409978585338647803044577182942437027156401628087522267601972713267759073787404132654921721043098478369296|29934292569471815703363755226997845073545738667501237803957680847283080542129475423696483417806010171923751057450372494361758724728289501602492090448848706266885172109480272010048281849170055027096272553904872380723830007840644079815126735090510221286243662888112310922242506575820245103502418648518037684112,-21627427564859692871607980544502391995135725746472152647532172629071699503752589147589008201502208786678594136605740253912219755939688067145589663222363251747851181456245722891111913772396992196602024806546104102083185098682262204868868794139167512528524369543939531083241005579818092881356982615423576691605,176839029147532789455522785442738478049409371224700882039503756023790320876676330359714505430586793397649436855899139335082011213013721973064579158662211626800445041202290699798718862085318933995294002499387627536860514923891246937832235709964008507131234282169012371627871115559920941075179401745449676837538
|
||||
10013439159433989368964725373563382887574891949489700677050044742848904863973460805304293375442411192907083507310299969395983146408589524560833202656559624127327840001867965274370013167539210363322627273718141213894086509619780941576547772641539573210833142422223317097724915074066448586076045470572140906640,8310509330265721057433243761087295977033094222529694041792873186617167079529403730551603568975196878825930300295178836012162497002423788954615523897720318575793014458944774857654309162161287534450951840479782552544416928129945375223479302487034431413802055998746646446418560576461091628250104710978988283711,729371463016273963110544177662324936807730201765611306002068268068668637824971025044896789932884019488152669624502699796991126775679816762002628560217169359562928488795097209366461843162752726085374841269043547767926070040941464791696126630730708190840765048657149163857767697743125679328771823496672841634424|53070231924347082568804835060631378289496498123832644772276016787246416299549861270518581840230464146779761127524498364504195386387182521904349896158340177993161553682765729098600652803891496382298875979768509788803608935382898072295003870146958848103249920622300892108001270267505518700281027764636096833740,-10417045904363157434661773205739749791733323923523249180794936274249482583161962687848890485454386657190132561052636607343240275768181642068289523597327390757351630390400726183726689859598985450769013120294233573698641240921187000189001584616004996169093549349734180954432033587699679729849675222478884233311,137805678896928752296520072917407826444192224958002583188528402832110905130383122933446618731410797305667977506853537200263986333845054038041545138300862253525372279908216585177453144947870717454801757363277754721032068341587435554423804921498405475740879440309992782986462772299747827377706986933475774033684|56482649708459145913698445611252485312060512622120077359133908474066254680736347932747096146010188731146496181655662751016088725094095969432429720148408144169456178462601187248728823790080612841522193324466093276526908124707660336237710411213793152471895601301243018110500181075901054216803639852864737028850,49500528206529841911957152384541310290857923328806104231198472543790151686945922117895513040239668591093558926952515368216015961042415506812499837082111798870583213244606704215667322437109994138978691823955863634369767001231824513186587618556524171225612093890634215231765102523588484540352521700864775908391,139845177982276960575270039101197150993163035851524438788484301872591911839811648314287998492505051870128263318114638169162126726205946284015475459749582002542133038527256092765477445685371965587948783428628744556595668607565825917211361759008178572918967281201176709071648799305995083323084664578756735938622
|
||||
100137176306265990029733961444031383061223366889811053704411233166327830634077756142922727010656909223245031237249254709133350667800868491437148280477941194204587700926281351055456250199609042270725753605165960788792303060065875576152280599302149022622498012279559937562935558359151996671916418735428920407874,97779166460841276445850871197751897473918068054418745266060401791237288238653436085640513289818870139139618919771865928628062692360137571273452019987828179736062700190532592747648476510214800565987627353502647292543809222510700867942163153624606570877663088964161374448935565221244874684751958995844140920147,102256681515788126438883260779614224655986266663397201843001234522477597459794964756711032437403434184534404583233460968937962164574558546102488980641209149336930446800149993628815025349402768080588150480797996340762754608056907877670259116917971852689279794852877026737551375891068290636218096081379871615065|100137176306265990029733961444031383061223366889811053704411233166327830634077756142922727010656909223245031237249254709133350667800868491437148280477941194204587700926281351055456250199609042270725753605165960788792303060065875576152280599302149022622498012279559937562935558359151996671916418735428920407874,97779166460841276445850871197751897473918068054418745266060401791237288238653436085640513289818870139139618919771865928628062692360137571273452019987828179736062700190532592747648476510214800565987627353502647292543809222510700867942163153624606570877663088964161374448935565221244874684751958995844140920147,102256681515788126438883260779614224655986266663397201843001234522477597459794964756711032437403434184534404583233460968937962164574558546102488980641209149336930446800149993628815025349402768080588150480797996340762754608056907877670259116917971852689279794852877026737551375891068290636218096081379871615065|90230316563580194408667213300439360765549943827123723976699582813489678898952655680387614045807099591452452020884059027873359796950334151880947386773848115789736943898016681027189561282963394481712553688761042044178529870890932063063291912576811880180339151930033798900788177324802354824840693823677567948727,-51250096968515553727207440971544562384114008768089106206247467547899665759345213630706768471270630937078525436219387041016063211534659780348494492859921683763678230787094584046438254568966852960609578580031708027705688875405694260795850267621602038107210044773776590144869507841095128986805399917716889737097,94271497992835932562874103278757400032116756041765039747726332995183554964390204442288393334665236335700063020174534799860251424117225874828741908247259400897208844068836969114844343301370484015148786737029807531127609578040269356203181806490127049090765570457173053771731322678344641402857532580837050951380
|
||||
1001395889265586485395767421092943095772484906688205160639025138850588355434167443569518670890639224060287615982046173119211466447418875356487968111638376610456681184419174307282534045999642719677458693603373061246804412063778941537663208494251233702824916937867260454282227810431834716831538058300952240529,60445540632407873888807630431208524230030823670563578058253542014522089940657440267941912297376844686920437735513309169811551129412183931683096248710036617268265519243947751270645191479229689326385715524956466565650374324873653293511970021452999675894489762841364719216977754928108945414058693987652866277,5401452543992462314517473547060846830682300053665170002473827326781788915141651047957910827411217522592705590143110487190395657380723574363184777022159851917393607961064987992588915644654812213550360705959643031621136573608890274219923270810168453305278905475435769643968988593393956330128341342800859836282482|1001395889265586485395767421092943095772484906688205160639025138850588355434167443569518670890639224060287615982046173119211466447418875356487968111638376610456681184419174307282534045999642719677458693603373061246804412063778941537663208494251233702824916937867260454282227810431834716831538058300952240529,60445540632407873888807630431208524230030823670563578058253542014522089940657440267941912297376844686920437735513309169811551129412183931683096248710036617268265519243947751270645191479229689326385715524956466565650374324873653293511970021452999675894489762841364719216977754928108945414058693987652866277,5401452543992462314517473547060846830682300053665170002473827326781788915141651047957910827411217522592705590143110487190395657380723574363184777022159851917393607961064987992588915644654812213550360705959643031621136573608890274219923270810168453305278905475435769643968988593393956330128341342800859836282482|43569972642791160005757596858255828258440677425601503825448806514649923603624018287716685991744061240705340542732331922577472226472918231509238166036331218027449035406029770845535194662631393899654058445399116462950394778843477054303490660149914576382156352231393154632904722395547296167018467287872528029256,-25416175075838450919641769013264410597729745958193362136948110865397498509541978552163608664910111097484344111265508414674502206468095426484449495661952091027512836383946952942259134571474962916748153155124469369237399224386694894533985438381306408742628779331072259662078374717232763484127547679303302310423,127851513581210146707222534812462714415549658228702116548129323569875687997527570139914376876955894345964691178029394628745573178902316765592327648023513178993717765546280790932769863585265709550819660882599525799584893587529991012504312937097442098858522399473806578431530443021404617174701716319817659510588
|
||||
10014457466865501413264699180995213607651643403581155351850240885586127254516466035686557278805989563280873217997386135507560429328380625332058111008767730524810617486297285562994007263758369576890950982876431843971907525378186076190945281470031905336296565482376151661355756246367703162199805483942789509516,-9493045169000225624825724585241654877107258957466554573322941788423005986836702078635071088783742277452705183557515581054220105186163500969879785143181676844657120253295906990349839818041129525896218008774011956975336293108128480236859770511279248182237458109627660116415432972887068943678814730002774447323,568058498128347562017983106577404112679290790118077765226872096344304166614495246835964393367142362074124393647429278191341969083397190437238809441291521483431836555168421336650034272837791888742028164348356631901893675815620388348481938896223555723594783353067563133868242273893775394833482067029611721906579|10014457466865501413264699180995213607651643403581155351850240885586127254516466035686557278805989563280873217997386135507560429328380625332058111008767730524810617486297285562994007263758369576890950982876431843971907525378186076190945281470031905336296565482376151661355756246367703162199805483942789509516,-9493045169000225624825724585241654877107258957466554573322941788423005986836702078635071088783742277452705183557515581054220105186163500969879785143181676844657120253295906990349839818041129525896218008774011956975336293108128480236859770511279248182237458109627660116415432972887068943678814730002774447323,568058498128347562017983106577404112679290790118077765226872096344304166614495246835964393367142362074124393647429278191341969083397190437238809441291521483431836555168421336650034272837791888742028164348356631901893675815620388348481938896223555723594783353067563133868242273893775394833482067029611721906579|53924208564494923109968517258991384333718615783597634502228353963509962336751805354923463494565719411128406689879296751392427452179492575502279868846589843663305526485431433798862642111241114809566645178986499564696116126963309686958809916838000470566457881788520159467305886335238376585070031885019107861839,-39165088112891919485404645022206551911392044983195122526582505244941571614658605614311191813725723193620640489676510478992438060577861340792571425647895723271516089195795031639152263494946222662918005100610385322895768473350699779206361702599565733658715228168714169147264299885332019593127372341848528310877,112189763824528641217468278574322392988954546777239131658850758660466358827365295080995339889134329849615042048060538504294364321483596732194229239161149447040110980960983657967678809117682823152517826486688609621632734218254085881353576474560418869461310902870862203604502294697766172436420730459846253285376
|
||||
10014524612435081655051402581388141399758826121078479680077428037590919760198044078469208114625992172565561472610137633731570114446039320551421576820201144498480274752068507237188168464666743295560743051180514619150806895664325776982239371917265280309982409950396003685063877356037007592827997650696359708648,-1151946584820929060448198375444913319887694243637725495546164532401952339142382368891700429417009398962503441132652463153588614606824550308747271936296460648801898782148675402610858915130433609314541230955826121143276189468724039832396682232064702428868374548095200287491142543410829209121388657552507539861,755148183880958266120452185655234110618667867205538459331580575221728013160051641776310146717168795492323023035012567121444609095123943446710618919745199683082156201032014589922592096239933647413759449971964484414757026090967529868635390069577397530636511831668757182454799405458183267048363982001659170207347|10014524612435081655051402581388141399758826121078479680077428037590919760198044078469208114625992172565561472610137633731570114446039320551421576820201144498480274752068507237188168464666743295560743051180514619150806895664325776982239371917265280309982409950396003685063877356037007592827997650696359708648,-1151946584820929060448198375444913319887694243637725495546164532401952339142382368891700429417009398962503441132652463153588614606824550308747271936296460648801898782148675402610858915130433609314541230955826121143276189468724039832396682232064702428868374548095200287491142543410829209121388657552507539861,755148183880958266120452185655234110618667867205538459331580575221728013160051641776310146717168795492323023035012567121444609095123943446710618919745199683082156201032014589922592096239933647413759449971964484414757026090967529868635390069577397530636511831668757182454799405458183267048363982001659170207347|46183360432532901454553912811649590320395866004347241196844991991079215314437275037790647677890495653136878666779844887628869070006778207117633836660092513861015319661569732287838772799418674107359979430356246346034550280154482402202513605341927486676571446547869725605869822695502032982833841088921112910317,-14839171560103132001614843311520281027921489422034665235320812512225719145369465447283012912841921017696170329655940078247191555778130550993274994429848671209676820244675419866031667103832358269654123112505016252317575238332509399397558348115029597533711563469431946692326093523953990323828622920869190596305,164933181779897671999712222932130083401866004577771560343160060853528269308468525452931360567865498324819919495168385048274257865546801611749112060417208336526645794766502287072279593583106527746581118239327199774476900334621937982627978739872164479446504941326886004356233761306601172587310954186017120057146
|
||||
10015153163121593836478079113660124757348318592530821165639828390191159358973882062973457665510869038410016978521906069415643885467466803613263638452835291035274253082105374798431579187029855868716866951698965254377198199868261126247017409456764474165861037253182443325274363795830109568972878953062238823520,2382294090568001333199894323474279123934374114667847405540440750564854209907703388935432920732110218963078674073256448624811505546395497000378710736855311825351193195350046490926404354706980500837042629648272073851723169837427468358824989832884534921916167168920876623159906890551519514875606250679556403973,773658465692173962483130527303229646901934499596511207834787839028928145069426505005504820136922810366817841934360207193839133022641619097494932108724559232945611195348726835877676174729010759098808115181632361389730445448407363060843805088069390583778242530477288002693827656348092952397617162960252636436602|10015153163121593836478079113660124757348318592530821165639828390191159358973882062973457665510869038410016978521906069415643885467466803613263638452835291035274253082105374798431579187029855868716866951698965254377198199868261126247017409456764474165861037253182443325274363795830109568972878953062238823520,2382294090568001333199894323474279123934374114667847405540440750564854209907703388935432920732110218963078674073256448624811505546395497000378710736855311825351193195350046490926404354706980500837042629648272073851723169837427468358824989832884534921916167168920876623159906890551519514875606250679556403973,773658465692173962483130527303229646901934499596511207834787839028928145069426505005504820136922810366817841934360207193839133022641619097494932108724559232945611195348726835877676174729010759098808115181632361389730445448407363060843805088069390583778242530477288002693827656348092952397617162960252636436602|2334289880943001376407857326996263570161383789108737840675851906077977981768540714248105544895055900962482225672861273136265466132609608331964249615854131927898907957201650301595252550620756829520427054784019840985991520693282395588941752214974743008251596421642708049368885083348322205731564243670420111453,1451720076983591598762998723081545117923198868478265830640664361188690301293679623937617406037087334975387230852094993435248087727723628228521184122895045650428549727009619829664472593953602490826316016345941727517760259061554173070969494032097919619747777129170826368624036489935713881661043471800066640125,3318960568956834644312274599956969298741234864897695465866703354170475923995521916039531437101483638236150279927673715871252637092748519401149230098061946550109095773979423194478592673363716301124276065026975130628863523060647342416992862735921072287765667600233548851774826575592417995450427441845506696081388
|
||||
10015239581157875832393535763226085031936027674008799231064578015529654192320817181717861924169857992310709531421935508097069554814977182072669044193680614850544453265357095259368437732015348877933787885875170804438256215681419620514332393733243248548151757671725579685427667920968624432291421418590675885300,5094068907677575740286879080674249533942090145311835759008798415694966420126408035500684853222542571817165748053609110326610732625612063208376418866488998532875479258993000620044826461966140228426897339103003926919606128736757098245146058573375685873266553963971816210554103991392539430164989850926128708273,793368698167290739626939845245925598679004619304386735598558585912760256279890735283141314660505981777266664338091862952502183635644778863932176282239208069911448671090051312086285039683208751050938084831532228722294544316547609430035555984901118374565436615559075980852757981922632778527357570396074193505873|10015239581157875832393535763226085031936027674008799231064578015529654192320817181717861924169857992310709531421935508097069554814977182072669044193680614850544453265357095259368437732015348877933787885875170804438256215681419620514332393733243248548151757671725579685427667920968624432291421418590675885300,5094068907677575740286879080674249533942090145311835759008798415694966420126408035500684853222542571817165748053609110326610732625612063208376418866488998532875479258993000620044826461966140228426897339103003926919606128736757098245146058573375685873266553963971816210554103991392539430164989850926128708273,793368698167290739626939845245925598679004619304386735598558585912760256279890735283141314660505981777266664338091862952502183635644778863932176282239208069911448671090051312086285039683208751050938084831532228722294544316547609430035555984901118374565436615559075980852757981922632778527357570396074193505873|54841829397576178848410586601034860596951681568779361478370108261032921497569280442168530570346157404440784855573637229833444102498053726559151577392605738325853410653119896676062193149054976747541732412004218217068288550127184839213667255982218678702854737220904918059908451831872125006158411607941690397052,-13987639594862577439517093919564754940146287009709146462369986810150221519296281298521622497304190878362220137401179604871651085725669668566995040192751337189374220954170616856835063054456944563624013156491483611079953326833211481288513306777121436082074004700443915242579221138749893848640705537321387708809,145658957896464652977038505022308448361415349923894631554394890309500215673949920864830014124570888235622920757378372327525946059952077895236293799705256119864823158645268515234330467061529263252614881624406296566043408419602845128600163566622927193489899129202143975708704672075445501568437520798105023647844
|
||||
10016254093062341091793169016069728267098466973354611327776341296362926980734885768145505535610323176943330336454162903286601650062616238131379152236760546371204482195908361542328829078490793642835057146484428739306586521325328236448343779367153378279828280298660045704810418678221790320328995853516877961219,5290291792844776128036538578818355234036731339837804827682257620535756451822532868533550409363458436730292692155637706486234356872153487706954079157252741244973963860424508734267445638531496348565715559236158994920739250737957339663944820624379832490664101888239401802029497939684558696213321821587965089165,649562196414599732260624464563141423074514382020176141033151990702926870363780837252385965871530682720560442789827097838322398249975199460284454895932864056555126156062190575895999061116214790474483579500239339070750293285631666586984632253828693474154470829221739655058926181416125562534958534381263761974132|10016254093062341091793169016069728267098466973354611327776341296362926980734885768145505535610323176943330336454162903286601650062616238131379152236760546371204482195908361542328829078490793642835057146484428739306586521325328236448343779367153378279828280298660045704810418678221790320328995853516877961219,5290291792844776128036538578818355234036731339837804827682257620535756451822532868533550409363458436730292692155637706486234356872153487706954079157252741244973963860424508734267445638531496348565715559236158994920739250737957339663944820624379832490664101888239401802029497939684558696213321821587965089165,649562196414599732260624464563141423074514382020176141033151990702926870363780837252385965871530682720560442789827097838322398249975199460284454895932864056555126156062190575895999061116214790474483579500239339070750293285631666586984632253828693474154470829221739655058926181416125562534958534381263761974132|4371923964825216081284965901486251829658920327478160330494959761785570498729926171763697403539994609514035386549444286899305836316283570402957212167175599769519526858160920653621106184279087086218630872059466833612874880235324503114394586087353649281136173057014948419793113247251617601913225740371158264594,-1777711233855585326424402788112018092969733488690398670027508570423282261674718543600694888501454195345939794788269076453964223553057248156896791027286117126036185606587718958830247368692129308590218482424190086311842595428742140075700660885589198113766412954745249944832418277914084817045523687626938171785,1486753504481531714235052666066139608869409848938074431937349188798515713076253106271449862728854109674272536360912828894345019832890057397353770574425655506024994198304163182702822689738838001321557096641997078734385067590564038418788081682782254559978113888414124552326849527747130706995014118004294289090507
|
||||
100168933817004159727571823870862212374515071383247163682233493029515956409883385367746187285740348786673303354766599662884032925310153869913659930858915269690815416234679514078167380783771768659750083394948158950008326340270387586985723448583932705818464704601214600293828130344813737095058092807371622380596,94832715670637342331954204053963565603302480280224254821703778448479787031215111088413069986664424694762700821340882966261664606716747356784210807087846121536668261049472463334524682357378613143974178468771819549191894308095591279746614292380149290609465170348542192697415722868093623009037253233869856957249,102860441967964242444445722269341757702905607863364253263839843561869841563005656247302036622183568251273499262767768690361280263007610763737074443848261770701568579600837276156244861738658629562432640564576786387713071777708265072467592751700403901387393831303255944800743982818455033707731784929932463764787|100168933817004159727571823870862212374515071383247163682233493029515956409883385367746187285740348786673303354766599662884032925310153869913659930858915269690815416234679514078167380783771768659750083394948158950008326340270387586985723448583932705818464704601214600293828130344813737095058092807371622380596,94832715670637342331954204053963565603302480280224254821703778448479787031215111088413069986664424694762700821340882966261664606716747356784210807087846121536668261049472463334524682357378613143974178468771819549191894308095591279746614292380149290609465170348542192697415722868093623009037253233869856957249,102860441967964242444445722269341757702905607863364253263839843561869841563005656247302036622183568251273499262767768690361280263007610763737074443848261770701568579600837276156244861738658629562432640564576786387713071777708265072467592751700403901387393831303255944800743982818455033707731784929932463764787|77074101972769923370658023573461029047908280864501436531886214070884695444419790476920141159581106162534554398040667029684395317753749995140975694643351101153246406361333865778019332847126758508398386399309944270422140994351224794089223904030644354844471144608782627152160492615030406249102513998568586126653,41985809674026851301068939458342266766093613320697544468890621111459064094913132603897896518617407840492037076180430740254366932298578105226006922522339189157081422030305375009727018508446301230399756872145212262654632874007091596766171377732560260349745066521408866260391195589212337788533541057115385883425,110229138576369926974358954548772667512560757802376313780826844717365768043167923353943051327604684088175403151021231033281660580097059744410859188703138886987578267563448651782227630417696079180690392826925010189611494463744920925421564075513181916017454497019126236913116432477001913262238126225201422341436
|
||||
10016905787587129103970068378589209223718079791180726370802218768976971488497998963132244508629494308529380628538141221743580243393344335649567002150936320257090927900467530902572471077942584896593451110546304416815718151825873142786318484895510554032583903064792109176935301749381314577344473149515437073560,-4606191417439560848418163571752652850846391635765859587403508494460979835111500495993727812816590518091323150783186546267331220869638878833615969103418728210432746474134652280483753966001415196686238333974286033749286862708642243562674370580850529480084335445537434013760930078201975018692661527689582576651,605629172398620500162437997408160351967898827176789386195142449064206069917749164747262079121234714184955198496120255981525746584380916729025666697652941726995464456228081635615903549843932017595245592861355354651584306759089064045480854767640497444940703279199283744488071666641763271403206424800946819221209|10016905787587129103970068378589209223718079791180726370802218768976971488497998963132244508629494308529380628538141221743580243393344335649567002150936320257090927900467530902572471077942584896593451110546304416815718151825873142786318484895510554032583903064792109176935301749381314577344473149515437073560,-4606191417439560848418163571752652850846391635765859587403508494460979835111500495993727812816590518091323150783186546267331220869638878833615969103418728210432746474134652280483753966001415196686238333974286033749286862708642243562674370580850529480084335445537434013760930078201975018692661527689582576651,605629172398620500162437997408160351967898827176789386195142449064206069917749164747262079121234714184955198496120255981525746584380916729025666697652941726995464456228081635615903549843932017595245592861355354651584306759089064045480854767640497444940703279199283744488071666641763271403206424800946819221209|46304687373394436931218438666336335256163483212484332920442711829320278593351077938042811198542492407186729960199059393629663370119443451307712349370714705707036441431251782566272288509732854919564985572759872505231639307883389746522852343879592729064407291688011480357040596643477509242715875322162180945750,-27559962602683142671407402152656684625711978340483108455301920226275039655520624691717381412007576185077377268485337641259513780832297300630514833099989822452624240349981167585374487019267119021970798715861631920467292530317231419988216997273247875678528676583110608263771292353047679830100015076536212572871,134999594026951253395775325545499481323026670784912424362786946325493588697203309584859459643146426717172468824814166286260797091069281816967149658244654968987888219904891951992996909324931101736714925044299968419433398393443198400917682271553527341988170608553689440600718627726318712053029382276372293927321
|
||||
10018204832407485307717168433283551951171211565712475881182623460525924044598415564148247583748572210844295784844361310074903318189804960966908772513031346031383059069976302114174587533940128565286800673190990221782901119861314311455679210523773394109738879256410739142961640761546729001001316019848803176862,5319904375533742100925641023534751951391638893478820023967035481652261436239987131193126434052892185984232529181792190920674907331089418651303709226767934571557921846173913244300134187483219524696758678859856206200663423378880336983240402046185791279466371047694436246549133924131892629303395892591776395187,649443554629399472805877307531888884997294549224205118199170867300682218925831813905978113513120968194233947187441042861450829488125193696091497608405966874500722600331516590109468259720034716473854550338705028445661682847162605116427138852824514186119049574433700978648124399292078009263486664308050317605762|10018204832407485307717168433283551951171211565712475881182623460525924044598415564148247583748572210844295784844361310074903318189804960966908772513031346031383059069976302114174587533940128565286800673190990221782901119861314311455679210523773394109738879256410739142961640761546729001001316019848803176862,5319904375533742100925641023534751951391638893478820023967035481652261436239987131193126434052892185984232529181792190920674907331089418651303709226767934571557921846173913244300134187483219524696758678859856206200663423378880336983240402046185791279466371047694436246549133924131892629303395892591776395187,649443554629399472805877307531888884997294549224205118199170867300682218925831813905978113513120968194233947187441042861450829488125193696091497608405966874500722600331516590109468259720034716473854550338705028445661682847162605116427138852824514186119049574433700978648124399292078009263486664308050317605762|2096824613311195474736703091933491927179118439681576075463684305365113996801091784928235546455105051723066941197368294736517297176841884535935805063900042702255946184765201041823632273617760317603104813509978347996857764943233871467178918416729927262302333533232369242879390413535385046393166248041635195052,106494743809548339750384465880660679449902990323530191499768868050880389213560457433755933556230921885636912867886887645004590062925256300108980851523487384554584007694663026566980186001150284697993766392145530903618307059918756399086400576557720952521322359177695970013138988731324890614696675530003172189,3099537274480186341907264372921810635861168363663532429504499040028118656288725100184032700559268063816635775634703345843577214400172811320277070043994325333354476328328682954931303645039746659585813529747367061450073478508564524387846459195219414272058883943010351216728564728313947382708438971484753032540491
|
||||
10018324718324265352080889354041349230495045650756363847859249064826167700621077306379636998633382620068424485758426219639651755498284131150741688356919555549109464768469845299901089390604198312107185124929799165529332689261450442020302769382765032211061987664530506790585428478002180255625233322864976647458,-1506556466689461719964363510118987647616549995746954868616471745983245113792074110437071688516535364802439931589935160320446594866789971924891832800418288544496229576060497571654938278590804451001178571222736016531030712235951293438712713277945256316492298818368402112911658258565046390998975710669014707937,708633648140842422465025989226402132551754445128385378651747216241166649232185357696677838986015643979480257385865744447602978939236447538983280973796461564754777224324765925807967303202117722154439166886733422154436177593473337680099402130518111476687602398807958385973240844776043934886139211712396905414373|10018324718324265352080889354041349230495045650756363847859249064826167700621077306379636998633382620068424485758426219639651755498284131150741688356919555549109464768469845299901089390604198312107185124929799165529332689261450442020302769382765032211061987664530506790585428478002180255625233322864976647458,-1506556466689461719964363510118987647616549995746954868616471745983245113792074110437071688516535364802439931589935160320446594866789971924891832800418288544496229576060497571654938278590804451001178571222736016531030712235951293438712713277945256316492298818368402112911658258565046390998975710669014707937,708633648140842422465025989226402132551754445128385378651747216241166649232185357696677838986015643979480257385865744447602978939236447538983280973796461564754777224324765925807967303202117722154439166886733422154436177593473337680099402130518111476687602398807958385973240844776043934886139211712396905414373|27695493339474189059880649994786373673681195258723034498967136263221174895242876882887946040754182923842018399590448977999734476968405279409965275664350294423197625592498762797252651752487096596479518881899735472134497736489815871889587384160668070191112126826489102305651218385469424433736996571142100268141,4244952032054732923978416579691917713463067102733490131769022354718180777349838220573662792933493750823939044158056520471214587505994364897599832929831064732609354344151098280452640031958247121275726298011899146169585223669027857229201360814944532694404419990370729211245101258947186079227140704211123597077,256477087542010205875387979681474864287758986482727894664413009819175948644274490742191718780565989800083756066810584023109412061717270312386676508030363737098913494555400729954736934622756650518307368707185355806725304278546342578972238562139946071381611959969612417306120634997866733933066171286156441897864
|
||||
100183725937805337440102832154923451468884088040067509735031176134138272029603097931029532527171620687937178427853408917605171373483732022096443082050272616813579999826937201905718430121138104894761796713162794983612090638008542903172271321979734531328047767185223183894705715872373581190063338544430105324944,97967360545064065581782092795782542381718050317435898718948431525445051912029574864522929506831468927036372238440312318277489221772379035158891587900186742286147138092170859279721424649522055176445825889170777870731814816272149484567390197282747308726861433765864290861778135213069453090668850681241158130141,102026058802637364547431940124628332383045736950389197653455431566764985503089749509318465184383586821649550424369391712983254618997917250229615538329822378126555642981029789087346297188093481472570239624171949132198549570384613605722016512646835562730355439782372504448945801732597394795504733391497603335093|100183725937805337440102832154923451468884088040067509735031176134138272029603097931029532527171620687937178427853408917605171373483732022096443082050272616813579999826937201905718430121138104894761796713162794983612090638008542903172271321979734531328047767185223183894705715872373581190063338544430105324944,97967360545064065581782092795782542381718050317435898718948431525445051912029574864522929506831468927036372238440312318277489221772379035158891587900186742286147138092170859279721424649522055176445825889170777870731814816272149484567390197282747308726861433765864290861778135213069453090668850681241158130141,102026058802637364547431940124628332383045736950389197653455431566764985503089749509318465184383586821649550424369391712983254618997917250229615538329822378126555642981029789087346297188093481472570239624171949132198549570384613605722016512646835562730355439782372504448945801732597394795504733391497603335093|88007552516538570862938195555687347843271125145294862509637863339852312849461683699513427251868777755449793173646890377883712394792262777503483942996934326765981582162423696391672000556247247431253370862284402004050248548817767631668543644528300726312835546938100615886799945875203418182610947796762957426066,46229538931090505519067196461411597385016117678710797853895441617844339335997518932818211184588127766146461427860967017470462043930326616555616035492326025837765159149630918451827844844437116744925433303753825438769925710637787423788344940219740545569047456022116580673560308925831201666938083175493702647671,94949150488319392606413346466333119512866765599276437121309157049458742789511630485348500087618567561361017601972082423173906361345987933875129792711583865107081204947273992176380167405635064486260061816002217859656028475745573246943400761862339441042416462774614661346152692808807449954694367626488600259377
|
||||
10018622993047838712433185410421446815061984959152870777572656734193435222251946970691795794836467121595552277401220487788714277091933394850502637162917792769686767139849624312881217655116086523917779102305498425044983500792458780789534783880422443059521517950075233845690825129430658238084704480639376209109,-5642888291743578132708587871691433542854601085995709323535797030150736747981212204721414421313379808144339701595994626772514328521365374368168430420450149143091140909885716813202658261033852230689379211692039890782701731228409652608328076923100699005939261407374626950263084881921749869854247192520776393467,584355741641273221932263410866659097943618996328052690659780811632775391934038170008705223727517700749237903184431819452649538607172642783739379843963426355234430525043677403033326216332450474494227299404505243469315575849027861412999876408965870212198057391050926245137105584182883631254668161360450853213630|10018622993047838712433185410421446815061984959152870777572656734193435222251946970691795794836467121595552277401220487788714277091933394850502637162917792769686767139849624312881217655116086523917779102305498425044983500792458780789534783880422443059521517950075233845690825129430658238084704480639376209109,-5642888291743578132708587871691433542854601085995709323535797030150736747981212204721414421313379808144339701595994626772514328521365374368168430420450149143091140909885716813202658261033852230689379211692039890782701731228409652608328076923100699005939261407374626950263084881921749869854247192520776393467,584355741641273221932263410866659097943618996328052690659780811632775391934038170008705223727517700749237903184431819452649538607172642783739379843963426355234430525043677403033326216332450474494227299404505243469315575849027861412999876408965870212198057391050926245137105584182883631254668161360450853213630|24492216963212266409994030118552483730975075727585752220177989563872338705971497453471962798275543072636175655672560120906290569324009187038649563218726182874757477950170840864973817320145411108769238293767323154108926503045123037222803844779103784397763216133236290396907058542243428101056150879809315089176,-17735224044627622852810014209171696937481849587925646605967048837801771413294839162751742330787917315172217980725109761639973896911760524548506285715284414033504356013230406678376141516049028049732948719065205234900025147050216480775931691209693009856949654955944471263615211623003442072374457069595919699233,241918233622395884761827246850514897219165802162342296635123580790888932192977763833922926853355444881644755349323889380463316458550630788255600843973415342916444918642659362862569058232566277775534472941540495721557558697754452057639207696448965752690070221361062821443638513586031328286832012283835743514220
|
||||
10018933732727277902205269315771289076593947560040587959114941078087116999373425488340685401505876624281584630582917353725134238041079746342415896279966203184863826892445916822683268888700587092452305745538315423010290563725863170080340035065039975298577793326244665530455537053974727163555479979119191279926,-2305656050929911594001774361902538333750937712118410383814661797948886130836022054225957304174319742645328482100663492843669952358370802861270894168816436326458990297136526459920949376942432261379981780315229778535749028029896216855337892147060100885167806805043764484945583720350824386167496969085180728505,426903073734578001112620417146509321508736309565051582451873814142074420259405364041324675206078055851221135785335125834745297538613608978468731354815366776968439807098716134814276564770795992539739869501301828055278204465499226602180360134210119244471648153940999928351968352054963731820177407885865927236658|10018933732727277902205269315771289076593947560040587959114941078087116999373425488340685401505876624281584630582917353725134238041079746342415896279966203184863826892445916822683268888700587092452305745538315423010290563725863170080340035065039975298577793326244665530455537053974727163555479979119191279926,-2305656050929911594001774361902538333750937712118410383814661797948886130836022054225957304174319742645328482100663492843669952358370802861270894168816436326458990297136526459920949376942432261379981780315229778535749028029896216855337892147060100885167806805043764484945583720350824386167496969085180728505,426903073734578001112620417146509321508736309565051582451873814142074420259405364041324675206078055851221135785335125834745297538613608978468731354815366776968439807098716134814276564770795992539739869501301828055278204465499226602180360134210119244471648153940999928351968352054963731820177407885865927236658|26579833924289520389972900117950394438805828628221899849785251193277262506904016180015838661767033925903809658684422106275456221210787145479887893793178117616282806012189342470201902133434844784106437109753666637085736679857929223320267986046560553880930252162405414807068330327382869655263308507921578124762,-12071122961357042682227388807856025622183781701383406123339407125622773263556987057807120839167314088703384163940961495607053608272112660158109007999608142815575559883680071225874610842202742230050716632165554413346974345932440553672309803223445371844345386485359912292135145947019769810450457220546043659979,162236250544606905260439724773080091403174351417582646687611423124289071438608418146998192800378143503443566522030518800544598083530735564341780541276153264296511032654040655556029284610154943880012602862804365596003928006715967740792065055405085248350810462900711904458160412653922105321414238780026013533451
|
||||
10018948288270418016780081341685235002997245256040164792426543952818991311558791493453519174957285944783722833865026222848031081817691340856453828555107871396513690880005707344898646359417008593189440903277104626759357903337151059344508962185668959714673026792114793015152022487676173726198202553281736763192,-6995555163054430382942870868581755160069395592106884274460542261252343393118569480209218511916560630596078206970035597385154389463448089846021818488631352733935369530889081823095829009383638648970953617256944401187962256866752201837099775227177656065063350644379695273754386677388279021465213328634933930909,721042528909917874686430575245079781825221838112029624394686069315349560814178350680306853206143047638999149938695007663434153092166743090545673695580676514178586788701941454964134693721185647384090760708127649587795147765724504088383646300322664057264796405575462352962768416720670014119545119956267157763268|33152009177899700335521286237987596749114678289874326434440918518081126413178191723162867529955418655435996482622593235632019894996887430996202492483564865515014035645906573982414795827153656592748272697286574461771116159112804016039989028059075628750439940373451196506327787093378094310321443683918398305578,19078728942670828368834699251746230066071047051172922041653025393624623551743744386999716370764191631344442619983012078124921474009852416209669177199713374821106687471027572426997637428928400364743864020836844501941937756570061589022465875716319591910681201998018650317776190333584438330413688185262916051155,220283868712478416207788658621383280997894846941561822444891957123908778028879195278346553006033805168466857198910274082404942136780954015736899511278911633428569844883635491399257549871333616419819287122510218677255768780334985075712076521491595155945026941146633288297234150638278140903654693829381901681364|86660112777924566325641144753803400410997086305075442702977432289312131972915955256795072094482313726948480079751898750790544713440908592818334342498838917381523558133222779818572943010979268307136948067185583734409642160207725489813897991564467762533071090190022128208402492072833343072675416905847421692846,-52778887618554305290105838041380262564458801465646670949464065301477666757134518520029567230285725793439487930254994645696418125229532386083964770290005616954332222417663293453485136710527439679565903814537080125880293745499032607178356596254426977323351345945596998496291222195474053846483056964155485024969,91256009874012914314189895519654249139544913048606429213352879670217368386794747037392624823085153501261342847050224541672528576684432409807110715865396865727844957353872518329845940826549252426734698443465027159176074936925639415490497467627459134074448093109088470713684894800193345119623601342741289991431
|
||||
10019019997781066559943515640881506642517558843222778169026234770851975313720579259773361086779089551884331113250530982852069738010518159622349375335824689350970737457654843734623714224913981064444982445158390435699719229301999181267314607899665318687660691355693147862987025822541914292231182646321427861873,-3157363997717363888291408594979293600171398541934051160356171159608233287859036491344319963143369936444410446129850053542356863751408144208404845266526711359417425663346085658910109244458752728340593138106611282955961606114280076234921423984338932045399865574815874428373668830300085650219459974701588901291,427660300107522994538791232761616142662131142234945666620460681757069587002421636449099874675218488912225359428713775902235016576565531397345002001166527254555699729200052739867740788272516457497859568251192144704431298212101856469342734690447583085607097591547685515622397916186942279884556709767139560196364|10019019997781066559943515640881506642517558843222778169026234770851975313720579259773361086779089551884331113250530982852069738010518159622349375335824689350970737457654843734623714224913981064444982445158390435699719229301999181267314607899665318687660691355693147862987025822541914292231182646321427861873,-3157363997717363888291408594979293600171398541934051160356171159608233287859036491344319963143369936444410446129850053542356863751408144208404845266526711359417425663346085658910109244458752728340593138106611282955961606114280076234921423984338932045399865574815874428373668830300085650219459974701588901291,427660300107522994538791232761616142662131142234945666620460681757069587002421636449099874675218488912225359428713775902235016576565531397345002001166527254555699729200052739867740788272516457497859568251192144704431298212101856469342734690447583085607097591547685515622397916186942279884556709767139560196364|21550716916645018398165650019236850766796511258117069952017796540701386085912310717417651598467640925140901250417026118119274327376121328459299004640348530767025071918784935281870705231282717494840395458987826494640924389129904911635742804398745940919397702998940021391844339448198369222701583556010313045812,17308540888407999086403450710891722292596558140904996642436794702554735336548386086410226733754785281982433279805336861038046891710619959255360830608311138886000204010857210058502793117398659272632248311839231357476736302883731390652600445524351263663967663494261178750828036606884450644013387538641171794195,202180803355870010447215408817189049345827932931561109501494466474799106708426285256026437292412097802628616665602361337631758401467452446995726703770591794057694222974232570992815439680545736890553211079290478720762205284250715176457370298196341449115424087895906723941555883338741498383975320110297668277534
|
||||
10019269520234431826137367355034420920528860342846780753959912064827599010243316724633755419135436935645907443407020572618899291215095816080730065338555965834485853320180090560809076866724238012634325051855947616588404872824038021038592555404461140712393653058441964129349148722979422040489509372096847725674,4522869991076735362499160116541059903683984737748984347542239263701333187108105456062644949444149453629982469461841568384073346981390834850295332934943879978241839313265925834724485912067878288054867100877621399054735204930899125650232136163964080568519169554901660276496750207252542508193487574803619459009,749663683253588383775532442379228650764046549728574777396900821733935114135159669567652069917832665405176945410288020981482404785970875873582684426212358839598234585501899432885966938532819200647768194074040482435441119436072379143147234400064595949108182133121869311200924895068707591158185629325001898213097|10019269520234431826137367355034420920528860342846780753959912064827599010243316724633755419135436935645907443407020572618899291215095816080730065338555965834485853320180090560809076866724238012634325051855947616588404872824038021038592555404461140712393653058441964129349148722979422040489509372096847725674,4522869991076735362499160116541059903683984737748984347542239263701333187108105456062644949444149453629982469461841568384073346981390834850295332934943879978241839313265925834724485912067878288054867100877621399054735204930899125650232136163964080568519169554901660276496750207252542508193487574803619459009,749663683253588383775532442379228650764046549728574777396900821733935114135159669567652069917832665405176945410288020981482404785970875873582684426212358839598234585501899432885966938532819200647768194074040482435441119436072379143147234400064595949108182133121869311200924895068707591158185629325001898213097|16642018863761441710765797012067927359722077189969631448415362616699814913503672898852374525215334055299068298216385689523710707393718883505223743676435071846547044089283998146628167129062401919282532587286538467437993909697773987546172287165832896898434018866746267084068433592983100742343012553891013967598,4279618085412193426188644638927864595084294097891450444438077735383453062127268915528450003127312343513730070105859170701493137563013978799842440344152818674511355384686181809257130294212609318791976849425989687196701708107582124757707100916931554678238461537620568164241235565012338998887375426548345583339,451300244762011954040540232948856842185637826616664360199909803894796107535366932948228367749161671550552967885565839529658452718412544695138612399812114901538129955756634712380719016039028157710981132001101643596366369267735875381875175432502771795477425963992931644164806539340880034536557519705047322385756
|
||||
10019417926514296392019946929112818021632198703101505458649653394849455829204203329294836960034957633501294764450648155864378373289178486051989714219614702737597295310475376780688730971937576079121199314793519307265245938553456529418922522984552293638273911817508398110317305685502955048568809327523071451646,7901274255200127696618788587659559342110188499337362982289909048078505324309251529636836412429419509644512565320215289593933580545899621400755280134055539493035902983697255734323738954580031486643652880504218537900293807494750583881428021909372888539470375818772560108989429450107579283565673329101511361623,623699550931583586227312516211712634135558043787600676758608115259112248746313728815655527067581286781548781459656217474418345498402764321216306327583412055637930534007526887412883845579485648951016708462255973917762702757210736584322682381497339273737323760137458761222143566171226992185720766268284746949539|33994172292722720621983078916917152805135157553786453695681859425113486805780487896660717595372501233092400041645960826591356846046682770081212496668808601116475820169782887756136359474132767453083956483565660497074117273547864843066209384954581834231890370515327604527171929343867967182910635357940103381259,31993846672125961531384598386820046988679306439927918439126442104342750287165534338581303476671621941233213276321267207968356271919850887377330275696357098758109012385572207725576199219446164534402970313646005215676387512077572153065651471880735849343888575800500099273015977254516159942552263434250458169021,190897440537416564844354648094133803032782149306929915760090455032909782181885170078703110757010607891226613247221902350507051587112666985339761578838390574506735798985627221778883031220656445342689661417080864579978266745285225101384742969161503945655665695989381533846227380883303389726073267640913232240808|46223752318790909370837447383363380695209474743451082994109239582734730617406604327737568722130199854939421799114849872972877989567189718205858628003551407137904188277330292052370440786619825504842930785565096667031645779355485895793277208105594179243179236367866554346063343397949912203277267219196168228342,-11006265064354212636439188801633654461277681721343546696389358983928696946083632218719947786058303199938972841132237674419697191902116627029793522898887023505508883048022803011324802659223889838681052775013756116093960676539648227562055647315361638076266948642978861465645013053193461759019970585499519918551,135510058813836316466595636693848570774859961098724584660465530747418644245153590246150906297996570248784693174475582519076799984652691145697384165112598092893383581702308752699625740019767305915611482144859189733431647333812818245189583002227073705672065057825892795634209388635037930002295896526893410999911
|
||||
10019602901864092738325953873535047812547299524695025320532290515768840900630595544396879008556083370139972255849271116199083634435552540915196064651229780380925328336224573551564497154428220750159228126503023660786371036661986963326869101885946108118123565859605937169197265825780593487194236118858010532600,385562394428775749047853575173957314087625602564743010180946094529317438985024787344743900106472493168796231871305499111699051361035813309229378162588371556942740300961721890004066420192802443990741112403096930009444198021764517249355582327168404565052575639878289683556483174213973783173191751884045426337,783418388779217407199495491198572563161785093246466615634830075323053502538909242522004194931674520522772536562755280126097220160459899598091584353065112800205031495803329979380114748688327366649214078234380064643848371559165846159884696566323937944146599304471519733682046929885711023157291005000370881207583|10019602901864092738325953873535047812547299524695025320532290515768840900630595544396879008556083370139972255849271116199083634435552540915196064651229780380925328336224573551564497154428220750159228126503023660786371036661986963326869101885946108118123565859605937169197265825780593487194236118858010532600,385562394428775749047853575173957314087625602564743010180946094529317438985024787344743900106472493168796231871305499111699051361035813309229378162588371556942740300961721890004066420192802443990741112403096930009444198021764517249355582327168404565052575639878289683556483174213973783173191751884045426337,783418388779217407199495491198572563161785093246466615634830075323053502538909242522004194931674520522772536562755280126097220160459899598091584353065112800205031495803329979380114748688327366649214078234380064643848371559165846159884696566323937944146599304471519733682046929885711023157291005000370881207583|19818230550133203045823734101898906263121512206428289485014719092970295967340599816897147977749512129070950063889339566610951920388554330328298156066258170373411927366975503222525343688945315211747565841144619516815319867733346621311891854079913905473945585105165350274151561111090081792706060108559348689465,3535705381589141871228391312322719660822687473426523492896512078425893509048104602680687792493669387659393458499063851065894084002514574997947346565631807028562721897282782831306960899838643543821499923380013426924166037069379808013932912663720597103553887305082262913905822119893857258661880909162082386383,396232614221934638032209379440961132627800399045535096109310461742382984824006540071415151913091585171033970335144034008200593280126662125846778006926029922409396791751216059456912978293211117174561768028351334637727875808828406496707486419218523437819900629926847694284488804630237181598046520852448325184912
|
||||
10019618759445604574695938593576587154046024907827143734869384751181580594765954554297229655147503034078881467428687208204647162639839815171638500727552711523715462319701731893862102462479728615304020826611064530542284194703939928285119162487825469366941939907341692107287635698074740058272417655173119766470,-1495231899271916161022455577964100860902948284811380648472435397705462086200159484323324090415310461943736883556854457678257712744145878200402349694425772714427495950140611274533744925805188738644517051127445631541048041016411029423836592778690668280454275321001430386581000830461603779827661500573849313313,783469223238034771138196543049546952638608016561545783572815717469547125551690528706587314602219345674223915943792376346892343135362218779360461138111067908088830730205053230437782849794424701715846764766896886615248793041482000930114725702333293352788421520623938402925312326001614873502389289399996101695820|10019618759445604574695938593576587154046024907827143734869384751181580594765954554297229655147503034078881467428687208204647162639839815171638500727552711523715462319701731893862102462479728615304020826611064530542284194703939928285119162487825469366941939907341692107287635698074740058272417655173119766470,-1495231899271916161022455577964100860902948284811380648472435397705462086200159484323324090415310461943736883556854457678257712744145878200402349694425772714427495950140611274533744925805188738644517051127445631541048041016411029423836592778690668280454275321001430386581000830461603779827661500573849313313,783469223238034771138196543049546952638608016561545783572815717469547125551690528706587314602219345674223915943792376346892343135362218779360461138111067908088830730205053230437782849794424701715846764766896886615248793041482000930114725702333293352788421520623938402925312326001614873502389289399996101695820|42753617832955580018896456376048021312038672906196490293353833260191208069121641097415768067383199309083970209480148720670849061245193936234205337011636997701073642429299438906449136644520319530218401933372485811940869805081506160718825508067884253210821932270118450554609943933258707984251287707298966456434,17230882403850817862353558174953648187864024855604030801497255731670352761964080837026196910757872387822284474688098560486179344653906733048259368377140267627812727873134204479739477928295254560644024291521347574950750033700697110313592478883239065168888362080121017118321399563553912315660492325767550439625,185334720796235401233770375301583579692277465177160979515315309579304038663377302594175210667527463523713902806451243556694869849316694559583762178930255061453115298736511664428765337617081386042405590606496094216885684005811351670599975552269701611841562351169528636440894665534868320186990351387365005093446
|
||||
10019692946699738437088786776088494849594837049086417807717694310404351446172508582779767667693745900344488207593378322991177040183985344860702086830308533532509706853397521152883298228273128452797173239342923997882671035778655648164732292144430552486960912845252279998708953177942214236682313539500552760871,2604527605619485478722364121534608303298155156200794123073555280322873845863667712157493176540131822726294136122515227024701303496679207443255980148330176850776277321446427192954383305967741429509598325549628410919591073607402118557146971439755257250099080900555940132394424289156437827280461319685081840835,500718425039020767061203454192505123268716467124573838196978962956303476515938135055207132642966201859533626566887497521633145487747565092871485790754737106452537951081291971352805654412531250563576927867442028177911508524615458471957056998884949042800057393476930961808638050281181278355398049850987480026266|10019692946699738437088786776088494849594837049086417807717694310404351446172508582779767667693745900344488207593378322991177040183985344860702086830308533532509706853397521152883298228273128452797173239342923997882671035778655648164732292144430552486960912845252279998708953177942214236682313539500552760871,2604527605619485478722364121534608303298155156200794123073555280322873845863667712157493176540131822726294136122515227024701303496679207443255980148330176850776277321446427192954383305967741429509598325549628410919591073607402118557146971439755257250099080900555940132394424289156437827280461319685081840835,500718425039020767061203454192505123268716467124573838196978962956303476515938135055207132642966201859533626566887497521633145487747565092871485790754737106452537951081291971352805654412531250563576927867442028177911508524615458471957056998884949042800057393476930961808638050281181278355398049850987480026266|15699856336284744968275216258343503146645953756650748657692246165468174044843605062520381697859516745152728271221936503804746010309726370554190521588468426695997279591480421106636754720909204606127286384900034321176510676319624471022876412905986167145718126102692531020933251202001854123564019876070185880355,-14062166839366990397106911248374270143217677864591057546982352524148999437729801685798965579843060529335708158623771293637111706433187114619631528674568287241750380206758693785598159577574034470606603276333153981703961125634290277406642003061722480822932526131741380714977106447263763374124622526844984498859,322600729981396869806359195462894217882445977495880795669692121484810837171658548584546952485525802042033579797467228310295552846960328437752401071423653349872764602844139832402563063433112043761099494603274082871711473366936549010464198833941650861319850342621348528624209403813616631484437129382551268946870
|
||||
10019878828465334585310006306241539349820320632176313877609501227637096062920082798688866463474161563221707726590576927421178038553651876427988000587231398238649949818114022781306536860520405792494648694702226319794624629000713829609168795402418848754413215058377284034953425744232395623600320736707606263601,1457969396702138085449463993396644727452880810876852537963663018612951369129008613129868381569339225995112076334917995066335564006261425730889703965704362733694154907573251182502287488642500690958462811412545500622611307129116327910472660655763332350656262023349742750811995788737019311563028749123005882623,450291340913970001914821927902049497930656487941189505155449421740207064831253795807819514379798428822187833726946052293837627776646264129023306160855543475421211570474321370516290659041655321190880413623652464931091503946846331738732993987858421621514193715128900207229532916132573315382608752305324170212688|10019878828465334585310006306241539349820320632176313877609501227637096062920082798688866463474161563221707726590576927421178038553651876427988000587231398238649949818114022781306536860520405792494648694702226319794624629000713829609168795402418848754413215058377284034953425744232395623600320736707606263601,1457969396702138085449463993396644727452880810876852537963663018612951369129008613129868381569339225995112076334917995066335564006261425730889703965704362733694154907573251182502287488642500690958462811412545500622611307129116327910472660655763332350656262023349742750811995788737019311563028749123005882623,450291340913970001914821927902049497930656487941189505155449421740207064831253795807819514379798428822187833726946052293837627776646264129023306160855543475421211570474321370516290659041655321190880413623652464931091503946846331738732993987858421621514193715128900207229532916132573315382608752305324170212688|42833037907205783423276083695584027308854900022881436412191284154327219859963073830726581978719142468079055995456299937273491938799745755641832339881754413481117724798837471944396287268574687471412696368395253559323362777618554120629431245413190434891698142985970974309630607227057049486649455303551234276454,39533289765204979838239940217464189791925681811448897199438008522556423440885704979337332145873978223602711609006720684578384015360399795422483770905500296209984111909778890881255526888804755991926913525266473446809003766056812782710240729514579954010888129016691348159521572577875112811888010834450317724241,114445618247053384708154338158850812121782306445016732813783780022720172489813267526238634887903604880900808775058943405768328545540868455633901730958967680579278364092793074061036266572372464072327099841482886966487871555516444733955521438600902217517451457471166242011115873608622049499975622745683155293044
|
||||
10020286611438471830628019358455663881253310586699113562825236385112929540691864656311239753327727457544039348532845219250052901384983806849838772233628634015372101882756673893804993295286755978494686187836862364142553996432815511321224683238615875757382081170105089085250727802357622063598298344850144933258,-3518711690583590719591097309663537838033234040270517781284035777894691716513958367977437977244707408588621580445912322309023058291956527967904833369032334021917801602130557563969030363343390282689269679494383594614447232630864097161162053988664606910387710340058810601198928739842230703566256279504206597349,624519074467883157241759882142650482668439956786299222741478860768930417779553600133573019763129305374619657419598952403430928431333332942138935285782814167747294995855160857963617057240775629113016734743963566849367848417555290458534979590030936513460373735155075741191499370817771701007396549636851814063246|8984140046463484249883815882793946664284637844291004682379330614023973939307670161213321888699915249072065095665013984357459013131040423611078930602512682262356539184355252741789076484547599307370908468303880417320438645852556648240043112769759543510509999231273948875843246292758661134579579434257790056943,1015829211229239775971450394627474475125445320143707214965330038892897841144751214160653701706601947354240523693277132829250608515076685164228306669891554248890083979225036216154539270241518786129131737028646904986272214000689553330402618431223976598945398343370629254397826639390022921851207744783430299181,696229436805911789845333715373446839368886781044433762113742356470360747294068486152977041956647781976745992022313448046591023280602965461797453603661925762491060402477228052040796508933029960965488494546655270327536485285614615574903948243360057525231142937895796209410153481097105649076038536726330776071856|54848884991217637960566999744777250759299676195564728508167267655054271555707478739692179275489551583228746099712696785024768087317010330909987410610335755940330039266190842809649304513680352828151859917245186776225281746820196246056188053726348717015680880973426980177317094806038726097322528009147634772745,-6297694570572926762876118238570574530971092334512760425031884066392157325338148271545111848669911902764684562706179269339278979620083804367858431071965438609706945865206821584390347519912299967269039438763099113180095159546022212222371772149775642184659607016581991317838734844206339663600961049231899483767,114217089877346912860627247021964232304547591103532855496244374445579581677534108677722729277710412822218846458954885849274521645333106817369257230151814552428619784818123898009869914417388072106361002314975966932911313776975771180600386738223895005689517440276702703392932181245821359844597699717902940161882
|
||||
10020350829980446730171851653876883566847163081423697114380946239282341122006641305758856122547334357120649922140862854047676100901410759420113771337592330434048703781028710403003719890979006119445870636592350392949743016116360518402562929646175152381835283065319457849053035555929737557936105886116269575510,5109280702416633154295665717802160083976280911440360164357040723966034505263983198614731009455276771449649216657900445462253241694441028125347117381803166387820276260518904247537793302370100297043111469835733504997940289628818493126591029673530532890213508380205622484398576652164337711722991311438354895077,783009249844890893386725492620727464553802137797080547324163831661264002221403011235072342035014102836039015675936188668078646910670188403603171656900915122608838040537846311585633442130109085368959065613240580402159306705278726186443869273434480098383561830991110484097132938532579731404550435571781667457120|10020350829980446730171851653876883566847163081423697114380946239282341122006641305758856122547334357120649922140862854047676100901410759420113771337592330434048703781028710403003719890979006119445870636592350392949743016116360518402562929646175152381835283065319457849053035555929737557936105886116269575510,5109280702416633154295665717802160083976280911440360164357040723966034505263983198614731009455276771449649216657900445462253241694441028125347117381803166387820276260518904247537793302370100297043111469835733504997940289628818493126591029673530532890213508380205622484398576652164337711722991311438354895077,783009249844890893386725492620727464553802137797080547324163831661264002221403011235072342035014102836039015675936188668078646910670188403603171656900915122608838040537846311585633442130109085368959065613240580402159306705278726186443869273434480098383561830991110484097132938532579731404550435571781667457120|15925442580907323476159397125803944340654208405155024852617286343514956884706735535756801413937274485810029110697926230088903038708172843921662902925858010133310107241826173293821650453674715296467364194160263065021258375363251922427504055324499581378214158250201451314577475359578763255572268099357250433862,-7555018813268449946347299883155637510823174468910058845458344328340586029132905296413170968626375161086356436888766911933184468019856845539645923943455062521960029199818385839225962202237763532700191551972267033706448220551883282613693004882011515763441495954827960366711246754821589418038272565907011571371,493158713590448502858812148491777446425856175908645102112390069549258575786631074217529579034304661646702428496672314797453719364387931287920597953147023776521758543809562386644010437874871311725548645377471116791426470171042917330992088151061235643311858502168972419940204783448967903363982044887911681560644
|
||||
10020520888850607221318889209733010855356370939979030352174416847268871176606842611908448929226351061331244222832181615393476121893202716429497688626737367070357875341852767661277331348237224754401428337725087948250057680576003972340744936007808116625981445480427395587481367415686693519322831225744083857506,-3510865184553106032575534381192821350315875177100225193260562098432442799313338094676188269972656054940854032321449718355451351690660219631429988981801589127116014570347706272895437608443770068021130141264825492984427313262655182236186480543751195475768423487011396127341338009641051881511727659162848161119,631736658355910953992723930048397079196586052511742763210137641692860240361410089621711682505909275894759266095700988382555714505394268624248297891868203056209475282038131157087467910727013960998888913755441699771876897234334835639550616100989309716008969633105517000398222168491114030388197708472040972683126|10020520888850607221318889209733010855356370939979030352174416847268871176606842611908448929226351061331244222832181615393476121893202716429497688626737367070357875341852767661277331348237224754401428337725087948250057680576003972340744936007808116625981445480427395587481367415686693519322831225744083857506,-3510865184553106032575534381192821350315875177100225193260562098432442799313338094676188269972656054940854032321449718355451351690660219631429988981801589127116014570347706272895437608443770068021130141264825492984427313262655182236186480543751195475768423487011396127341338009641051881511727659162848161119,631736658355910953992723930048397079196586052511742763210137641692860240361410089621711682505909275894759266095700988382555714505394268624248297891868203056209475282038131157087467910727013960998888913755441699771876897234334835639550616100989309716008969633105517000398222168491114030388197708472040972683126|7743624975856046040306859618381122855435839505066655963077953345318192394961725484815279361678840380508650449544352702656790861663924047145774380332205220566837995316217250717822771650639012193352578327705393209628172084550305955102732361657948117240351750958876943333563882332223706621973470079325216233558,-1302101084353535785220069078550654080595332453473298993211431176604229397211571627224468015823760998656644913758576425096529602829962318111227560243799515644278666734720045652589883053894188670485823003998604116205699634345292108055002592831517880997584910995083278522924829895139882422136963697022188627761,817146068444645002282702401442161961453363715531517354922416373299365609662611633811411725714915989553805697260975442785287852917015804775140015044436435034561860932937633743951090004573111260937285724402644730836466114286731010063169028245934842509507242843981736397798548000353928823827450308171577842094862
|
||||
10020928293252284825691361744328291985679526412406671670547266480511907045983316758483586023724996977667177961315263269397743828323222195866600241379821175298238115703011379072606569390759148045042025527825985903353933863183965714600189445609817913064133950477152949408914363876047922634974111379776851043444,8142743010559227647391965354039043610167208616578224783916189122845589179285287981476385252457789283574398377141778580365522603626148442954692842646237080732477747098895946414915542936790529750280288364463486949414374698119959104763454330750738981793594749326992763123032351693132354526673391669903228534689,592964939014299189950759948556152413778070028508201513223477782517837089792535061751235218815245724595945353108562584681842937744985593454797280372456160144528618905336752579099036263281502692258180148097231362749391384857475259373320991218168838336648271137666762974150421876463236269917491554488254970217679|1349884692028663713443418855258970852876197688505766806916101525225125648882224033090914393786384981404185367136201476426040087000294669320520442557740324611111940178669433599306350594555401574017007121415045406126185440950248044705540071793090107212207268142684391021538262661004297297377597036659211434174,875208077680684118200876261868445011629698306468238985964846580756586701312125036248886125282325554453814339944800057599270619114144498434513170361313175501368378946075602194132049645256086611958223310749365652107262190169934699379958455541016773996539749758645125590779000274985163557422936755735709025447,4389763511378485954501282191747251660999265924712682485695638493214865378547677386856476228802410653501422368180730844272453992845175409659922990510986478738442978379229425566565975718386747664393902959866984083918397026705604419570614664652992630348606149487368881973666571039701786237266865588917768672714852|5132295574467316848841777686734617679960174295612803556136691640948831222631657128041983413228627956037030789543068853182770008751639881188344733284990628383483491534738190385257771536358960825091917844011611151709882253457446948086421180899165481250089224998180312937340245384853080966454437114981749282088,4739229759958591334649295599424854432655955954287517912213597569502250150023192426249576133181257597090869245470242256174272934097508617180274802785425851556700817333154643929185825330049486269453049410315760063060060300773867433992976428473895933388104059320286367359084036012644394853593574323294698599047,1155642354763640840161317866632512711606463189115904666846240158382151567767869875575965412366883980252176109447698054839109820546539837615968386168917753356894372414795267678454138557008897676758489406076799290056896394919016510966326013771652656266881913835619564662608220574395369543699406086980500479286021
|
||||
1002117978472811787753331928095730917976095264113100009019616793747721435107135088389509812754479746771762680547024275550906766428627777497396364614972130274470274918515966945652987824482224985008334448385591915791378703701911471719689908547324909949135740705163689874051360252727792128439306172396510982072,-605384264858430906616142488992272359132356724983679496986875094989266808748892270936577381465129550495430948251840196888998891525556778784313001078991820767039598015715393254809115469379426480017252950332375890914475777381882010670869152139638115965300974540658001803028482400664131564914546111105190254697,5913050976191825085156815974405378266929897129377882420061135471366299940142986781640170880340909029950997987433372868814199338484242838439841578708925504283923079897355159590243914836924282498902916652661483948536914918309139164893684671128828548900808846820323860573206533041501286493089345814823705125482184|1002117978472811787753331928095730917976095264113100009019616793747721435107135088389509812754479746771762680547024275550906766428627777497396364614972130274470274918515966945652987824482224985008334448385591915791378703701911471719689908547324909949135740705163689874051360252727792128439306172396510982072,-605384264858430906616142488992272359132356724983679496986875094989266808748892270936577381465129550495430948251840196888998891525556778784313001078991820767039598015715393254809115469379426480017252950332375890914475777381882010670869152139638115965300974540658001803028482400664131564914546111105190254697,5913050976191825085156815974405378266929897129377882420061135471366299940142986781640170880340909029950997987433372868814199338484242838439841578708925504283923079897355159590243914836924282498902916652661483948536914918309139164893684671128828548900808846820323860573206533041501286493089345814823705125482184|40380288636863554747802272146363479186663329648459490067115808757434033306882038739884681373117979723495792330864501446629245889731229516933727403492773771957483850679041758865017396807842498482944854723605982182982516939476048881995525535805104281408686338183559590430185038164235953706463250800021094604474,-39534865948835591455192703514729394748021266253728249692602243000799548352268225360374954844443730084878434721021241498114475458481167089270721522242274850596448738616202710373135498775106936938952151771547223007405550740805387552512761050820125134092471485389585963771433812018574391368483598373549383847189,156418754990595886837540510636676538980249340054775526675231187766083040611703861850669234853631535367187296945071108522620946681763860321505477715553908841995650918300850635601347255855518666703848642329714582982193362014895765955759528160104377932684150225067984397783920984799879483126817672124425872829049
|
||||
10021358599463053436428121851639014288861925656265693598359693460594603335959883569550641125363212428397536880700859686977743945025535807563785786052244914761332363029072620567677261483868230251440566526595521949067385197316983806258145013751454322468391099167319094251906044804264200412596430324237392628100,709083183297048652772820333122772466256400885278203522245823989743215866042577745109340161132152908476855845193022669210873284198994493560336775521366659865852432460708969754436068709338598181470025481044065851120985245468046464349075382208377683917405549429133970439515821299430661611942330536123845644949,516570730285299534762323653103362077033679349887441156383985263227144702832028548168588332437855509742797208817471793880841971810641558363411834198813856099949994799818753787070184420373328485385171466383296907894871575302325766835865200237080249407408770698788688709844525521993129914019403957225364497263784|10021358599463053436428121851639014288861925656265693598359693460594603335959883569550641125363212428397536880700859686977743945025535807563785786052244914761332363029072620567677261483868230251440566526595521949067385197316983806258145013751454322468391099167319094251906044804264200412596430324237392628100,709083183297048652772820333122772466256400885278203522245823989743215866042577745109340161132152908476855845193022669210873284198994493560336775521366659865852432460708969754436068709338598181470025481044065851120985245468046464349075382208377683917405549429133970439515821299430661611942330536123845644949,516570730285299534762323653103362077033679349887441156383985263227144702832028548168588332437855509742797208817471793880841971810641558363411834198813856099949994799818753787070184420373328485385171466383296907894871575302325766835865200237080249407408770698788688709844525521993129914019403957225364497263784|45614503146354773723748422556503247371485318543120586857419562717702458851951901017328552145694380945314803604713256441070275022414069445773768101699000362770774983002903055045789385932735047082208988353464300453066243128392263161058473354625441431303590972274514200470903553097396578608004283743393727480965,-18121746874119905746733087661833019801123133290011543785996868679743860577167772600952885673213204134707814090152450287251108460725457761668330446170883400606809709199165941064933022535458655256850936026007055165113021346772772048647561510274730081303287537167422875133875982474754404203878182518086566378039,115286014209231820841785285504789236723202458419099047051127275140595097884705397561562945865060894329450657461353202401141562369532605474636151114816630008035888537731586842019104642780200033707263419710825605300157241899226642312799356394901240315456385563221341513078098381767868711376025198760539717198382
|
||||
10021467180917602737976485607440169246689782775819592060097133723376896163041617997117690261968456452635527584517534178504548298348503697184587408892932776130526709512085862666360259215825375712520283335147827351975626062358619071671249870717811464295853663335144999169566479738875598518880232950110692415860,5837741371138928752178739797917364838658798118140089345232324713852930065920933839519905580179654383108038638880741427980662680469791777270068068248248823295528533080598248956003543247574941878960563240116001302598572351690506654603050328390643642345907246472180377442808566360199364409627306574545050404961,447367712945794368035040617182455309390859836657260473211881159345841479208328013611245196832742331205848397804369783648021077720443154207595416670723327933025826385393654289188255079761853719682847837385185400997339750661153486494578411301935184740783631461198583032914565210707960404049019611688784713553950|10021467180917602737976485607440169246689782775819592060097133723376896163041617997117690261968456452635527584517534178504548298348503697184587408892932776130526709512085862666360259215825375712520283335147827351975626062358619071671249870717811464295853663335144999169566479738875598518880232950110692415860,5837741371138928752178739797917364838658798118140089345232324713852930065920933839519905580179654383108038638880741427980662680469791777270068068248248823295528533080598248956003543247574941878960563240116001302598572351690506654603050328390643642345907246472180377442808566360199364409627306574545050404961,447367712945794368035040617182455309390859836657260473211881159345841479208328013611245196832742331205848397804369783648021077720443154207595416670723327933025826385393654289188255079761853719682847837385185400997339750661153486494578411301935184740783631461198583032914565210707960404049019611688784713553950|37349917633767587717677900017226055640277491797128368066909216648299856708848885314856667952257677125356703617528489552040640666031343260644627231518748509259039268948250724796991429094425535890736981916444739110193691988414365116633947866879178749608358114634543684726462828729304210028284694641568628398966,28432301470760114127472799211494908630719349909135890789013779669649467182102043473145513283547284407986093529470668063517370252190889483927419539271833812410008532555047333957640590516339384293520187649830718680466604203963675273404448810489933228206090139475240540056839557201036234130668781355507913201183,125217411042216743409615853418748212447815557938720716586287232669270939052168073429461670911284540249994159813915524580152040717865022372477773851596046555005754956888615646701914356508633194785367798807957000924761874706728044310360895862676117058335122487191434401996751617050877596333038588838996255145412
|
||||
10021498468260956088123000232540981309673362233093607160766199611849988598018670545801586655713528191099718167654049219862424879654097800612715754405882205966256512537388088543329708772570689386840584832681600027519346949153293344313097460804932850840053785736778266237521116511372386612740914586110495537184,3731424607272136278046418371062826309603938690430502989163037797814883875895107208656392082954628965555189423854897982564780098075475012739517997385664143357277834178448678167762594236943371764347482562787414335427396456552673654489280935057856453787409277651050808844230948476551514072021069206021678774679,804130312590685641878596579775606667166276173286759021130255643061750446804433775305738231667374247846782607238734204509216228540137516790899866440807044660490591982953819190288555363659024778526537985822773652575997791262130221988665167762257066646395773224522658242462757313827560884465576118125526400301268|34167053368438934062493883132954265990697806318308586148616977663701145830016368570117108522767165162437388551633476818714638781998737588453423052906955047313659481428825017492981415212399429876112133486106544289854247118707826610748061980313138870978861241099932331052851628733408772936072321439631381625681,-3231990625187035132148669134941674343311291560670575472626948487039873506375201953961203524971750773872175368844083313789606744945666601496978495543448223413432959722175027775640416642119534579082078058359377011061266769493053544073177090778768228650034186796092538667273516567672252447273843436045477135595,235833074847574898390813679013790646015645150909185733872405459206523708909325302363230937825102097363178252008781874033668789787718772243559737247157023625992313606650868510119173526138833975525463395139358451436580786324137262685697090102400693677208248369147898653293586089386800659102730021728025849255818|64608837982278224108987963939830921137767130655870201859314566649037112194604993755919994541029928783963356571015929786284493006279718103094473109088356869444636451105877134516067500703977445578997872357043341015093673550983708510265625469154579844276561631683451922580837098594165662625287526508058436293986,15854906341458894966500422391448052536768193946037447623218750633953720338742777805649471066920966160101792990529839212517155533383911249825767111242302747793376405376781322851763232537121183798411448041082168628199040455135693063512226758138709898399548068871039436946823094929235771529576088321067557016361,125647737690478667744295859750549841902875194170056775019306475803353424716724181236654109541003077830795994847519888612974479612555855274394676374638319448048091194349835875247946393849792063872096400150096455332718354245732182310596592154379165437563189009506346555534189191250868232374253149843604451203312
|
||||
100215518435515616798081693150831119413586767021678884124518533924984792516593586077070489902053827517598088670562746849336597165534172718871853401767137095032008213339529086616777467841346280017019578258259797551450310087222690828893461467525694138266456717327225955476876417507053206969995585955166268406129,95057958551667401403353090513192344071592935246219146691681088413017107538601166978955721880254187942559271242509539286042857509266018196345088028113071042234423096387755035509877692642793106294014825987119124937967036662120185797721977723389759564327297787909379686186622926363357951464215904895677999421567,102919326722329333489116060760618421823222867295966177344707558731080005177983472593218329502964236109795974387237881276225611846575332218440299281932674994159773703889896299379022277106535867836949285795306043775879545666098740309487810106763993748938964994198360229518682147400433454886610366004026941047356|100215518435515616798081693150831119413586767021678884124518533924984792516593586077070489902053827517598088670562746849336597165534172718871853401767137095032008213339529086616777467841346280017019578258259797551450310087222690828893461467525694138266456717327225955476876417507053206969995585955166268406129,95057958551667401403353090513192344071592935246219146691681088413017107538601166978955721880254187942559271242509539286042857509266018196345088028113071042234423096387755035509877692642793106294014825987119124937967036662120185797721977723389759564327297787909379686186622926363357951464215904895677999421567,102919326722329333489116060760618421823222867295966177344707558731080005177983472593218329502964236109795974387237881276225611846575332218440299281932674994159773703889896299379022277106535867836949285795306043775879545666098740309487810106763993748938964994198360229518682147400433454886610366004026941047356|97265337163108204413956364816446311461172514617683583383746668715450840222180976393430496104553022674333721978573099848181220662887846947468935453182046364733749916475895309307017567642434296055225121834950440706059303257140878621147190170027097598386070490643511792242136161870345758898813890460055238965518,87547457109798873839305649757452333043926932497015596041815056726077989206997009131840148396020804211298638181409067017194388111483773222118240882283209994405160200490126585806391098433830826470475358556954973925001096433563812177048160467037091694157852152308504545492956027258260588167152638099756708452923,102515957029857878751803789736896993327202543313952394340885451428025600212535749454672085478483321275958139112689603772374702592116757008616636478536965453679964666255956305064090090239129654015924433954512354305722977754010864408774189090428174122344384620043576093595618564991259055360564491303523423085863
|
||||
100215518435515616798081693150831119413586767021678884124518533924984792516593586077070489902053827517598088670562746849336597165534172718871853401767137095032008213339529086616777467841346280017019578258259797551450310087222690828893461467525694138266456717327225955476876417507053206969995585955166268406129,95057958551667401403353090513192344071592935246219146691681088413017107538601166978955721880254187942559271242509539286042857509266018196345088028113071042234423096387755035509877692642793106294014825987119124937967036662120185797721977723389759564327297787909379686186622926363357951464215904895677999421567,102919326722329333489116060760618421823222867295966177344707558731080005177983472593218329502964236109795974387237881276225611846575332218440299281932674994159773703889896299379022277106535867836949285795306043775879545666098740309487810106763993748938964994198360229518682147400433454886610366004026941047356|97265337163108204413956364816446311461172514617683583383746668715450840222180976393430496104553022674333721978573099848181220662887846947468935453182046364733749916475895309307017567642434296055225121834950440706059303257140878621147190170027097598386070490643511792242136161870345758898813890460055238965518,87547457109798873839305649757452333043926932497015596041815056726077989206997009131840148396020804211298638181409067017194388111483773222118240882283209994405160200490126585806391098433830826470475358556954973925001096433563812177048160467037091694157852152308504545492956027258260588167152638099756708452923,102515957029857878751803789736896993327202543313952394340885451428025600212535749454672085478483321275958139112689603772374702592116757008616636478536965453679964666255956305064090090239129654015924433954512354305722977754010864408774189090428174122344384620043576093595618564991259055360564491303523423085863|36966589133632021596451231446360613869218644305972974964188922476722370035917724082641341991636532809500406571267262673636673259154835535079572834230006192461227395506315158937114124659074990425552664025796331234355303904150803244972310400202941266552149385712614489884410598364289566113507512621328083820598,-21149549205459986335385704446469107610959268704221609170214996514478740430167085550085863459876947711137447213809502018277525104101042350103376631096271919925064995296178696672186362840988476041323653097243744018198278462448741240768165379772727430920245528842325914682295445854217287403981994755438946746143,220927487842748418739085114242513506611909793723984315299233121420377274197319470229298268289856409101985756388437199198962449705412131211265923072982106236351953282676471404053070507026981693842676184502073850443982862759823135849927410711140706664324113248738142786497634534093355523248932828221913746822818
|
||||
1002171279912987474674729832690970557140429555644292059472271841324924331291685060249454596336585889404705002700240738701699260928512934819245660001207610075089195766056310376194900771895925996113770666776022108500330653518924376342638824072832759321658474598385675431858595122771183526939999696158578609708,826219028959713490046361889088584439498783654783530925153550597879152616132729000468702177706363955325292708928091882754198698376648310966516057873159349764829040425546512821864182430231493467696041840597321743210951783900165181749863389211006249005916285731575237461143803624956905795631847651371075603271,8037828098286918052259824988376802356784599160404526733485731117320394626772712632224126968007402853349764765913068975115077635719542022449549397610278043584259551667143554443745235133704301422592616247052815801996895563245349515275951060813799742580455732670079073038616591480535324416008144264918698168050014|1002171279912987474674729832690970557140429555644292059472271841324924331291685060249454596336585889404705002700240738701699260928512934819245660001207610075089195766056310376194900771895925996113770666776022108500330653518924376342638824072832759321658474598385675431858595122771183526939999696158578609708,826219028959713490046361889088584439498783654783530925153550597879152616132729000468702177706363955325292708928091882754198698376648310966516057873159349764829040425546512821864182430231493467696041840597321743210951783900165181749863389211006249005916285731575237461143803624956905795631847651371075603271,8037828098286918052259824988376802356784599160404526733485731117320394626772712632224126968007402853349764765913068975115077635719542022449549397610278043584259551667143554443745235133704301422592616247052815801996895563245349515275951060813799742580455732670079073038616591480535324416008144264918698168050014|56177784089692916832266345214421120674340798487038570515623153805048107174705903801913422904686022519185882309714950449353350144136176082122642988743155385846519789014579069658520240091050781441562176069717906258293112423657764692478227614483398005555460543943687308770699629754468588531994448652035243537193,-1367086938896255072793415069058299472671169571526909227192393757206171174220534221238412428332819898373711167739278653738196147736460040492805449727552702294473184951105379473908985544436596593693459127262500591594358945429165046595165680187593280155590732587752336804926254680443537232304173256876819864345,143394353759539327949427865403227850259090677769631111628953936665415814894670562885615312902238352976078395198035416430261300974094600135242231268642783230986499797624830094698405716034919055851528418996945744623233014619026973652777892429824489371625486460871462705495597542593148226840678864076948049036056
|
||||
10022430537581100668502883292824778933607339338765926026805737984600928768394291101969168677779321137283218236917508266473465030665219284863536608447940487677072083129795072785840083494425556238492937940196822995238448372796541954279303435932510765640503040286741618037016213243353519162818665268721728774804,1745450390765598318476765814191109791291817192933930838487529317598912090407141417101048723630667618601898718290746648849351810269839537783425961583377520701947088669609241693035013571476458016904170389418378228794668337339954300480921565354479003099904568784841604791321827362751710640603340143528678878307,505461416773210200375665916297012066614237052797213136609066313311545733018491487357728242574093909073856795981653867763762281713211234379922321747443616377604676750509494828442443340820844933440417718090216464110039019539088373064239526712549777394214168807828906636896179669124200810156121848745927583143473|10022430537581100668502883292824778933607339338765926026805737984600928768394291101969168677779321137283218236917508266473465030665219284863536608447940487677072083129795072785840083494425556238492937940196822995238448372796541954279303435932510765640503040286741618037016213243353519162818665268721728774804,1745450390765598318476765814191109791291817192933930838487529317598912090407141417101048723630667618601898718290746648849351810269839537783425961583377520701947088669609241693035013571476458016904170389418378228794668337339954300480921565354479003099904568784841604791321827362751710640603340143528678878307,505461416773210200375665916297012066614237052797213136609066313311545733018491487357728242574093909073856795981653867763762281713211234379922321747443616377604676750509494828442443340820844933440417718090216464110039019539088373064239526712549777394214168807828906636896179669124200810156121848745927583143473|62092481921639574438226283198332200678734028657724766941730022043809545444204108322446905830622252301375431538847493859046365695561521947886739278282380330944740137778796806258440017010320211759144908638103476555150573303911926239710190937911611647166321874200336757808613044926465128049757211183544247137033,-45250053315775064910191280612561362661486537888549446589078696876018947013616669550765115160411532144837380748629686624052593601626644191366587957076497250945144687082001936959339633808733565487985938465191480629685961056777143827741613522372695750936020580143021192692134512265227690413020620317312128938767,89818959533274049458857462069020739338602011671046728330943513188118466840658369260446327848180189713317967953477747595755322234416809755612045527023070344299134617743385420998285144607795275808302453674682604268889767229654448620219461284821255145925444306004911131336470833940664306256327917520781637949994
|
||||
10022447467429108159774355787589122715485396978224199367300758397771363796346073591552810427326339622121413685155961164725589610901918895551781900417862806225664599680621980718988526130452221161919053852672286805155084312599146807342205269705230729665300558186233143844168304167857171548003707472393702474384,1188885044590400163258159304120537014931301063692806659646722818307638465604090862597898645794165661603569562151904733849823451481071963642820939826997500655539582070601901658042242359967350311563512079177663668335375683704849269904109356286951724174166294895547399547486092075854607019467491563004574181747,451886511793730238078310968270671960837012936994555807769579552350299617939295621484477388940254813126337697555682035175155312684470552706006082326229489214590934446980684912399661406451818153885180492656373585024394872163807899894979861799817481760468528780471201306793514412189815424515752868704991093442748|10022447467429108159774355787589122715485396978224199367300758397771363796346073591552810427326339622121413685155961164725589610901918895551781900417862806225664599680621980718988526130452221161919053852672286805155084312599146807342205269705230729665300558186233143844168304167857171548003707472393702474384,1188885044590400163258159304120537014931301063692806659646722818307638465604090862597898645794165661603569562151904733849823451481071963642820939826997500655539582070601901658042242359967350311563512079177663668335375683704849269904109356286951724174166294895547399547486092075854607019467491563004574181747,451886511793730238078310968270671960837012936994555807769579552350299617939295621484477388940254813126337697555682035175155312684470552706006082326229489214590934446980684912399661406451818153885180492656373585024394872163807899894979861799817481760468528780471201306793514412189815424515752868704991093442748|40311793122681847438147936825674014314470693373123318161207015676732082581716792137317735331938108693356512243120485847992937858572985495883514340613966135614307974866016309204238807033530669264492564117724246353883749827195305324197399377631361609176376894124562777952015115546002574992839306368859847102214,-33025539083635098527284543501358773726385310602673068647569756256609245347645406103541323476799319282115094670558563042038040727572072629107289743928712116480609261863925810781181839890265471330792670893248452312920468922228853995606392415425665874155050360471274554137526685669823510791388257867791420447345,119104774305358145853754696022566395542085319811674406549968528384273306539129655277119394569116384064134522924495522726505126314830673393570305912602792523829301472113875383292982915986048501532006750975293601050038174705411480721485112499986909208662941192321772927410908019836648310546774872889908741289549
|
||||
10022730206246523605885847628248331589129959745152946800589982371582759735440896033124734292653525513269378463322751069994968860121969888496580966465696069881018097413525001416210515174455496944629883370533539582159385347137053307519490537337422600372155743988569466107652391801498216166822344049274248006914,729727310531644666459577636524370584122920562232400100508958613100574209791027073647329563436154072167135037277674792721862334569450792556614550488339055151138688316081220432057278684502305768700617734898572463248131416139418546546921772768563777642345566507958981323489827996692750181630164696164350792239,743420530670049129014551314283001582671251574132606225656558769248051872668919945335156046109684599461479010072698042194265131432439432111708952985059170648240550914992169145894926437588173425753889988734024781047390921725232442091277340971091116650569099484901188657501225210251920789312381353410873675482898|10022730206246523605885847628248331589129959745152946800589982371582759735440896033124734292653525513269378463322751069994968860121969888496580966465696069881018097413525001416210515174455496944629883370533539582159385347137053307519490537337422600372155743988569466107652391801498216166822344049274248006914,729727310531644666459577636524370584122920562232400100508958613100574209791027073647329563436154072167135037277674792721862334569450792556614550488339055151138688316081220432057278684502305768700617734898572463248131416139418546546921772768563777642345566507958981323489827996692750181630164696164350792239,743420530670049129014551314283001582671251574132606225656558769248051872668919945335156046109684599461479010072698042194265131432439432111708952985059170648240550914992169145894926437588173425753889988734024781047390921725232442091277340971091116650569099484901188657501225210251920789312381353410873675482898|72678153493282504157416115644391264652311137140691071678059939078869970502440343742868078709786102781757123551689967637475890683084227768997487411568948523707471659432320585674519265605598599734502760770267332905322559905487379207111063130039684891358469047921852095373415568614214678421199229135813148340086,-33947255666808860516772098102208086001134373039996489095024233296987004975315716216270171442041054094605710390151835995913332617034994068103936254773578912095997116516855870766220741602335129322709546766837859664219492792132163257557798382623121354098297535938342782377977312458602436715508338777893530715947,106484190269718620144286637065233814518223762302071472353291401620347574484719889974719727699170546479802692571973907348709106400438154108695479596777257546039047068390011589281587022778512291574952016353907379824791098458869045617748541670371657706126860369909581308416699070396340994092087729258233572584479
|
||||
10022801037884735919398225401015346770690037220981230548926941756106963920408338416095733094536206053772963879852109190901255264805008288279841331919785607478274212775267264447609163695284184368267756738466008982331882800742073245734831347575593957813641726104668466028052775256385701674654962758632735214325,-1581758127940839328365881014818315360646059541554455415456767586268677829342640676667660057584626141079060910685268398574862315277919005616512245424342499450499940252940175197812452339693288044870174334000429767858420712066019926176503980859313840839446940401868444636117019979796283038985302067912785275287,496761537019467923365643288264945659788228256979170730808696057920098575449994591930452099194380843846370073248896650848520976197841222484748214967557803091427696552713317560221122191533744679546984546053333189737767090004462878944114371161170193473185997313558677097782867340116873490763865370370260817678938|10022801037884735919398225401015346770690037220981230548926941756106963920408338416095733094536206053772963879852109190901255264805008288279841331919785607478274212775267264447609163695284184368267756738466008982331882800742073245734831347575593957813641726104668466028052775256385701674654962758632735214325,-1581758127940839328365881014818315360646059541554455415456767586268677829342640676667660057584626141079060910685268398574862315277919005616512245424342499450499940252940175197812452339693288044870174334000429767858420712066019926176503980859313840839446940401868444636117019979796283038985302067912785275287,496761537019467923365643288264945659788228256979170730808696057920098575449994591930452099194380843846370073248896650848520976197841222484748214967557803091427696552713317560221122191533744679546984546053333189737767090004462878944114371161170193473185997313558677097782867340116873490763865370370260817678938|11794018787280482940784484560654447929703367834543013693618622456325444683498014462584498990809979794991029406828035162064888206099231897450516338131683344468341641773247077777974904033180523619849644665052604243871182886239709602918372696154159689574416694382901020412810986466933364313296340223658056711860,1521303582082972784094072429213245037004474422912041747980341661334088522130166480999863587718878595218681652383126000473728595142115360315778132844751721718890137106680913339185860894697918722593994440198312742439897553470706013918108591714015302153342792691194124679477731145179750991721088470556891980683,422154249545788907790313192562529747503206514258177376656051975747255059759645179919603489351691318624495599133821906453410850735326793444201922900151270842818708202863054380424556183873836633029531584190623724167592312286966999660766414372084390763660497972689763908414494950088490657933080790950343854684683
|
||||
100229993686309443431652234853242745584964039848901396902154758000675611952948762456754223980100376888310959032918053199573371179952836402943594446966248713771392255748269391671122973567354604611827710836480143363448852247469233467634585666281897503837387248046923275198978369387627574778973203963568459570613,99141614774063628352404317381455383177814780210220526925227232275804977777537108958838490639289349073928621828114260050626184229387757267144939794360548040966543453766396248232212371430223357646841577045712198699745634479223254936354615654319866477688010773948549511551046967361375809493630740150224195152939,104882524400956127942658813062851389442407913609672222789148495255743494809906874598039501219688723468166574648371069153919928988258063568059818823680918241728433303999086584504182405446032391227196284068159574388579981415818096136448105143139694516800086480906674126689437313489030594417564677758780953521314|100229993686309443431652234853242745584964039848901396902154758000675611952948762456754223980100376888310959032918053199573371179952836402943594446966248713771392255748269391671122973567354604611827710836480143363448852247469233467634585666281897503837387248046923275198978369387627574778973203963568459570613,99141614774063628352404317381455383177814780210220526925227232275804977777537108958838490639289349073928621828114260050626184229387757267144939794360548040966543453766396248232212371430223357646841577045712198699745634479223254936354615654319866477688010773948549511551046967361375809493630740150224195152939,104882524400956127942658813062851389442407913609672222789148495255743494809906874598039501219688723468166574648371069153919928988258063568059818823680918241728433303999086584504182405446032391227196284068159574388579981415818096136448105143139694516800086480906674126689437313489030594417564677758780953521314|74350434749389969050012184990337127551177662105941520713519479144559556197790064845857130327167806787623076521428876751871163669518580183330141936425233250661556229643890019866856080560251792692090494599862764037832371889499003253542457382200017573287275373464647146587627430764219256453016377003846953421792,63957711791573361964387609614017192151897432836032720396105880275969302058600840013396804158201720534370023895822842857827830012733763196699928990175961939998886321856401382898475734879783268690655497427397663979021512999064707392335539401656442120559970485354029428771216688798043679886727502284879667604695,122094202522303244187343830185980046602374556531568820744954812272038371153739943186637285289631950376927966459293327247925407412742819149064968500238603572438294529950547276948751033111097715894035925769404645235126181286620345914299937264438033627270225587240098530161700877220337370607067995020225846162049
|
||||
100236185197041329075554833621063049933091933804804579181020863476728313391686305869039610612323226747485959655907451027539483829746780221656275287251359920572256326848112354466643258852396004468792417619989592999892771161118188446161121453052287245392349650298061886772129843629230859327769032485896380376,-23246228755139486121091450291914215536752934295258164744923084651696211557139982911633633936256958755233390860799953871691506689375274550434281909010783595844874773750530708001462730196953616598369162178869242223651107363158755851755977149870788847101056032248840046983417481075963548958473469668684959891,56573523673680298471644280373809509686143659597565817726545502453421314503494549466829923326874504507298291631695935926527600390521472116074127195438583945763976558015737054829572336871056542824657451863625497940311479875421301704568832621760721804490304525701867696665290350769186367013604263730372702025776917|100236185197041329075554833621063049933091933804804579181020863476728313391686305869039610612323226747485959655907451027539483829746780221656275287251359920572256326848112354466643258852396004468792417619989592999892771161118188446161121453052287245392349650298061886772129843629230859327769032485896380376,-23246228755139486121091450291914215536752934295258164744923084651696211557139982911633633936256958755233390860799953871691506689375274550434281909010783595844874773750530708001462730196953616598369162178869242223651107363158755851755977149870788847101056032248840046983417481075963548958473469668684959891,56573523673680298471644280373809509686143659597565817726545502453421314503494549466829923326874504507298291631695935926527600390521472116074127195438583945763976558015737054829572336871056542824657451863625497940311479875421301704568832621760721804490304525701867696665290350769186367013604263730372702025776917|15573203821391096660668742152065727671791482748659900060639926963022005424305428598384096201045285103243110012385503647750757013115954608677386233978142224494513680866630913236076316930192686744226921983870965664346251492074685634583531334565997695428546882772894918870424603926033309071559111059501203642333,6451721584690521069581901111974092204654122587875579916279551744658661205413364185368986076832511568929170794843492990781144450828332965740817648161987976580582338126230945095334678085775013660661642032765404588316501300352495628863315640949745573214882043885532409624351786399389352651138436910377540588715,364800994330757396882653090957020494991186585063682233319677342832051344502776958834410035811370111943816463424448302716551318762170472662165419035921367121365358358160571142517808605560056227966869017916492144933000445349984077920674346135535102210585266868874844995392794923436866721883251932973852604825116
|
||||
10023667082494025533694458923906062911614808800770741660171152481026059347510371753561616097379084784341713671154750835715019868680624888814365226032644794597463378220681171484265152741451558871527205613714299617780955377578029153710181790009777505367079339560569389236075705577562497976407198835496123421815,8237178824212969139758302266371465433903111044341794615829413365403141507594223080352356455683475273814082845524013102162873125179530876016035628585832833134556337909718743386830931466874558092486241907311137385119488677802975754525714977343935483066353264879509528297193753064624793968877384112576484389591,423224971588853021692214116546653537988666116441804013450094782696541031203993989512468938158606185066216192664407632356213925851579704646681338385590758369803509256824915492724160624602987883926813515751341908451718832678074898298694978135986894313441355375932022035725661361883088309484290780962315557040384|10023667082494025533694458923906062911614808800770741660171152481026059347510371753561616097379084784341713671154750835715019868680624888814365226032644794597463378220681171484265152741451558871527205613714299617780955377578029153710181790009777505367079339560569389236075705577562497976407198835496123421815,8237178824212969139758302266371465433903111044341794615829413365403141507594223080352356455683475273814082845524013102162873125179530876016035628585832833134556337909718743386830931466874558092486241907311137385119488677802975754525714977343935483066353264879509528297193753064624793968877384112576484389591,423224971588853021692214116546653537988666116441804013450094782696541031203993989512468938158606185066216192664407632356213925851579704646681338385590758369803509256824915492724160624602987883926813515751341908451718832678074898298694978135986894313441355375932022035725661361883088309484290780962315557040384|26149581659024134542252839056088737943459101230098434304929833472689045273647101980834416767117184344850968739815058973073425320764635194473778310753733774870500611744687135320440722493629102059325894273417025541554717397282491317870553755571826770905575804901409545560793682652830798005534542887045797606186,-1697969983698485305905454448895722929114256960413081228420951351866600414430800217182268923658152076765210118720420817273440690524435493363475828642615467592516719174944772197605654745416391960101282581330420264887754748587983051609045080004443224578293135292425351561632174977350140009380537152490928076887,161609629862554141142708472275797044218689904367615056614920333643328937851927686237891781051003871507296405842898237370248243352582987628460341700892139196626441792037632328670727659225186548971653052724874684965299456515833967561157293186033533538079205556741150926459475886439855496878616457828726831550112
|
||||
10023862893594232582190646068648463209940952006884955056666263414474264317722655546318247009455771884983355234222787422801894657323776793269825967901010897328305149754199815134059038386803327107954623997783328925014573712361190412041544730846393144970158584993932522919092961533807689663994273510181230611975,-2760322820547873699921094239708262618123220686640344280427532457964735913231839541155448488755106353058077772483391926518490758309421884945189004380274532339303673658136307214150768559915038249044318636340829040623019533080008795877188365713108541851533478868182315253939354465782006188226272150540248455533,539774532098344028178575637715654362402942864818067869426574212334581836029933543954242820122684669884416483020859433711413498388105161261765872011520166122694643001745601237406507189268543940858796801993814111596277340371144355358041455940732653675597524992815557778776692308187755956982584432604519599405036|10023862893594232582190646068648463209940952006884955056666263414474264317722655546318247009455771884983355234222787422801894657323776793269825967901010897328305149754199815134059038386803327107954623997783328925014573712361190412041544730846393144970158584993932522919092961533807689663994273510181230611975,-2760322820547873699921094239708262618123220686640344280427532457964735913231839541155448488755106353058077772483391926518490758309421884945189004380274532339303673658136307214150768559915038249044318636340829040623019533080008795877188365713108541851533478868182315253939354465782006188226272150540248455533,539774532098344028178575637715654362402942864818067869426574212334581836029933543954242820122684669884416483020859433711413498388105161261765872011520166122694643001745601237406507189268543940858796801993814111596277340371144355358041455940732653675597524992815557778776692308187755956982584432604519599405036|48715243603698629821940426961114291788526831094737919680655564244368028434506892148169445801801507062147482077938401141271200004998443292904217897448972538551776558146708202066192286102689914350481841990540885514221263570815029978710961611989482704700171591369852446182654047272669614885074291437285365544460,15461979039278362276597154663342472093520340953601325231902305531667625678747495978358134272949704300055117324152966543774546452680787464009096008897144630532639259858616922948118805845884304673520502690819270668894425836172912196918903901652212033563796089034742441883378992888990103186375633458530164516317,112254170401540486949707124025758283679636240637378289192656933481574624585762302045534446659987957789349537165930984237831795400327841686426067814232036082567083362372524941094990583657803451112651533845361102072607539347050570081691100018981326399925221570110823787216043908322347678600920061436414622205345
|
||||
10024289314253109068181408824584907548682813194738591861732979563130066037537322274697443177137048505246344585833979570630525401656305713560413859208020518275537432959569499157916033857588787751319126726484190263493857704290501320067515311770609186057345956871152108834406551727855172143151298819670712846606,250504711193651543885319560950205973661493792695329060474635142907355144915197487552594082031949875905008463463563678142215091936373578313885813322111597330162926418717728507984924427400756505737871837782137693463723537653383553918621336520844369928180694979696895523967764933497235970432812594037072497051,715621301200572432492975207084152505969843326949635795107806123209445143151718517449817068713936125495042559248838811939558778417894618132276860461288711015473626724568542195567695133648202437411311798035098899324593482673311597084169133485553033610858821471717692594066324611630669968328053616507731719142856|10024289314253109068181408824584907548682813194738591861732979563130066037537322274697443177137048505246344585833979570630525401656305713560413859208020518275537432959569499157916033857588787751319126726484190263493857704290501320067515311770609186057345956871152108834406551727855172143151298819670712846606,250504711193651543885319560950205973661493792695329060474635142907355144915197487552594082031949875905008463463563678142215091936373578313885813322111597330162926418717728507984924427400756505737871837782137693463723537653383553918621336520844369928180694979696895523967764933497235970432812594037072497051,715621301200572432492975207084152505969843326949635795107806123209445143151718517449817068713936125495042559248838811939558778417894618132276860461288711015473626724568542195567695133648202437411311798035098899324593482673311597084169133485553033610858821471717692594066324611630669968328053616507731719142856|69691918841176288984823797473901681196094628879675315489755259444998436434953893357490252440851727841764856894926617359858762775119043951866997363697297297444653923770370354552225052699848341814307273549886449783549055935119439453155817735871573060612568620074695549908654214345458834165261842993120064731877,29396998803244259208706324369693841135210373137766178345587378836957006029896347992580130862460199303906902776177861781944189386331882004200746161097147483839158568813322086972498062377955537624817737605600339132204987534032119897113967273038860438816060235575010015500174845850861550917579850703027368690837,106032740697299793989572674990101926746114173477172287236417937947154096127701068054351010022541808717403069236123423199088480578855329299917113038220143550055260783011691574203288951873393089140671443554631887510834797278656898859315134431047639142121497581377857339388563046962362704012299890107532747273864
|
||||
10025428900225290685290151690469854982214932916715816521705584076773008242243937008766386881454192668460673460928145859037221457715710934570710912601758825277917537132977601878466722300639421318388444709119075347515835153260761313907776418189378977092187686581753209864749194659254262457796167519362282389944,8035407417908027120985682166291560102987169154314800046344974577695327891178900017914738842677039490694291401465931876496716613929624358740551659992744919248664062419629947961043318471204322567520912143542047278378993142962380418872588429956261466474640589358106914252999077869082097127384356318300378316515,526506212965607285294504652802203087863317784238837123201810456971631654056439372780456787465506517550858742170829690899565417756124817089047569475165769047941621936008499130409010932902058625548248971355379292220521819976269615165269965092960486278068237861168382524126578791019346639264332649030378056985183|10025428900225290685290151690469854982214932916715816521705584076773008242243937008766386881454192668460673460928145859037221457715710934570710912601758825277917537132977601878466722300639421318388444709119075347515835153260761313907776418189378977092187686581753209864749194659254262457796167519362282389944,8035407417908027120985682166291560102987169154314800046344974577695327891178900017914738842677039490694291401465931876496716613929624358740551659992744919248664062419629947961043318471204322567520912143542047278378993142962380418872588429956261466474640589358106914252999077869082097127384356318300378316515,526506212965607285294504652802203087863317784238837123201810456971631654056439372780456787465506517550858742170829690899565417756124817089047569475165769047941621936008499130409010932902058625548248971355379292220521819976269615165269965092960486278068237861168382524126578791019346639264332649030378056985183|22138319840700167895312881508181272807615611642960031764554010440709354488166777949391350577243475719290294812551529754345491786841502661934416467056115565617682227037416000132315258676326832664293472268496755124942179527934459542753167413348749025306046598965185451619481594689484505194124705909904529437016,-11131863740438194145696527360624732907005872365618169777307266620259512556501908857842536958655885195096195748687569086057992329814846073549253878495916056982261048696264863065937434987201822416655310303356962123778695372607503843603636308900759414300401601767853289915741229529512784406304245742359645877437,239100722014735247362237833086276623512072741916888955896402203382427372194255695065669877432592987292352301916479402236621014870053157629159394772682571609781590319296070407875820019520943129073048256367075297134176669670916790346961022995994025660850270895833918044332478002360056773821184240475743476227793
|
||||
10025696373056081323076067608649787757301021243808185859274808349280293058956119916709251366791092102112010300737183625444037192198725817688527600134257833611989912831501342672141015848343142445555687647450237725473967806277927764282835935236016323094913726640542283793306041765928288192544236949963888652742,-7551573577419239436071851881922105087510160439185121186338107875456959549550841973546977393389532111591614312842887678906809652876632858754122403767673808362967953534249136664179536748454994677273595591516700421480181975305574013927943181245218443636797391029556909610245497977668952560989113626530355626403,488551202347944315504020596344859283372184958565644254623325222360870646703286196267475027122265755221917465236349901297478448862017138325309245093096937651510172757567584161967211867376922683411877153052678659984267061266457787269417246896692832538104568250487618601354692837088103049130077128213591142309282|10025696373056081323076067608649787757301021243808185859274808349280293058956119916709251366791092102112010300737183625444037192198725817688527600134257833611989912831501342672141015848343142445555687647450237725473967806277927764282835935236016323094913726640542283793306041765928288192544236949963888652742,-7551573577419239436071851881922105087510160439185121186338107875456959549550841973546977393389532111591614312842887678906809652876632858754122403767673808362967953534249136664179536748454994677273595591516700421480181975305574013927943181245218443636797391029556909610245497977668952560989113626530355626403,488551202347944315504020596344859283372184958565644254623325222360870646703286196267475027122265755221917465236349901297478448862017138325309245093096937651510172757567584161967211867376922683411877153052678659984267061266457787269417246896692832538104568250487618601354692837088103049130077128213591142309282|60393031392510595353689024388979736338459176869905458858711562614756995826747740419365757994707737913997543366818386810567166008495382740947599739430340534765458717365457600414802742877973222192406990314478073640352910084093417199594859293029865969059185936671473103965892459853411850141569702842003428649274,38329753573953857590669151489102652306888210200689056278625104334993443543324622863340848043537460677248162565965074671978338401303611611484783137870568580776992301362308417714890643838644524909137849140837295996399799637901901974938629017550061052634048860038885099946489697555545683915123490961748882032563,86948805727102164020528697795654924433436758890959241635759391106001442581272485956111792521204085749386969011988358799013634480122996757146530322550896381169828204152724081141046858586814946327125019525970600049950459272456428386457599502469581747116784271717706447744628609754739530433937342398267975398266
|
||||
10025795277027889904587708106143218928217212795791943900096455901045016119560329143219194735847213817310006544292588010221295347093799623990992065640705758739633420740707391553060038825197435786302291280814741597987499076013530747593280825513696921556065232738339683658383829389180388637941998690144811369597,5684979695119467447669475199616030835217750876317308626399899267476547529035287916782085067945907170746605510283861183133612038067129245932165458949837306805149633974813244043762392619755476811530088171886491397765159164208502011381649757076514242464099478526057069033992519207091422655970324739132300656901,562007444349085595243678168150362315344210015071199683818344834829191775432825810670825147187078104135705553739701002486305372357596398874560795249464367016590567012959728033251032467564115881230202627660086530992291649152268041406000599974523312325932278194132351429623587227242904398909856612628818780435778|10025795277027889904587708106143218928217212795791943900096455901045016119560329143219194735847213817310006544292588010221295347093799623990992065640705758739633420740707391553060038825197435786302291280814741597987499076013530747593280825513696921556065232738339683658383829389180388637941998690144811369597,5684979695119467447669475199616030835217750876317308626399899267476547529035287916782085067945907170746605510283861183133612038067129245932165458949837306805149633974813244043762392619755476811530088171886491397765159164208502011381649757076514242464099478526057069033992519207091422655970324739132300656901,562007444349085595243678168150362315344210015071199683818344834829191775432825810670825147187078104135705553739701002486305372357596398874560795249464367016590567012959728033251032467564115881230202627660086530992291649152268041406000599974523312325932278194132351429623587227242904398909856612628818780435778|21268893649707309919570226960346372728495718162766890279898665692070832053021527941744710318344298178920800948932846738089018664772788493927580517099544523821251022066659574678369202749060209753445042621950578890219002532761197990179516522502045501310564866950615799259252489912339574839719060814022687315833,-16974163508967143175633640446755920949410222455507178592573412674696095005693865169009177473634493301741992193686041205183814819978515841920175784743689108590732720018205453159865088935842801461210617037675036778351747079803439546961298001090840400908639940207556458714733757110771041917290102952953525885901,267927541659497862467954399158595317217757334505550228883969422271210761133505257969057962914766286654857630940214532971487737583736851759345565614399969808206018020458924660929875641469250964043761370010683938550578868703713683401770700995854517531350144574746588257756156838858326386968013405064043171677102
|
||||
10027231464587935675639730747678568553908782143975994882531107664457436183429164280181747996889942331170488347016005448660418260392761004178712470722876674735769717730721096608074660784751458654872470573207263246635112395824536847938300087322544843942058256547417838850894365569811278659238183569174057618461,-4440267082761131414853294025879558077404333378765096794740543986499915534978609296838455472705453725784503668845242671918380807204902116758601260037461056825902249629220350908043324356588944839161111532952326818438147003761862650635018374512533491039199092599100710336766544058009407418500582600655649176731,648644865497954786776779349508457974872894617589720812073415733603605246322174185807123848556285887617844905639166726609275182111944451202589938026255239735903760010573449137429043799240258539000988138770732321918291392488327546867698375214486961050410251228096630089455328472100573545758827677160537099320072|10027231464587935675639730747678568553908782143975994882531107664457436183429164280181747996889942331170488347016005448660418260392761004178712470722876674735769717730721096608074660784751458654872470573207263246635112395824536847938300087322544843942058256547417838850894365569811278659238183569174057618461,-4440267082761131414853294025879558077404333378765096794740543986499915534978609296838455472705453725784503668845242671918380807204902116758601260037461056825902249629220350908043324356588944839161111532952326818438147003761862650635018374512533491039199092599100710336766544058009407418500582600655649176731,648644865497954786776779349508457974872894617589720812073415733603605246322174185807123848556285887617844905639166726609275182111944451202589938026255239735903760010573449137429043799240258539000988138770732321918291392488327546867698375214486961050410251228096630089455328472100573545758827677160537099320072|46009921711915221172675762660378602913284935911769009327398886576025556944392570855250807675821524214292205195685897041743100957229886916848065466280285331142834500895832407569582736664860239313946858454701727263963934792933919730548918244937925570913918752904708052633399310307728141781833372082621654521012,23113475896105025107394605331889841460333790037514477610982037645403180016015663190091781841332002225731097821541822074963875072814544317858697958764287783670995655541483455486482934375887626558700537105583870368524253911345190227270218382103667348149461739557925536602713765457923023851021682724701425292285,144158936962616263074854848511540730235089365933518189341717329619972562457005307870230026030935456404849352326770086269924745439466300887545713518178631945541398236558781981355199214433550895067837895099984050382102279411033270720567051341019780619857285120976043103941344405749600962507460384488305160927409
|
||||
10028350739307738239553437040783010537831658077620987335136512740169676263676747904072610524038617826531776850363823183733316438383606013506243196250082245650509414494066287488240898643357609392647649696817421880362011995934355791054933802156008906495889209763185641418699747996844644309107005112769042124318,-8707724909729199988066303291337645249173793540898282778024990496827621579508639942367666079187451324678862416133361451354021503910330702173658524643590899178624105480074443491370735876152164927759833250717689047284841393067105491783984924710355073809596596309834373465404107419929383484013294580151001556205,709758849546988349416271112886481225556022674837057904210411294800853958134290458192748393663317224087035819308413648727887254453418237510262143014913358121419251454923066768843049946946235581252429358021933518874438830803109875124372809973223871915099838973789742920465584130081571378073407884375094121268086|75318449301263415467735932548665333631833209464496019863964846786179367552717568503501179580307848690931127517090493242442668414948431300766436151276701082711193885234526326365772794857402011587084042826807831628195071551088506032974178171732912459672450935320336391563419572190330442739927553072512433668492,-37666884930926310053453757600840503983118095033807980727340808659295811653448510252245931091899049389573453471548035871058367468721695376360491358764096189091201995027259909431928638716214539254513869701208949761595174662474754859884399931318260163661631099379190898913272807941135716989109599181870658955411,98959195118263740892956000993748226884659367220332828268929254332674345256309662055166848715197441404549693155497652798902798133883715701424760429622411156195661335500009744018343869593442437677434882815576040667549098187431048868332096738149061496080175268157896224795266747997461998351291015430290846127991|78879828918733154172761232408717349879484411577276118445906917725867063887736403698268620449039366903222875325557071665537210036919488537356651491469585633888702020869953229589162929365722510146484615161939420331780149558523973332122378453822513488024388432239153051455307708434618917487055946350509115159954,76022832032228931560745697540761625684085285731069434889900171934534714627230254695020398894919788417337545845925550378316932977023401785630385785258013781974664129868656557307645950862628223235191878262315897562597443878541677560567949780990105397727409041603839660905756066382442879369790583798789010488305,108311876812780092185464248430819211209817518273155531596997245418001592611818208219323720419932959536655772814492616252593108875759365327114882816039706034356112007450695439375062874008822159624139628714241658551452565287963490475631456873365249553095821106476912177956653681222238113836907581862856535718737
|
||||
10028851844651833483859929571953137249991455639548429827963027247884276614126582614765754168788406967864569784762670102265610798647378386836840906226432130520069813697908016956233348000504802826879321612396642793367212498698674853695626535119160503473498038239103440516242421347929877540717111105756485685416,2125595786027029524418010744012416366895751257304333344547068089057782417304598028459234751630103098379533864111162338454453990302791615035666668646880454521909199231924063610130346480860493194786475025500179927152042631414216166076205706865335089506746163544867373884186074330874303125032398057106297186863,800913161978634698742609378449357774955505407483415355913501780948951093468088505693408572348493350961801168010893237963412292289122055848739177106855852125098292236006510856110523212361731635197072591774393685461794786770421350652687522647241859653967881884006552182286419954577117744245767788677817306762852|50429916262905224121199165505326103712322633321578675412441680250060233972857110270845245669993781820897616267433177701631160063889458653764653687193369398981186203131244488744056545097485284912257268749768458331368107477031080466529105477483573960360042156349879055924595032652993263006931935621163071940669,-27065457947223595691396496360583757525811978893552969421355220262690251856919447274985744020030753772138102799000695707517100290349316439468276434701083568894717249805760937039437729313480400330251378090593495078991541936054800615447964857892934462412215184000258243195317080477356913381022045983896051265339,162884360410278142867611075754290453359699000687335791914852080089316910769333692647979960993562595617317591055325367385753910502341805589561432506963888415490402296553372275035046411345233183682360113909981999769321373626395576042577426393704313732652524189312065702142816306042456646293512481995292218184630|53997723292458827021420578276444072896002053124414909531202213558828743141566632795132611868503445251027453958158504792518315802051451653007369750551307662332396699632827748059470875485288011830316694909885816703989889585271656952405885761371722676008299809654786389827849524552375005490619782071967768476620,-3921961296864439599504210025762424797468664702267290731411285739993844771294339132594454147684650522033462891630908841344585194018116919380259122700777039543903609394837238783496880317096351827072103366260798880944073390853134441762823497871536553346031444078137460262118850735234076150428857645894786599751,148801743068668131617014767083337764289837422117725728166091414005082627848729316116752646484455568027336119364510594603975358934000097718262611755893849397982664596027513725455266261222215386005085253076887565120162601272630243587251846986242350641739720550891898677287459766121608903079025422071040317411427
|
||||
10029389724354647916501896404393742667486460299990236556418317010668116357688170330436730152626311842309710400719826928488284825527027730454134618086311842571929328216480439284941404499751921093227604323134474990591797348436817566328316099817073417778247297081309102907064789976846493401165211794614652077581,-5748548483444797737722189452249937786310843486604864328602367281135708748614533947090219774019556230317272055169227525539578087511031078860820692360107715435130140444616499305586047090927584090418666083007681585523416727535418733837425822999564006750813702161869964846496575730545650729911357481033875975819,719895727819428792994563756994341424767785889195228293344753744212732679301708252203825226413012156273021174986595157595824763180256881701588113889797640827369987995936500880423386237711358833858185065722206691788564039408747808726964665919487597212670306097386648373066512338291830265434985728533154609458396|10029389724354647916501896404393742667486460299990236556418317010668116357688170330436730152626311842309710400719826928488284825527027730454134618086311842571929328216480439284941404499751921093227604323134474990591797348436817566328316099817073417778247297081309102907064789976846493401165211794614652077581,-5748548483444797737722189452249937786310843486604864328602367281135708748614533947090219774019556230317272055169227525539578087511031078860820692360107715435130140444616499305586047090927584090418666083007681585523416727535418733837425822999564006750813702161869964846496575730545650729911357481033875975819,719895727819428792994563756994341424767785889195228293344753744212732679301708252203825226413012156273021174986595157595824763180256881701588113889797640827369987995936500880423386237711358833858185065722206691788564039408747808726964665919487597212670306097386648373066512338291830265434985728533154609458396|8560998041202342563145796199673331908087223591151890019844277290088279806853407215903188817680041281745686724901293662893322531582604865370359246593736212994518909947445852055733198112706083016676348016714291995623917124402224705247934604030962953619706293397331305385867121828720733169551586472433525366937,-537975643989974344334263003423538768209474800355518283566587248897859525466409192148505701554962331296631250873445941844817525452815362174465113061273994639614043454341045805645253425898526417994404807933232055819444976823823121190979410608683098711316112363065614462414343124780847750195760827288806749811,842416466225224033183393216850362224780744722633748075411867357471068659147784175969996596348967969848559647034288532517371764252498077837862667546193299637156461175039504339023851201930547252305821527420041035325847162633397442876512610187216200063222815713605031344575281997919080197584636819283493689893368
|
||||
10029462828108406279939177067115161395010840703955688660855251935920272008672857135011101256731718086932191566776707625465927083826902687987460773347952918706606341231446896979494902183159052228641287627294356517943283997224691515527031637969828335115038316970291491432668820800917926368076854280638205187309,-6629646230072911423556297764360629625589965368903862583111147478898388162363395818084398589541887766856708633717083099875720612184669212924373539095145308857941719336023981955297255371765324592355503775749174475673743444341624220885937903545914339945102711106579165895756968511409705213351719512183267438507,782742743661597372172423816386424221021017552503284524697466177183281891845425353410464186233869636520966594583971179297268228166989165546064661406781232750204176842910595282543729669785450570724055031796400642778914378223882150571438409693254554219540729724954243581265311980228274664427499269984624348473720|10029462828108406279939177067115161395010840703955688660855251935920272008672857135011101256731718086932191566776707625465927083826902687987460773347952918706606341231446896979494902183159052228641287627294356517943283997224691515527031637969828335115038316970291491432668820800917926368076854280638205187309,-6629646230072911423556297764360629625589965368903862583111147478898388162363395818084398589541887766856708633717083099875720612184669212924373539095145308857941719336023981955297255371765324592355503775749174475673743444341624220885937903545914339945102711106579165895756968511409705213351719512183267438507,782742743661597372172423816386424221021017552503284524697466177183281891845425353410464186233869636520966594583971179297268228166989165546064661406781232750204176842910595282543729669785450570724055031796400642778914378223882150571438409693254554219540729724954243581265311980228274664427499269984624348473720|78667156036256111077611624900655903416490936286908879028793529978954307476546731244382117972535629204391216663640753691624585098486838208251820032478479477157140644001833697695041181016581251701307504852404041540782811897181398727717806959310986773271700555774873273014053192416692372242335858566589217791557,-11681938670990905592355073596188490162953864508666802257304897456361955348551384361326321552281799532866414312577544184561189074950098884814900830627703536569755802878449922371901033061871486784064588452214883192668082672979794267084922475962025561930112420060063420934779749780994794637529679089941387143427,100087743332058471063169855843669770171915090829420561680411008586982501053400685795132793033729482971332564612241450018617179058547543051543609602249472699027915450803902552375241387388609502154707845080333148480015751381946173697011349301767118798190494650916047348538729674905622316757245591467381527471900
|
46
crates/vdf/Cargo.toml
Normal file
46
crates/vdf/Cargo.toml
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright 2018 POA Networks Ltd.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# and limitations under the License.
|
||||
[package]
|
||||
name = "vdf"
|
||||
version = "0.1.0"
|
||||
authors = ["Demi M. Obenour <demiobenour@gmail.com>"]
|
||||
readme = "README.md"
|
||||
keywords = ["vdf", "classgroup", "crypto", "cryptography"]
|
||||
repository = "https://github.com/poanetwork/vdf"
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
description = "An implementation of Verifiable Delay Functions (VDFs) in Rust"
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "staticlib"]
|
||||
name = "vdf"
|
||||
|
||||
[dependencies]
|
||||
classgroup = { path = "../classgroup", version = "^0.1.0" }
|
||||
num-traits = "0.2"
|
||||
sha2 = "0.8"
|
||||
bit-vec = "0.5"
|
||||
uniffi = { version= "0.25", features = ["cli"]}
|
||||
|
||||
[build-dependencies]
|
||||
uniffi = { version = "0.25", features = [ "build" ] }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = ">=0.2"
|
||||
hex = "0.3"
|
||||
|
||||
[[bench]]
|
||||
name = "classgroup-bench"
|
||||
harness = false
|
||||
path = "bench/bench.rs"
|
223
crates/vdf/README.md
Normal file
223
crates/vdf/README.md
Normal file
@ -0,0 +1,223 @@
|
||||
# Verifiable Delay Function (VDF) Implementation in Rust
|
||||
|
||||
## What is a VDF?
|
||||
|
||||
A Verifiable Delay Function (VDF) is a function that requires substantial time
|
||||
to evaluate (even with a polynomial number of parallel processors) but can be
|
||||
very quickly verified as correct. VDFs can be used to construct randomness
|
||||
beacons with multiple applications in a distributed network environment. By
|
||||
introducing a time delay during evaluation, VDFs prevent malicious actors from
|
||||
influencing output. The output cannot be differentiated from a random number
|
||||
until the final result is computed. See <https://eprint.iacr.org/2018/712.pdf>
|
||||
for more details.
|
||||
|
||||
## Description
|
||||
|
||||
This VDF implementation is written in Rust. The GMP library is used for
|
||||
arithmetic and greatest common divisor (GCD) calculations. We use class groups
|
||||
to implement the approaches described in the following papers:
|
||||
|
||||
1. [Simple Verifiable Delay Functions](https://eprint.iacr.org/2018/627.pdf). Pietrzak, 2018
|
||||
2. [Efficient Verifiable Delay Functions](https://eprint.iacr.org/2018/623.pdf). Wesolowski, 2018
|
||||
|
||||
The chosen generator is (2, 1, c), where c is calculated from the provided
|
||||
discriminant. A form is represented internally (a, b, c), with the
|
||||
discriminant not being used in most omputations. This implementation performs
|
||||
reduction is performed after every multiplication and squaring, as not doing so
|
||||
did not give any gains in our benchmarks.
|
||||
|
||||
|
||||
This repo includes three crates:
|
||||
|
||||
* `classgroup`: a class group implementation, as well as a trait for class
|
||||
groups.
|
||||
* `vdf`: a Verifyable Delay Function (VDF) trait, as well as an
|
||||
implementation of that trait.
|
||||
* `vdf-cli`: a command-line interface to the vdf crate. It also includes
|
||||
additional commands, which are deprecated and will be replaced by a CLI to
|
||||
the classgroup crate.
|
||||
|
||||
## Usage
|
||||
|
||||
- Install [Rust]. We (POA Networks) have tested the code with the latest
|
||||
stable, beta, and nightly versions of Rust. It may work with older
|
||||
versions, but this is not guaranteed.
|
||||
- Install the [GNU Multiple Precision Library](https://gmplib.org/)
|
||||
* On Debian and derivatives (including Ubuntu):
|
||||
```sh
|
||||
$ sudo apt-get install -y libgmp-dev
|
||||
```
|
||||
* On Red Hat and derivatives (Fedora, CentOS)
|
||||
```sh
|
||||
$ sudo dnf -y install gmp-devel
|
||||
```
|
||||
- Download and prepare the repository
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/poanetwork/vdf.git
|
||||
$ cargo install --path=vdf-cli
|
||||
$ # or for the competition binary
|
||||
$ cargo install --path=vdf-competition
|
||||
```
|
||||
|
||||
### Command Line Interface
|
||||
|
||||
To initiate, use the `vdf-cli` command followed by 2 arguments:
|
||||
|
||||
- _challenge_: byte string of arbitrary length
|
||||
- _difficulty_: number of iterations, each iteration requires more time to evaluate
|
||||
|
||||
This generates the Weslowski proof of time. To generate the Pietrzak proof of
|
||||
time, pass `-tpietrzak`. For detailed usage information, run `vdf-cli --help`.
|
||||
|
||||
Once complete you will see the output, returned as a `Vec<u8>`. The CLI tool
|
||||
hex-encodes its output.
|
||||
|
||||
**Example**
|
||||
|
||||
```sh
|
||||
$ vdf-cli aa 100
|
||||
005271e8f9ab2eb8a2906e851dfcb5542e4173f016b85e29d481a108dc82ed3b3f97937b7aa824801138d1771dea8dae2f6397e76a80613afda30f2c30a34b040baaafe76d5707d68689193e5d211833b372a6a4591abb88e2e7f2f5a5ec818b5707b86b8b2c495ca1581c179168509e3593f9a16879620a4dc4e907df452e8dd0ffc4f199825f54ec70472cc061f22eb54c48d6aa5af3ea375a392ac77294e2d955dde1d102ae2ace494293492d31cff21944a8bcb4608993065c9a00292e8d3f4604e7465b4eeefb494f5bea102db343bb61c5a15c7bdf288206885c130fa1f2d86bf5e4634fdc4216bc16ef7dac970b0ee46d69416f9a9acee651d158ac64915b
|
||||
```
|
||||
|
||||
To verify, use the `vdi-cli` command with the same arguments and include the
|
||||
output.
|
||||
|
||||
**Example**
|
||||
|
||||
```sh
|
||||
$ vdf-cli aa 100 005271e8f9ab2eb8a2906e851dfcb5542e4173f016b85e29d481a108dc82ed3b3f97937b7aa824801138d1771dea8dae2f6397e76a80613afda30f2c30a34b040baaafe76d5707d68689193e5d211833b372a6a4591abb88e2e7f2f5a5ec818b5707b86b8b2c495ca1581c179168509e3593f9a16879620a4dc4e907df452e8dd0ffc4f199825f54ec70472cc061f22eb54c48d6aa5af3ea375a392ac77294e2d955dde1d102ae2ace494293492d31cff21944a8bcb4608993065c9a00292e8d3f4604e7465b4eeefb494f5bea102db343bb61c5a15c7bdf288206885c130fa1f2d86bf5e4634fdc4216bc16ef7dac970b0ee46d69416f9a9acee651d158ac64915b
|
||||
Proof is valid
|
||||
```
|
||||
### VDF Library
|
||||
|
||||
<!--
|
||||
Keep as is, and possibly include argument explanations as well (for byte_length for example). May not be needed though is CLI is main user interaction tool.
|
||||
-->
|
||||
|
||||
```rust
|
||||
extern crate vdf;
|
||||
use vdf::{InvalidProof, PietrzakVDFParams, VDFParams, WesolowskiVDFParams, VDF};
|
||||
|
||||
/// The correct solution.
|
||||
const CORRECT_SOLUTION: &[u8] =
|
||||
b"\x00\x52\x71\xe8\xf9\xab\x2e\xb8\xa2\x90\x6e\x85\x1d\xfc\xb5\x54\x2e\x41\x73\xf0\x16\
|
||||
\xb8\x5e\x29\xd4\x81\xa1\x08\xdc\x82\xed\x3b\x3f\x97\x93\x7b\x7a\xa8\x24\x80\x11\x38\
|
||||
\xd1\x77\x1d\xea\x8d\xae\x2f\x63\x97\xe7\x6a\x80\x61\x3a\xfd\xa3\x0f\x2c\x30\xa3\x4b\
|
||||
\x04\x0b\xaa\xaf\xe7\x6d\x57\x07\xd6\x86\x89\x19\x3e\x5d\x21\x18\x33\xb3\x72\xa6\xa4\
|
||||
\x59\x1a\xbb\x88\xe2\xe7\xf2\xf5\xa5\xec\x81\x8b\x57\x07\xb8\x6b\x8b\x2c\x49\x5c\xa1\
|
||||
\x58\x1c\x17\x91\x68\x50\x9e\x35\x93\xf9\xa1\x68\x79\x62\x0a\x4d\xc4\xe9\x07\xdf\x45\
|
||||
\x2e\x8d\xd0\xff\xc4\xf1\x99\x82\x5f\x54\xec\x70\x47\x2c\xc0\x61\xf2\x2e\xb5\x4c\x48\
|
||||
\xd6\xaa\x5a\xf3\xea\x37\x5a\x39\x2a\xc7\x72\x94\xe2\xd9\x55\xdd\xe1\xd1\x02\xae\x2a\
|
||||
\xce\x49\x42\x93\x49\x2d\x31\xcf\xf2\x19\x44\xa8\xbc\xb4\x60\x89\x93\x06\x5c\x9a\x00\
|
||||
\x29\x2e\x8d\x3f\x46\x04\xe7\x46\x5b\x4e\xee\xfb\x49\x4f\x5b\xea\x10\x2d\xb3\x43\xbb\
|
||||
\x61\xc5\xa1\x5c\x7b\xdf\x28\x82\x06\x88\x5c\x13\x0f\xa1\xf2\xd8\x6b\xf5\xe4\x63\x4f\
|
||||
\xdc\x42\x16\xbc\x16\xef\x7d\xac\x97\x0b\x0e\xe4\x6d\x69\x41\x6f\x9a\x9a\xce\xe6\x51\
|
||||
\xd1\x58\xac\x64\x91\x5b";
|
||||
fn main() {
|
||||
// The length of the prime numbers generated, in bits.
|
||||
let num_bits: u16 = 2048;
|
||||
|
||||
// An instance of the VDF. Instances can be used arbitrarily many times.
|
||||
let pietrzak_vdf = PietrzakVDFParams(num_bits).new();
|
||||
|
||||
// Solve for the correct answer. This will take a minute or two.
|
||||
assert_eq!(
|
||||
&pietrzak_vdf.solve(b"\xaa", 10000).unwrap()[..],
|
||||
CORRECT_SOLUTION
|
||||
);
|
||||
|
||||
// Verify the answer. This should be far faster (less than a second).
|
||||
assert!(pietrzak_vdf.verify(b"\xaa", 10000, CORRECT_SOLUTION).is_ok());
|
||||
}
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Benchmarks are provided for the classgroup operations. To run benchmarks:
|
||||
|
||||
```sh
|
||||
$ ./bench.sh <your challenge here>
|
||||
```
|
||||
|
||||
Additional benchmarks are under development.
|
||||
|
||||
### Current Benchmarks
|
||||
|
||||
These were generated by `./bench.sh aadf`. Outliers could be due to preemption
|
||||
by the OS and/or hypervisor. Changes are relative to the previous test run
|
||||
done on the same machine. Since the previous run was done with different
|
||||
settings and/or code than reported here, these changes are not meaningful.
|
||||
|
||||
```text
|
||||
Benchmarking square with seed aadf: 512: Collecting 100 samples in estimated 5.0439 s (374k iteratio square with seed aadf: 512
|
||||
time: [13.301 us 13.333 us 13.372 us]
|
||||
change: [-22.286% -21.745% -21.225%] (p = 0.00 < 0.05)
|
||||
Performance has improved.
|
||||
Found 22 outliers among 100 measurements (22.00%)
|
||||
5 (5.00%) high mild
|
||||
17 (17.00%) high severe
|
||||
|
||||
Benchmarking multiply with seed aadf: 512: Collecting 100 samples in estimated 5.0452 s (293k iterat multiply with seed aadf: 512
|
||||
time: [17.219 us 17.251 us 17.287 us]
|
||||
change: [-24.323% -23.739% -23.149%] (p = 0.00 < 0.05)
|
||||
Performance has improved.
|
||||
Found 10 outliers among 100 measurements (10.00%)
|
||||
4 (4.00%) high mild
|
||||
6 (6.00%) high severe
|
||||
|
||||
Benchmarking square with seed aadf: 1024: Collecting 100 samples in estimated 5.0822 s (177k iterati square with seed aadf: 1024
|
||||
time: [28.672 us 28.716 us 28.767 us]
|
||||
change: [-29.947% -29.339% -28.708%] (p = 0.00 < 0.05)
|
||||
Performance has improved.
|
||||
Found 8 outliers among 100 measurements (8.00%)
|
||||
1 (1.00%) low mild
|
||||
1 (1.00%) high mild
|
||||
6 (6.00%) high severe
|
||||
|
||||
Benchmarking multiply with seed aadf: 1024: Collecting 100 samples in estimated 5.0886 s (136k itera multiply with seed aadf: 1024
|
||||
time: [37.163 us 37.207 us 37.254 us]
|
||||
change: [-21.403% -20.750% -20.170%] (p = 0.00 < 0.05)
|
||||
Performance has improved.
|
||||
Found 8 outliers among 100 measurements (8.00%)
|
||||
1 (1.00%) low mild
|
||||
1 (1.00%) high mild
|
||||
6 (6.00%) high severe
|
||||
|
||||
Benchmarking square with seed aadf: 2048: Collecting 100 samples in estimated 5.2519 s (76k iteratio square with seed aadf: 2048
|
||||
time: [69.115 us 69.254 us 69.430 us]
|
||||
change: [-28.091% -27.738% -27.341%] (p = 0.00 < 0.05)
|
||||
Performance has improved.
|
||||
Found 8 outliers among 100 measurements (8.00%)
|
||||
1 (1.00%) low mild
|
||||
1 (1.00%) high mild
|
||||
6 (6.00%) high severe
|
||||
|
||||
Benchmarking multiply with seed aadf: 2048: Collecting 100 samples in estimated 5.0554 s (56k iterat multiply with seed aadf: 2048
|
||||
time: [90.922 us 91.057 us 91.201 us]
|
||||
change: [-25.236% -24.794% -24.336%] (p = 0.00 < 0.05)
|
||||
Performance has improved.
|
||||
Found 13 outliers among 100 measurements (13.00%)
|
||||
2 (2.00%) low mild
|
||||
5 (5.00%) high mild
|
||||
6 (6.00%) high severe
|
||||
```
|
||||
|
||||
[Rust]: <https://doc.rust-lang.org/cargo/getting-started/installation.html>
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
<http://www.apache.org/licenses/LICENSE-2.0>
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
54
crates/vdf/bench/bench.rs
Normal file
54
crates/vdf/bench/bench.rs
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2018 POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#[macro_use]
|
||||
extern crate criterion;
|
||||
|
||||
use hex;
|
||||
|
||||
use classgroup::{gmp_classgroup::GmpClassGroup, ClassGroup};
|
||||
use criterion::Criterion;
|
||||
use std::{cell::RefCell, env, rc::Rc};
|
||||
use vdf::create_discriminant;
|
||||
fn bench_square(c: &mut Criterion) {
|
||||
let bench_params = |c: &mut Criterion, len: u16, seed: &[u8]| {
|
||||
let i = Rc::new(RefCell::new(GmpClassGroup::generator_for_discriminant(
|
||||
create_discriminant(seed, len),
|
||||
)));
|
||||
{
|
||||
let i = i.clone();
|
||||
c.bench_function(
|
||||
&format!("square with seed {}: {}", hex::encode(seed), len),
|
||||
move |b| b.iter(|| i.borrow_mut().square()),
|
||||
);
|
||||
}
|
||||
{
|
||||
let multiplier = i.borrow().clone();
|
||||
c.bench_function(
|
||||
&format!("multiply with seed {}: {}", hex::encode(seed), len),
|
||||
move |b| b.iter(|| *i.borrow_mut() *= &multiplier),
|
||||
);
|
||||
}
|
||||
};
|
||||
let seed = env::var("VDF_BENCHMARK_SEED")
|
||||
.ok()
|
||||
.and_then(|x| hex::decode(x).ok())
|
||||
.expect("bug in calling script");
|
||||
for &i in &[512, 1024, 2048] {
|
||||
bench_params(c, i, &seed)
|
||||
}
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_square);
|
||||
criterion_main!(benches);
|
115
crates/vdf/build.rs
Normal file
115
crates/vdf/build.rs
Normal file
@ -0,0 +1,115 @@
|
||||
// Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use std::{env, fs::File, io::Write, path::PathBuf, u16};
|
||||
|
||||
/// The number of odd primes less than 65536.
|
||||
const PRIMES_LEN: usize = 6541;
|
||||
|
||||
/// The number of integers that are:
|
||||
///
|
||||
/// * equal to 7 mod 8
|
||||
/// * not divisible by any prime number less than or equal to 13.
|
||||
/// * less than 8 * 3 * 5 * 7 * 11 * 13
|
||||
const RESIDUES_LEN: usize = 5760;
|
||||
|
||||
/// The number of odd prime numbers between 13 and 65536 exclusive.
|
||||
const SIEVE_INFO_LEN: usize = PRIMES_LEN - 5;
|
||||
|
||||
fn odd_primes_below_65536() -> Vec<usize> {
|
||||
const N: usize = 1 << 16;
|
||||
let mut sieve = vec![true; N >> 1];
|
||||
let mut q = (N as f64).powf(0.5) as usize;
|
||||
assert!(q * q <= N);
|
||||
q += 1;
|
||||
assert!(q * q > N);
|
||||
for i in (3..q).step_by(2) {
|
||||
if sieve[i >> 1] {
|
||||
for i in ((i * i >> 1)..sieve.len()).step_by(i) {
|
||||
sieve[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// mega cheat ― we know the exact size of this vector
|
||||
let res: Vec<_> = (1..N / 2)
|
||||
.filter(|&i| sieve[i])
|
||||
.map(|i| 2 * i + 1)
|
||||
.collect();
|
||||
assert_eq!(res.len(), PRIMES_LEN);
|
||||
res
|
||||
}
|
||||
|
||||
fn mod_exponentiation(base: usize, exponent: usize, modulus: usize) -> usize {
|
||||
assert!(base < u16::MAX.into());
|
||||
assert!(exponent < u16::MAX.into());
|
||||
assert!(modulus < u16::MAX.into());
|
||||
let (mut base, mut exponent, modulus) = (base as u32, exponent as u32, modulus as u32);
|
||||
let mut state = 1;
|
||||
loop {
|
||||
if exponent & 1 != 0 {
|
||||
state *= base;
|
||||
state %= modulus;
|
||||
}
|
||||
exponent >>= 1;
|
||||
if exponent == 0 {
|
||||
return state as _;
|
||||
}
|
||||
base *= base;
|
||||
base %= modulus;
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! const_fmt {
|
||||
() => {
|
||||
"#[allow(warnings)]\nconst {}: [{}; {}] = {:#?};\n\n";
|
||||
};
|
||||
}
|
||||
|
||||
/// A product of many small prime numbers. We precompute the numbers between
|
||||
/// `1` and `M` that are coprime to `M`. Any number whose residue modulo `M` is
|
||||
/// one of these is not divisible by any of the prime factors of `M`. This
|
||||
/// speeds up the generation of random prime numbers.
|
||||
const M: usize = 8 * 3 * 5 * 7 * 11 * 13;
|
||||
fn emit<T: std::fmt::Debug>(f: &mut dyn Write, name: &str, t: &str, obj: &[T]) {
|
||||
write!(f, const_fmt!(), name, t, obj.len(), obj).expect("i/o error in build script");
|
||||
}
|
||||
|
||||
/// Write the generated code to `f`.
|
||||
fn generate(f: &mut dyn Write) {
|
||||
write!(f, "const M: u32 = 8 * 3 * 5 * 7 * 11 * 13;\n\n").expect("i/o error");
|
||||
let residues: Vec<usize> = {
|
||||
let primes = [3, 5, 7, 11, 13];
|
||||
let not_divisible = |&x: &usize| primes.iter().all(|p| x % p != 0);
|
||||
(7..M).step_by(8).filter(not_divisible).collect()
|
||||
};
|
||||
assert_eq!(residues.len(), RESIDUES_LEN);
|
||||
emit(f, "RESIDUES", "u32", &residues[..]);
|
||||
let sieve_info: Vec<(usize, usize)> = odd_primes_below_65536()[5..]
|
||||
.iter()
|
||||
.map(|&i| (i, mod_exponentiation(M % i, i - 2, i)))
|
||||
.collect();
|
||||
assert_eq!(sieve_info.len(), SIEVE_INFO_LEN);
|
||||
emit(f, "SIEVE_INFO", "(u16, u16)", &sieve_info[..]);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
uniffi::generate_scaffolding("src/lib.udl").expect("uniffi generation failed");
|
||||
|
||||
let manifest_path = env::var("OUT_DIR").expect("cargo should have set this");
|
||||
let mut path = PathBuf::from(&manifest_path);
|
||||
path.push("constants.rs");
|
||||
let mut f = File::create(path).expect("cannot create constants.rs");
|
||||
generate(&mut f);
|
||||
}
|
199
crates/vdf/src/create_discriminant.rs
Normal file
199
crates/vdf/src/create_discriminant.rs
Normal file
@ -0,0 +1,199 @@
|
||||
// Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Creation of discriminants.
|
||||
//!
|
||||
//! The [`pot`] tool does not accept a discriminant as a command-line argument.
|
||||
//! Instead, we generate the discriminant from a (much smaller) seed.
|
||||
//!
|
||||
//! For performance, we follow the Chia network's [`inkfish`] implementation
|
||||
//! of ["Close to Uniform Prime Number Generation With Fewer Random Bits"][1]
|
||||
//! by Pierre-Alain Fouque and Mehdi Tibouchi.
|
||||
//! We employ a table of precomputed constants generated by `build.rs`.
|
||||
//!
|
||||
//! [1]: https://eprint.iacr.org/2011/481.pdf
|
||||
//! [`inkfish`]: <https://github.com/Chia-Network/vdf-competition/blob/003b0d202d3b27058159f7a3f6a838e312e7d79e/inkfish/create_discriminant.py>
|
||||
//! [`pot`]: <https://github.com/Chia-Network/vdf-competition/blob/003b0d202d3b27058159f7a3f6a838e312e7d79e/inkfish/cmds.py>
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/constants.rs"));
|
||||
|
||||
use classgroup::BigNumExt;
|
||||
use num_traits::Zero;
|
||||
use sha2::{digest::FixedOutput, Digest, Sha256};
|
||||
use std::u16;
|
||||
|
||||
fn random_bytes_from_seed(seed: &[u8], byte_count: usize) -> Vec<u8> {
|
||||
assert!(byte_count <= 32 * ((1 << 16) - 1));
|
||||
let mut blob = Vec::with_capacity(byte_count);
|
||||
let mut extra: u16 = 0;
|
||||
while blob.len() < byte_count {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.input(seed);
|
||||
let extra_bits: [u8; 2] = [((extra & 0xFF00) >> 8) as _, (extra & 0xFF) as _];
|
||||
hasher.input(&extra_bits);
|
||||
blob.extend_from_slice(&hasher.fixed_result()[..]);
|
||||
extra += 1;
|
||||
}
|
||||
blob.resize(byte_count, 0);
|
||||
blob
|
||||
}
|
||||
|
||||
/// Create a discriminant from a seed (a byte string) and a bit length (a
|
||||
/// `u16`). The discriminant is guaranteed to be a negative prime number that
|
||||
/// fits in `length` bits, except with negligible probability (less than
|
||||
/// 2^(-100)). It is also guaranteed to equal 7 modulo 8.
|
||||
///
|
||||
/// This function uses sha256 to expand the seed. Therefore, different seeds
|
||||
/// will result in completely different discriminants with overwhelming
|
||||
/// probability, unless `length` is very small. However, this function is
|
||||
/// deterministic: if it is called twice with identical seeds and lengths, it
|
||||
/// will always return the same discriminant.
|
||||
///
|
||||
/// This function is guaranteed not to panic for any inputs whatsoever, unless
|
||||
/// memory allocation fails and the allocator in use panics in that case.
|
||||
pub fn create_discriminant<T: BigNumExt>(seed: &[u8], length: u16) -> T {
|
||||
let (mut n, residue) = {
|
||||
// The number of “extra” bits (that don’t evenly fit in a byte)
|
||||
let extra: u8 = (length as u8) & 7;
|
||||
|
||||
// The number of random bytes needed (the number of bytes that hold `length`
|
||||
// bits, plus 2).
|
||||
let random_bytes_len = ((usize::from(length) + 7) >> 3) + 2;
|
||||
let random_bytes = random_bytes_from_seed(seed, random_bytes_len);
|
||||
let (n, last_2) = random_bytes.split_at(random_bytes_len - 2);
|
||||
let numerator = (usize::from(last_2[0]) << 8) + usize::from(last_2[1]);
|
||||
|
||||
// If there are any extra bits, right shift `n` so that it fits
|
||||
// in `length` bits, discarding the least significant bits.
|
||||
let n = T::from(n) >> usize::from((8 - extra) & 7);
|
||||
(n, RESIDUES[numerator % RESIDUES.len()])
|
||||
};
|
||||
n.setbit(usize::from(length - 1));
|
||||
debug_assert!(n >= Zero::zero());
|
||||
let rem = n.frem_u32(M);
|
||||
|
||||
// HACK HACK `rust-gmp` doesn’t expose += and -= with i32 or i64
|
||||
if residue > rem {
|
||||
n = n + u64::from(residue - rem);
|
||||
} else {
|
||||
n = n - u64::from(rem - residue);
|
||||
}
|
||||
debug_assert!(n >= Zero::zero());
|
||||
|
||||
// This generates the smallest prime ≥ n that is of the form n + m*x.
|
||||
loop {
|
||||
// Speed up prime-finding by quickly ruling out numbers
|
||||
// that are known to be composite.
|
||||
let mut sieve = ::bit_vec::BitVec::from_elem(1 << 16, false);
|
||||
for &(p, q) in SIEVE_INFO.iter() {
|
||||
// The reference implementation changes the sign of `n` before taking its
|
||||
// remainder. Instead, we leave `n` as positive, but use ceiling
|
||||
// division instead of floor division. This is mathematically
|
||||
// equivalent and potentially faster.
|
||||
let mut i: usize = (n.crem_u16(p) as usize * q as usize) % p as usize;
|
||||
while i < sieve.len() {
|
||||
sieve.set(i, true);
|
||||
i += p as usize;
|
||||
}
|
||||
}
|
||||
|
||||
for (i, x) in sieve.iter().enumerate() {
|
||||
if !x {
|
||||
let q = u64::from(M) * u64::from(i as u32);
|
||||
n = n + q;
|
||||
if n.probab_prime(1) {
|
||||
return -n;
|
||||
}
|
||||
n = n - q;
|
||||
}
|
||||
}
|
||||
// M is set to a number with many prime factors so the results are
|
||||
// more uniform https://eprint.iacr.org/2011/481.pdf
|
||||
// TODO: Explain previous reference to https://eprint.iacr.org/2011/401.pdf
|
||||
n = n + (u64::from(M) * (1 << 16)) as u64
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use classgroup::{gmp_classgroup::GmpClassGroup, ClassGroup};
|
||||
type Mpz = <GmpClassGroup as ClassGroup>::BigNum;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn check_discriminant_1() {
|
||||
assert_eq!(
|
||||
create_discriminant::<Mpz>(b"\xaa", 40),
|
||||
(-685_537_176_559i64).into()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_discriminant_3() {
|
||||
assert_eq!(
|
||||
create_discriminant::<Mpz>(b"\xaa", 1024),
|
||||
Mpz::from_str(
|
||||
"-112084717443890964296630631725167420667316836131914185144761\
|
||||
7438378168250988242739496385274308134767869324152361453294226\
|
||||
8295868231081182819214054220080323345750407342623884342617809\
|
||||
8794592117225058677336074005099949757067786815439982423354682\
|
||||
0386024058617141397148586038290164093146862666602485017735298\
|
||||
03183"
|
||||
)
|
||||
.unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_discriminant_2() {
|
||||
assert_eq!(
|
||||
create_discriminant::<Mpz>(b"\xaa", 2048),
|
||||
-Mpz::from_str(
|
||||
"201493927071865251625903550712920535753645598483515670853547009\
|
||||
878440933309489362800393797428711071833308081461824159206915864\
|
||||
150805748296170245037221957772328044276705571745811271212292422\
|
||||
075849739248257870371300001313586036515879618764093772248760562\
|
||||
386804073478433157526816295216137723803793411828867470089409596\
|
||||
238958950007370719325959579892866588928887249912429688364409867\
|
||||
895510817680171869190054122881274299350947669820596157115994418\
|
||||
034091728887584373727555384075665624624856766441009974642693066\
|
||||
751400054217209981490667208950669417773785631693879782993019167\
|
||||
69407006303085854796535778826115224633447713584423"
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn check_random_bytes() {
|
||||
assert_eq!(
|
||||
&random_bytes_from_seed(b"\xaa", 7),
|
||||
b"\x9f\x9d*\xe5\xe7<\xcb"
|
||||
);
|
||||
assert_eq!(
|
||||
&random_bytes_from_seed(b"\xaa", 258)[..],
|
||||
&b"\x9f\x9d*\xe5\xe7<\xcbq\xa4q\x8e\
|
||||
\xbc\xf0\xe3:\xa2\x98\xf8\xbd\xdc\xaa\xcbi\xcb\x10\xff\x0e\xafv\xdb\xec!\xc4K\
|
||||
\xc6Jf\xf3\xa5\xda.7\xb7\xef\x87I\x85\xb8YX\xfc\xf2\x03\xa1\x8f4\xaf`\xab\xae]n\
|
||||
\xcc,g1\x12EI\xc7\xd5\xe2\xfc\x8b\x9a\xde\xd5\xf3\x8f'\xcd\x08\x0fU\xc7\xee\xa85\
|
||||
[>\x87]\x07\x82\x00\x13\xce\xf7\xc3/@\xef\x08v\x8f\x85\x87dm(1\x8b\xd9w\xffA]xzY\
|
||||
\xa0,\xebz\xff\x03$`\x91\xb66\x88-_\xa9\xf1\xc5\x8e,\x15\xae\x8f\x04\rvhnU3f\x84\
|
||||
[{$\xa6l\x95w\xa9\x1f\xba\xa8)\x05\xe6\x8f\x167o\x11/X\x9cl\xab\x9c\xcb}\xec\x88\
|
||||
\xf8\xa5\xabXpY\xb0\x88\xed@r\x05\xba\\\x03\xf6\x91\xf8\x03\xca\x18\x1c\xcdH\x1c\
|
||||
\x91\xe1V\xed;\x94oJ\xa8 \xa4\x97\xb7K\xce\xc4e\xea\xa2\xbf\x8b\x1f\x90\x87\xc8\
|
||||
\x15\xee\x0e\x0fPC:\xb5\xe1g\x97\xea/_\x86c\xaf\x12Wp\xfd\x11\xdb\x17\xe6\x9f\
|
||||
\xa5\x8a"[..]
|
||||
);
|
||||
}
|
||||
}
|
261
crates/vdf/src/lib.rs
Normal file
261
crates/vdf/src/lib.rs
Normal file
@ -0,0 +1,261 @@
|
||||
// Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#![deny(warnings)]
|
||||
//! # Rust implementations of class groups and verifyable delay functions
|
||||
//!
|
||||
//! This repo includes three crates
|
||||
//!
|
||||
//! * `classgroup`, which includes a class group implementation, as well as a
|
||||
//! trait for class groups.
|
||||
//! * `vdf`, which includes a Verifyable Delay Function (VDF) trait, as well as
|
||||
//! an implementation of that trait.
|
||||
//! * `vdf-cli`, which includes a command-line interface to the `vdf` crate. It
|
||||
//! also includes additional commands, which are deprecated and will later be
|
||||
//! replaced by a CLI to the `classgroup` crate.
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! First, install Rust, Cargo, and the GNU Multiprecision Library (GMP). Then,
|
||||
//! follow one of the below steps.
|
||||
//!
|
||||
//! ### To use the command line interface
|
||||
//!
|
||||
//! ```sh
|
||||
//! $ git clone https://github.com/poanetwork/vdf
|
||||
//! $ cd vdf
|
||||
//! $ cargo install
|
||||
//! $ vdf-cli aa 100
|
||||
//! 005271e8f9ab2eb8a2906e851dfcb5542e4173f016b85e29d481a108dc82ed3b3f97937b7aa824801138d1771dea8dae2f6397e76a80613afda30f2c30a34b040baaafe76d5707d68689193e5d211833b372a6a4591abb88e2e7f2f5a5ec818b5707b86b8b2c495ca1581c179168509e3593f9a16879620a4dc4e907df452e8dd0ffc4f199825f54ec70472cc061f22eb54c48d6aa5af3ea375a392ac77294e2d955dde1d102ae2ace494293492d31cff21944a8bcb4608993065c9a00292e8d3f4604e7465b4eeefb494f5bea102db343bb61c5a15c7bdf288206885c130fa1f2d86bf5e4634fdc4216bc16ef7dac970b0ee46d69416f9a9acee651d158ac64915b
|
||||
//! $ vdf-cli aa 100 005271e8f9ab2eb8a2906e851dfcb5542e4173f016b85e29d481a108dc82ed3b3f97937b7aa824801138d1771dea8dae2f6397e76a80613afda30f2c30a34b040baaafe76d5707d68689193e5d211833b372a6a4591abb88e2e7f2f5a5ec818b5707b86b8b2c495ca1581c179168509e3593f9a16879620a4dc4e907df452e8dd0ffc4f199825f54ec70472cc061f22eb54c48d6aa5af3ea375a392ac77294e2d955dde1d102ae2ace494293492d31cff21944a8bcb4608993065c9a00292e8d3f4604e7465b4eeefb494f5bea102db343bb61c5a15c7bdf288206885c130fa1f2d86bf5e4634fdc4216bc16ef7dac970b0ee46d69416f9a9acee651d158ac64915b
|
||||
//! Proof is valid
|
||||
//! ```
|
||||
//!
|
||||
//! ### To use the VDF library
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate vdf;
|
||||
//! use vdf::{InvalidProof, PietrzakVDFParams, VDFParams, WesolowskiVDFParams, VDF};
|
||||
//! const CORRECT_SOLUTION: &[u8] =
|
||||
//! b"\x00\x52\x71\xe8\xf9\xab\x2e\xb8\xa2\x90\x6e\x85\x1d\xfc\xb5\x54\x2e\x41\x73\xf0\x16\
|
||||
//! \xb8\x5e\x29\xd4\x81\xa1\x08\xdc\x82\xed\x3b\x3f\x97\x93\x7b\x7a\xa8\x24\x80\x11\x38\
|
||||
//! \xd1\x77\x1d\xea\x8d\xae\x2f\x63\x97\xe7\x6a\x80\x61\x3a\xfd\xa3\x0f\x2c\x30\xa3\x4b\
|
||||
//! \x04\x0b\xaa\xaf\xe7\x6d\x57\x07\xd6\x86\x89\x19\x3e\x5d\x21\x18\x33\xb3\x72\xa6\xa4\
|
||||
//! \x59\x1a\xbb\x88\xe2\xe7\xf2\xf5\xa5\xec\x81\x8b\x57\x07\xb8\x6b\x8b\x2c\x49\x5c\xa1\
|
||||
//! \x58\x1c\x17\x91\x68\x50\x9e\x35\x93\xf9\xa1\x68\x79\x62\x0a\x4d\xc4\xe9\x07\xdf\x45\
|
||||
//! \x2e\x8d\xd0\xff\xc4\xf1\x99\x82\x5f\x54\xec\x70\x47\x2c\xc0\x61\xf2\x2e\xb5\x4c\x48\
|
||||
//! \xd6\xaa\x5a\xf3\xea\x37\x5a\x39\x2a\xc7\x72\x94\xe2\xd9\x55\xdd\xe1\xd1\x02\xae\x2a\
|
||||
//! \xce\x49\x42\x93\x49\x2d\x31\xcf\xf2\x19\x44\xa8\xbc\xb4\x60\x89\x93\x06\x5c\x9a\x00\
|
||||
//! \x29\x2e\x8d\x3f\x46\x04\xe7\x46\x5b\x4e\xee\xfb\x49\x4f\x5b\xea\x10\x2d\xb3\x43\xbb\
|
||||
//! \x61\xc5\xa1\x5c\x7b\xdf\x28\x82\x06\x88\x5c\x13\x0f\xa1\xf2\xd8\x6b\xf5\xe4\x63\x4f\
|
||||
//! \xdc\x42\x16\xbc\x16\xef\x7d\xac\x97\x0b\x0e\xe4\x6d\x69\x41\x6f\x9a\x9a\xce\xe6\x51\
|
||||
//! \xd1\x58\xac\x64\x91\x5b";
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let pietrzak_vdf = PietrzakVDFParams(2048).new();
|
||||
//! assert_eq!(
|
||||
//! &pietrzak_vdf.solve(b"\xaa", 100).unwrap()[..],
|
||||
//! CORRECT_SOLUTION
|
||||
//! );
|
||||
//! assert!(pietrzak_vdf.verify(b"\xaa", 100, CORRECT_SOLUTION).is_ok());
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ### To run the benchmarks
|
||||
//!
|
||||
//! Benchmarks are provided for the classgroup operations. Run `cargo bench`
|
||||
//! to run them. Additional benchmarks are under development.
|
||||
use classgroup;
|
||||
|
||||
mod create_discriminant;
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub use self::{
|
||||
create_discriminant::create_discriminant,
|
||||
proof_pietrzak::{PietrzakVDF, PietrzakVDFParams},
|
||||
proof_wesolowski::{WesolowskiVDF, WesolowskiVDFParams},
|
||||
};
|
||||
|
||||
/// Message used to report an internal miscalculation of serialization buffer
|
||||
/// sizes.
|
||||
const INCORRECT_BUFFER_SIZE: &str =
|
||||
"internal error: incorrect buffer size calculation (this is a bug)";
|
||||
|
||||
mod proof_of_time;
|
||||
mod proof_pietrzak;
|
||||
mod proof_wesolowski;
|
||||
|
||||
uniffi::include_scaffolding!("lib");
|
||||
|
||||
/// An empty struct indicating verification failure.
|
||||
///
|
||||
/// For security reasons, the functions that perform verification *do not*
|
||||
/// return any information on failure. Use `VDF::validate_params` to check if
|
||||
/// the parameters are correct.
|
||||
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct InvalidProof;
|
||||
|
||||
/// An error return indicating an invalid number of iterations. The string is a
|
||||
/// human-readable message describing the valid iterations. It should not be
|
||||
/// interpreted by programs.
|
||||
#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct InvalidIterations(String);
|
||||
|
||||
/// The type of VDF parameters.
|
||||
///
|
||||
/// Parameters represent public information that can be shared by all users
|
||||
/// of the protocol. As such, they must implement `Clone`, so that they can
|
||||
/// be duplicated. They also must implement `Send`, so that a parallel
|
||||
/// application can send them safely across threads.
|
||||
///
|
||||
/// The parameters *do not* include the difficulty level (usually an
|
||||
/// iteration count), since that can be separate for each invocation.
|
||||
///
|
||||
/// This must implement `Clone` and `Eq`.
|
||||
pub trait VDFParams: Clone + Eq {
|
||||
type VDF: VDF + Sized;
|
||||
|
||||
/// Creates an instance of this VDF from the given parameters.
|
||||
///
|
||||
/// # Performance
|
||||
///
|
||||
/// This method is expected to be fairly cheap. For example, it is okay if
|
||||
/// it allocates memory, but it should not perform expensive computations or
|
||||
/// I/O.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This method **MUST NOT** fail due to invalid values for `params`. Such
|
||||
/// errors should be checked by the factory functions for `Self::Params`.
|
||||
///
|
||||
/// This function **MAY** panic for other reasons. For example, it is
|
||||
/// allowed to panic if an allocation fails, or if a needed external library
|
||||
/// could not be dynamically loaded.
|
||||
fn new(self) -> Self::VDF;
|
||||
}
|
||||
|
||||
/// A Verifiable Delay Function (VDF).
|
||||
///
|
||||
/// VDFs are problems that require a certain amount of time to solve, even on a
|
||||
/// parallel machine, but can be validated much more easily.
|
||||
///
|
||||
/// While VDFs are considered to be cryptographic primitives, they generally do
|
||||
/// *not* operate on highly sensitive data. As such, implementers of this trait
|
||||
/// **do not** guarantee that they will be immune to side-channel attacks, and
|
||||
/// consumers of this trait **MUST NOT** expect this.
|
||||
///
|
||||
/// Instances of this trait are *not* expected to be `Sync`. This allows them
|
||||
/// to reuse allocations (such as scratch memory) accross invocations without
|
||||
/// the need for locking. However, they **MUST** be `Send` and `Clone`, so that
|
||||
/// consumers can duplicate them and send them across threads.
|
||||
pub trait VDF: Send + Debug {
|
||||
/// Solve an instance of this VDF, with challenge `challenge` and difficulty
|
||||
/// `difficulty`.
|
||||
///
|
||||
/// The output is to be returned in a `Vec<u8>`, so it can be stored to disk
|
||||
/// or sent over the network.
|
||||
///
|
||||
/// # Challenge format
|
||||
///
|
||||
/// The challenge is an opaque byte string of arbitrary length.
|
||||
/// Implementors **MUST NOT** make any assumptions about its contents,
|
||||
/// and **MUST** produce distinct outputs for distinct challenges
|
||||
/// (except with negiligible probability).
|
||||
///
|
||||
/// This can be most easily implemented by using the challenge as part of
|
||||
/// the input of a cryptographic hash function. The VDFs provided in this
|
||||
/// crate use this strategy.
|
||||
///
|
||||
/// The difficulty must be checked before performing any expensive
|
||||
/// computations.
|
||||
///
|
||||
/// Most applications will generate the challenge using a
|
||||
/// cryptographically-secure pseudorandom number generator, but implementors
|
||||
/// **MUST NOT** rely on this. In particular, this function must be secure
|
||||
/// even if `challenge` is chosen by an adversary. Excessive values for
|
||||
/// `difficulty` may cause excessive resource consumption, but must not
|
||||
/// create any other vulnerabilities.
|
||||
///
|
||||
/// # Complexity
|
||||
///
|
||||
/// The VDFs in this crate consume memory that does not depend on
|
||||
/// `difficulty`, and time linearly proportional to `difficulty`.
|
||||
/// Implementors of this trait should document the resource use.
|
||||
///
|
||||
/// # Purity
|
||||
///
|
||||
/// This method must have no side effects. In particular, it must be
|
||||
/// **deterministic**: it must always return the same output for the same
|
||||
/// inputs, except with negligible probability. Furthermore, while it may
|
||||
/// change `self` via interior mutability, such changes must not affect
|
||||
/// future calls to this method, `Self::check_difficulty`, or
|
||||
/// `Self::verify`. They *may* affect the `Debug` output.
|
||||
fn solve(&self, challenge: &[u8], difficulty: u64) -> Result<Vec<u8>, InvalidIterations>;
|
||||
|
||||
/// Check that the difficulty is valid.
|
||||
///
|
||||
/// This must return `Ok` if and only if `difficulty` is valid. Otherwise,
|
||||
/// it must return `Err`.
|
||||
///
|
||||
/// # Rationale
|
||||
///
|
||||
/// It would be more ideomatic Rust to use the type system to enforce that a
|
||||
/// difficulty has been validated before use. However, I (Demi) have not
|
||||
/// yet figured out an object-safe way to do so.
|
||||
fn check_difficulty(&self, difficulty: u64) -> Result<(), InvalidIterations>;
|
||||
|
||||
/// Verifies an alleged solution of this VDF, with challenge `challenge` and
|
||||
/// difficulty `difficulty`. Return `Ok(())` on success, or
|
||||
/// `Err(InvalidProof)` on failure.
|
||||
///
|
||||
/// This function *does not* return any extended error information for
|
||||
/// security reasons. To check that the difficulty is correct, call
|
||||
/// `Self::check_difficulty`.
|
||||
///
|
||||
/// # Uniqueness of valid solutions
|
||||
///
|
||||
/// For any `(challenge, difficulty)` tuple, there must be at most one
|
||||
/// `alleged_solution` (as measured by `Eq`) that causes this function to
|
||||
/// return `Ok(())`. If the difficulty is valid (as determined by
|
||||
/// `check_difficulty`), there must be exactly one such solution; otherwise,
|
||||
/// there must be none.
|
||||
///
|
||||
/// # Purity
|
||||
///
|
||||
/// This method must have no side effects. In particular, it must be
|
||||
/// **deterministic**: it must always return the same output for the same
|
||||
/// inputs. Furthermore, while it may change `self` via interior
|
||||
/// mutability, such changes must not affect future calls to this method,
|
||||
/// `Self::prove`, or `Self::check_difficulty`. Such changes **MAY** affect
|
||||
/// debugging output.
|
||||
fn verify(
|
||||
&self,
|
||||
challenge: &[u8],
|
||||
difficulty: u64,
|
||||
alleged_solution: &[u8],
|
||||
) -> Result<(), InvalidProof>;
|
||||
}
|
||||
|
||||
/// Solve and prove with the Wesolowski VDF using the given parameters.
|
||||
/// Outputs the concatenated solution and proof (in this order).
|
||||
pub fn wesolowski_solve(int_size_bits: u16, challenge: &[u8], difficulty: u32) -> Vec<u8> {
|
||||
let vdf = WesolowskiVDFParams(int_size_bits).new();
|
||||
vdf.solve(challenge, difficulty.into()).expect("invalid difficulty")
|
||||
}
|
||||
|
||||
/// Verify with the Wesolowski VDF using the given parameters.
|
||||
/// `alleged_solution` is the output of `wesolowski_solve`.
|
||||
pub fn wesolowski_verify(int_size_bits: u16, challenge: &[u8], difficulty: u32, alleged_solution: &[u8]) -> bool {
|
||||
let vdf = WesolowskiVDFParams(int_size_bits).new();
|
||||
vdf.verify(challenge, difficulty.into(), alleged_solution).is_ok()
|
||||
}
|
4
crates/vdf/src/lib.udl
Normal file
4
crates/vdf/src/lib.udl
Normal file
@ -0,0 +1,4 @@
|
||||
namespace vdf {
|
||||
sequence<u8> wesolowski_solve(u16 int_size_bits, [ByRef] sequence<u8> challenge, u32 difficulty);
|
||||
boolean wesolowski_verify(u16 int_size_bits, [ByRef] sequence<u8> challenge, u32 difficulty, [ByRef] sequence<u8> alleged_solution);
|
||||
};
|
88
crates/vdf/src/proof_of_time.rs
Normal file
88
crates/vdf/src/proof_of_time.rs
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use super::classgroup::ClassGroup;
|
||||
use std::{collections::HashMap, usize};
|
||||
|
||||
pub fn serialize<V: ClassGroup>(proof: &[V], y: &V, int_size_bits: usize) -> Vec<u8> {
|
||||
let proof_len = proof.len();
|
||||
let element_length = 2 * ((int_size_bits + 16) >> 4);
|
||||
let proof_len_in_bytes = (proof_len + 1) * element_length;
|
||||
let mut v = vec![0; proof_len_in_bytes];
|
||||
y.serialize(&mut v[0..element_length])
|
||||
.expect(super::INCORRECT_BUFFER_SIZE);
|
||||
for (index, group) in proof.iter().enumerate() {
|
||||
let offset = (index + 1) * element_length;
|
||||
group
|
||||
.serialize(&mut v[offset..offset + element_length])
|
||||
.expect(super::INCORRECT_BUFFER_SIZE)
|
||||
}
|
||||
v
|
||||
}
|
||||
pub fn deserialize_proof<T>(
|
||||
proof_blob: &[u8],
|
||||
discriminant: &T::BigNum,
|
||||
orig_length: usize,
|
||||
) -> Result<Vec<T>, ()>
|
||||
where
|
||||
T: ClassGroup,
|
||||
for<'a, 'b> &'a T: std::ops::Mul<&'b T, Output = T>,
|
||||
for<'a, 'b> &'a T::BigNum: std::ops::Mul<&'b T::BigNum, Output = T::BigNum>,
|
||||
{
|
||||
let length = T::size_in_bits(discriminant);
|
||||
if length > usize::MAX - 16 {
|
||||
return Err(());
|
||||
}
|
||||
let length = (length + 16) >> 4;
|
||||
if length == 0 {
|
||||
return Err(());
|
||||
}
|
||||
if orig_length != length {
|
||||
return Err(());
|
||||
}
|
||||
let length = length * 2;
|
||||
let proof_blob_length = proof_blob.len();
|
||||
let rem = proof_blob_length % length;
|
||||
if rem != 0 {
|
||||
return Err(());
|
||||
}
|
||||
let proof_len = proof_blob_length / length;
|
||||
let mut v = Vec::with_capacity(proof_len);
|
||||
for i in 0..proof_len {
|
||||
let offset = i * length;
|
||||
v.push(T::from_bytes(
|
||||
&proof_blob[offset..offset + length],
|
||||
discriminant.clone(),
|
||||
))
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
pub fn iterate_squarings<V, U>(mut x: V, powers_to_calculate: U) -> HashMap<u64, V>
|
||||
where
|
||||
V: ClassGroup,
|
||||
for<'a, 'b> &'a V: std::ops::Mul<&'b V, Output = V>,
|
||||
for<'a, 'b> &'a V::BigNum: std::ops::Mul<&'b V::BigNum, Output = V::BigNum>,
|
||||
U: Iterator<Item = u64>,
|
||||
{
|
||||
let mut powers_calculated = HashMap::new();
|
||||
let mut powers_to_calculate: Vec<u64> = powers_to_calculate.collect();
|
||||
powers_to_calculate.sort_unstable();
|
||||
let mut previous_power: u64 = 0;
|
||||
for ¤t_power in &powers_to_calculate {
|
||||
x.repeated_square(current_power - previous_power);
|
||||
powers_calculated.insert(current_power, x.clone());
|
||||
previous_power = current_power
|
||||
}
|
||||
powers_calculated
|
||||
}
|
466
crates/vdf/src/proof_pietrzak.rs
Normal file
466
crates/vdf/src/proof_pietrzak.rs
Normal file
@ -0,0 +1,466 @@
|
||||
// Copyright 2018 Chia Network Inc and POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use super::proof_of_time::{deserialize_proof, iterate_squarings, serialize};
|
||||
use classgroup::{gmp_classgroup::GmpClassGroup, BigNumExt, ClassGroup};
|
||||
use num_traits::{One, Zero};
|
||||
use std::{fmt, num::ParseIntError, ops::Index, str::FromStr, u64, usize};
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone, Debug)]
|
||||
pub struct Iterations(u64);
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Ord, PartialOrd, Copy, Clone, Debug)]
|
||||
pub enum InvalidIterations {
|
||||
OddNumber(u64),
|
||||
LessThan66(u64),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct ParseIterationsError {
|
||||
kind: Result<InvalidIterations, ParseIntError>,
|
||||
}
|
||||
|
||||
impl From<InvalidIterations> for ParseIterationsError {
|
||||
fn from(t: InvalidIterations) -> Self {
|
||||
Self { kind: Ok(t) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParseIntError> for ParseIterationsError {
|
||||
fn from(t: ParseIntError) -> Self {
|
||||
Self { kind: Err(t) }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for InvalidIterations {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
InvalidIterations::OddNumber(s) => {
|
||||
write!(f, "Pietrzak iterations must be an even number, not {}", s)
|
||||
}
|
||||
InvalidIterations::LessThan66(s) => write!(
|
||||
f,
|
||||
"Pietrzak proof-of-time must run for at least 66 iterations, not {}",
|
||||
s
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Iterations> for u64 {
|
||||
fn from(t: Iterations) -> u64 {
|
||||
t.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ParseIterationsError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.kind {
|
||||
Ok(ref q) => <InvalidIterations as fmt::Display>::fmt(q, f),
|
||||
Err(ref q) => <ParseIntError as fmt::Display>::fmt(q, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Iterations {
|
||||
type Err = ParseIterationsError;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Self::new(s.parse::<u64>().map_err(ParseIterationsError::from)?)
|
||||
.map_err(ParseIterationsError::from)
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterations {
|
||||
pub fn new<T: Into<u64>>(iterations: T) -> Result<Iterations, InvalidIterations> {
|
||||
let iterations = iterations.into();
|
||||
if iterations & 1 != 0 {
|
||||
Err(InvalidIterations::OddNumber(iterations))
|
||||
} else if iterations < 66 {
|
||||
Err(InvalidIterations::LessThan66(iterations))
|
||||
} else {
|
||||
Ok(Iterations(iterations))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Selects a reasonable choice of cache size.
|
||||
fn approximate_i(t: Iterations) -> u64 {
|
||||
let x: f64 = (((t.0 >> 1) as f64) / 8.) * 2.0f64.ln();
|
||||
let w = x.ln() - x.ln().ln() + 0.25;
|
||||
(w / (2. * 2.0f64.ln())).round() as _
|
||||
}
|
||||
|
||||
fn sum_combinations<'a, T: IntoIterator<Item = &'a u64>>(numbers: T) -> Vec<u64> {
|
||||
let mut combinations = vec![0];
|
||||
for i in numbers {
|
||||
let mut new_combinations = combinations.clone();
|
||||
for j in combinations {
|
||||
new_combinations.push(i + j)
|
||||
}
|
||||
combinations = new_combinations
|
||||
}
|
||||
combinations.remove(0);
|
||||
combinations
|
||||
}
|
||||
|
||||
fn cache_indices_for_count(t: Iterations) -> Vec<u64> {
|
||||
let i: u64 = approximate_i(t);
|
||||
let mut curr_t = t.0;
|
||||
let mut intermediate_ts = vec![];
|
||||
for _ in 0..i {
|
||||
curr_t >>= 1;
|
||||
intermediate_ts.push(curr_t);
|
||||
if curr_t & 1 != 0 {
|
||||
curr_t += 1
|
||||
}
|
||||
}
|
||||
let mut cache_indices = sum_combinations(&intermediate_ts);
|
||||
cache_indices.sort();
|
||||
cache_indices.push(t.0);
|
||||
cache_indices
|
||||
}
|
||||
|
||||
fn generate_r_value<T>(x: &T, y: &T, sqrt_mu: &T, int_size_bits: usize) -> T::BigNum
|
||||
where
|
||||
T: ClassGroup,
|
||||
for<'a, 'b> &'a T: std::ops::Mul<&'b T, Output = T>,
|
||||
for<'a, 'b> &'a T::BigNum: std::ops::Mul<&'b T::BigNum, Output = T::BigNum>,
|
||||
{
|
||||
use sha2::{digest::FixedOutput, Digest, Sha256};
|
||||
|
||||
let size = (int_size_bits + 16) >> 4;
|
||||
let mut v = Vec::with_capacity(size * 2);
|
||||
for _ in 0..size * 2 {
|
||||
v.push(0)
|
||||
}
|
||||
let mut hasher = Sha256::new();
|
||||
for i in &[&x, &y, &sqrt_mu] {
|
||||
i.serialize(&mut v).expect(super::INCORRECT_BUFFER_SIZE);
|
||||
hasher.input(&v);
|
||||
}
|
||||
let res = hasher.fixed_result();
|
||||
T::unsigned_deserialize_bignum(&res[..16])
|
||||
}
|
||||
|
||||
fn create_proof_of_time_pietrzak<T>(
|
||||
challenge: &[u8],
|
||||
iterations: Iterations,
|
||||
int_size_bits: u16,
|
||||
) -> Vec<u8>
|
||||
where
|
||||
T: ClassGroup,
|
||||
<T as ClassGroup>::BigNum: BigNumExt,
|
||||
for<'a, 'b> &'a T: std::ops::Mul<&'b T, Output = T>,
|
||||
for<'a, 'b> &'a T::BigNum: std::ops::Mul<&'b T::BigNum, Output = T::BigNum>,
|
||||
{
|
||||
let discriminant = super::create_discriminant::create_discriminant(&challenge, int_size_bits);
|
||||
let x = T::from_ab_discriminant(2.into(), 1.into(), discriminant);
|
||||
|
||||
let delta = 8;
|
||||
let powers_to_calculate = cache_indices_for_count(iterations);
|
||||
let powers = iterate_squarings(x.clone(), powers_to_calculate.iter().cloned());
|
||||
let proof: Vec<T> = generate_proof(
|
||||
x,
|
||||
iterations,
|
||||
delta,
|
||||
&powers,
|
||||
&generate_r_value,
|
||||
usize::from(int_size_bits),
|
||||
);
|
||||
serialize(
|
||||
&proof,
|
||||
&powers[&iterations.into()],
|
||||
usize::from(int_size_bits),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn check_proof_of_time_pietrzak<T>(
|
||||
challenge: &[u8],
|
||||
proof_blob: &[u8],
|
||||
iterations: u64,
|
||||
length_in_bits: u16,
|
||||
) -> Result<(), super::InvalidProof>
|
||||
where
|
||||
T: ClassGroup,
|
||||
T::BigNum: BigNumExt,
|
||||
for<'a, 'b> &'a T: std::ops::Mul<&'b T, Output = T>,
|
||||
for<'a, 'b> &'a T::BigNum: std::ops::Mul<&'b T::BigNum, Output = T::BigNum>,
|
||||
{
|
||||
let discriminant = super::create_discriminant::create_discriminant(&challenge, length_in_bits);
|
||||
let x = T::from_ab_discriminant(2.into(), 1.into(), discriminant);
|
||||
let iterations = Iterations::new(iterations).map_err(|_| super::InvalidProof)?;
|
||||
if usize::MAX - 16 < length_in_bits.into() {
|
||||
// Proof way too long.
|
||||
return Err(super::InvalidProof);
|
||||
}
|
||||
let length: usize = (usize::from(length_in_bits) + 16usize) >> 4;
|
||||
if proof_blob.len() < 2 * length {
|
||||
// Invalid length of proof
|
||||
return Err(super::InvalidProof);
|
||||
}
|
||||
let result_bytes = &proof_blob[..length * 2];
|
||||
let proof_bytes = &proof_blob[length * 2..];
|
||||
let discriminant = x.discriminant().clone();
|
||||
let proof =
|
||||
deserialize_proof(proof_bytes, &discriminant, length).map_err(|()| super::InvalidProof)?;
|
||||
let y = T::from_bytes(result_bytes, discriminant);
|
||||
verify_proof(
|
||||
&x,
|
||||
&y,
|
||||
proof,
|
||||
iterations,
|
||||
8,
|
||||
&generate_r_value,
|
||||
length_in_bits.into(),
|
||||
)
|
||||
.map_err(|()| super::InvalidProof)
|
||||
}
|
||||
|
||||
fn calculate_final_t(t: Iterations, delta: usize) -> u64 {
|
||||
let mut curr_t = t.0;
|
||||
let mut ts = vec![];
|
||||
while curr_t != 2 {
|
||||
ts.push(curr_t);
|
||||
curr_t >>= 1;
|
||||
if curr_t & 1 == 1 {
|
||||
curr_t += 1
|
||||
}
|
||||
}
|
||||
ts.push(2);
|
||||
ts.push(1);
|
||||
assert!(ts.len() >= delta);
|
||||
ts[ts.len() - delta]
|
||||
}
|
||||
|
||||
pub fn generate_proof<T, U, V>(
|
||||
x: V,
|
||||
iterations: Iterations,
|
||||
delta: usize,
|
||||
powers: &T,
|
||||
generate_r_value: &U,
|
||||
int_size_bits: usize,
|
||||
) -> Vec<V>
|
||||
where
|
||||
T: for<'a> Index<&'a u64, Output = V>,
|
||||
U: Fn(&V, &V, &V, usize) -> V::BigNum,
|
||||
V: ClassGroup,
|
||||
for<'a, 'b> &'a V: std::ops::Mul<&'b V, Output = V>,
|
||||
for<'a, 'b> &'a V::BigNum: std::ops::Mul<&'b V::BigNum, Output = V::BigNum>,
|
||||
{
|
||||
let identity = x.identity();
|
||||
let i = approximate_i(iterations);
|
||||
let mut mus = vec![];
|
||||
let mut rs: Vec<V::BigNum> = vec![];
|
||||
let mut x_p = vec![x];
|
||||
let mut curr_t = iterations.0;
|
||||
|
||||
let mut y_p = vec![powers[&curr_t].clone()];
|
||||
|
||||
let mut ts = vec![];
|
||||
|
||||
let final_t = calculate_final_t(iterations, delta);
|
||||
|
||||
let mut round_index = 0;
|
||||
while curr_t != final_t {
|
||||
assert_eq!(curr_t & 1, 0);
|
||||
let half_t = curr_t >> 1;
|
||||
ts.push(half_t);
|
||||
assert!(round_index < 63);
|
||||
let denominator: u64 = 1 << (round_index + 1);
|
||||
|
||||
mus.push(if round_index < i {
|
||||
let mut mu = identity.clone();
|
||||
for numerator in (1..denominator).step_by(2) {
|
||||
let num_bits = 62 - denominator.leading_zeros() as usize;
|
||||
let mut r_prod: V::BigNum = One::one();
|
||||
for b in (0..num_bits).rev() {
|
||||
if 0 == (numerator & (1 << (b + 1))) {
|
||||
r_prod *= &rs[num_bits - b - 1]
|
||||
}
|
||||
}
|
||||
let mut t_sum = half_t;
|
||||
for b in 0..num_bits {
|
||||
if 0 != (numerator & (1 << (b + 1))) {
|
||||
t_sum += ts[num_bits - b - 1]
|
||||
}
|
||||
}
|
||||
let mut power = powers[&t_sum].clone();
|
||||
power.pow(r_prod);
|
||||
mu *= &power;
|
||||
}
|
||||
mu
|
||||
} else {
|
||||
let mut mu = x_p.last().unwrap().clone();
|
||||
for _ in 0..half_t {
|
||||
mu *= &mu.clone()
|
||||
}
|
||||
mu
|
||||
});
|
||||
let mut mu: V = mus.last().unwrap().clone();
|
||||
let last_r: V::BigNum = generate_r_value(&x_p[0], &y_p[0], &mu, int_size_bits);
|
||||
assert!(last_r >= Zero::zero());
|
||||
rs.push(last_r.clone());
|
||||
{
|
||||
let mut last_x: V = x_p.last().unwrap().clone();
|
||||
last_x.pow(last_r.clone());
|
||||
last_x *= μ
|
||||
x_p.push(last_x);
|
||||
}
|
||||
mu.pow(last_r);
|
||||
mu *= y_p.last().unwrap();
|
||||
y_p.push(mu);
|
||||
curr_t >>= 1;
|
||||
if curr_t & 1 != 0 {
|
||||
curr_t += 1;
|
||||
y_p.last_mut().unwrap().square();
|
||||
}
|
||||
round_index += 1
|
||||
}
|
||||
if cfg!(debug_assertions) {
|
||||
let mut last_y = y_p.last().unwrap().clone();
|
||||
let mut last_x = x_p.last().unwrap().clone();
|
||||
let one: V::BigNum = 1u64.into();
|
||||
last_y.pow(one.clone());
|
||||
assert_eq!(last_y, y_p.last().unwrap().clone());
|
||||
last_x.pow(one << final_t as usize);
|
||||
}
|
||||
mus
|
||||
}
|
||||
|
||||
pub fn verify_proof<T, U, V>(
|
||||
x_initial: &V,
|
||||
y_initial: &V,
|
||||
proof: T,
|
||||
t: Iterations,
|
||||
delta: usize,
|
||||
generate_r_value: &U,
|
||||
int_size_bits: usize,
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
T: IntoIterator<Item = V>,
|
||||
U: Fn(&V, &V, &V, usize) -> V::BigNum,
|
||||
V: ClassGroup,
|
||||
for<'a, 'b> &'a V: std::ops::Mul<&'b V, Output = V>,
|
||||
for<'a, 'b> &'a V::BigNum: std::ops::Mul<&'b V::BigNum, Output = V::BigNum>,
|
||||
{
|
||||
let mut one: V::BigNum = One::one();
|
||||
let (mut x, mut y): (V, V) = (x_initial.clone(), y_initial.clone());
|
||||
let final_t = calculate_final_t(t, delta);
|
||||
let mut curr_t = t.0;
|
||||
for mut mu in proof {
|
||||
assert!(
|
||||
curr_t & 1 == 0,
|
||||
"Cannot have an odd number of iterations remaining"
|
||||
);
|
||||
let r = generate_r_value(x_initial, y_initial, &mu, int_size_bits);
|
||||
x.pow(r.clone());
|
||||
x *= μ
|
||||
mu.pow(r);
|
||||
y *= μ
|
||||
|
||||
curr_t >>= 1;
|
||||
if curr_t & 1 != 0 {
|
||||
curr_t += 1;
|
||||
y.square();
|
||||
}
|
||||
}
|
||||
one <<= final_t as _;
|
||||
x.pow(one);
|
||||
if x == y {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PietrzakVDF {
|
||||
int_size_bits: u16,
|
||||
}
|
||||
use super::InvalidIterations as Bad;
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct PietrzakVDFParams(pub u16);
|
||||
impl super::VDFParams for PietrzakVDFParams {
|
||||
type VDF = PietrzakVDF;
|
||||
fn new(self) -> Self::VDF {
|
||||
PietrzakVDF {
|
||||
int_size_bits: self.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::VDF for PietrzakVDF {
|
||||
fn check_difficulty(&self, difficulty: u64) -> Result<(), Bad> {
|
||||
Iterations::new(difficulty)
|
||||
.map_err(|x| Bad(format!("{}", x)))
|
||||
.map(drop)
|
||||
}
|
||||
fn solve(&self, challenge: &[u8], difficulty: u64) -> Result<Vec<u8>, Bad> {
|
||||
Ok(create_proof_of_time_pietrzak::<GmpClassGroup>(
|
||||
challenge,
|
||||
Iterations::new(difficulty).map_err(|x| Bad(format!("{}", x)))?,
|
||||
self.int_size_bits,
|
||||
))
|
||||
}
|
||||
|
||||
fn verify(
|
||||
&self,
|
||||
challenge: &[u8],
|
||||
difficulty: u64,
|
||||
alleged_solution: &[u8],
|
||||
) -> Result<(), super::InvalidProof> {
|
||||
check_proof_of_time_pietrzak::<GmpClassGroup>(
|
||||
challenge,
|
||||
alleged_solution,
|
||||
difficulty,
|
||||
self.int_size_bits,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn check_approximate_i() {
|
||||
assert_eq!(approximate_i(Iterations(534)), 2);
|
||||
assert_eq!(approximate_i(Iterations(134)), 1);
|
||||
assert_eq!(approximate_i(Iterations(1024)), 2);
|
||||
}
|
||||
#[test]
|
||||
fn check_cache_indices() {
|
||||
assert_eq!(cache_indices_for_count(Iterations(66))[..], [33, 66]);
|
||||
assert_eq!(
|
||||
cache_indices_for_count(Iterations(534))[..],
|
||||
[134, 267, 401, 534]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_calculate_final_t() {
|
||||
assert_eq!(calculate_final_t(Iterations(1024), 8), 128);
|
||||
assert_eq!(calculate_final_t(Iterations(1000), 8), 126);
|
||||
assert_eq!(calculate_final_t(Iterations(100), 8), 100);
|
||||
}
|
||||
#[test]
|
||||
fn check_assuptions_about_stdlib() {
|
||||
assert_eq!(62 - u64::leading_zeros(1024u64), 9);
|
||||
let mut q: Vec<_> = (1..4).step_by(2).collect();
|
||||
assert_eq!(q[..], [1, 3]);
|
||||
q = (1..3).step_by(2).collect();
|
||||
assert_eq!(q[..], [1]);
|
||||
q = (1..2).step_by(2).collect();
|
||||
assert_eq!(q[..], [1]);
|
||||
}
|
||||
}
|
316
crates/vdf/src/proof_wesolowski.rs
Normal file
316
crates/vdf/src/proof_wesolowski.rs
Normal file
@ -0,0 +1,316 @@
|
||||
// Copyright 2018 POA Networks Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use super::proof_of_time::{iterate_squarings, serialize};
|
||||
use classgroup::{gmp_classgroup::GmpClassGroup, BigNum, BigNumExt, ClassGroup};
|
||||
use sha2::{digest::FixedOutput, Digest, Sha256};
|
||||
use std::{cmp::Eq, collections::HashMap, hash::Hash, mem, u64, usize};
|
||||
use std::convert::TryInto;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WesolowskiVDF {
|
||||
int_size_bits: u16,
|
||||
}
|
||||
use super::InvalidIterations as Bad;
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub struct WesolowskiVDFParams(pub u16);
|
||||
impl super::VDFParams for WesolowskiVDFParams {
|
||||
type VDF = WesolowskiVDF;
|
||||
fn new(self) -> Self::VDF {
|
||||
WesolowskiVDF {
|
||||
int_size_bits: self.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::VDF for WesolowskiVDF {
|
||||
fn check_difficulty(&self, _difficulty: u64) -> Result<(), Bad> {
|
||||
Ok(())
|
||||
}
|
||||
fn solve(&self, challenge: &[u8], difficulty: u64) -> Result<Vec<u8>, Bad> {
|
||||
if difficulty > usize::MAX as u64 {
|
||||
Err(Bad("Cannot have more that usize::MAX iterations".to_owned()))
|
||||
} else {
|
||||
Ok(create_proof_of_time_wesolowski::<
|
||||
<GmpClassGroup as ClassGroup>::BigNum,
|
||||
GmpClassGroup,
|
||||
>(
|
||||
challenge, difficulty as usize, self.int_size_bits
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn verify(
|
||||
&self,
|
||||
challenge: &[u8],
|
||||
difficulty: u64,
|
||||
alleged_solution: &[u8],
|
||||
) -> Result<(), super::InvalidProof> {
|
||||
check_proof_of_time_wesolowski::<<GmpClassGroup as ClassGroup>::BigNum, GmpClassGroup>(
|
||||
challenge,
|
||||
alleged_solution,
|
||||
difficulty,
|
||||
self.int_size_bits,
|
||||
)
|
||||
.map_err(|()| super::InvalidProof)
|
||||
}
|
||||
}
|
||||
/// To quote the original Python code:
|
||||
///
|
||||
/// > Create `L` and `k` parameters from papers, based on how many iterations
|
||||
/// > need to be performed, and how much memory should be used.
|
||||
pub fn approximate_parameters(t: f64) -> (usize, u8, u64) {
|
||||
let log_memory = (10_000_000.0f64).log2();
|
||||
let log_t = (t as f64).log2();
|
||||
let l = if log_t - log_memory > 0. {
|
||||
2.0f64.powf(log_memory - 20.).ceil()
|
||||
} else {
|
||||
1.
|
||||
};
|
||||
|
||||
let intermediate = t * (2.0f64).ln() / (2.0 * l);
|
||||
let k = (intermediate.ln() - intermediate.ln().ln() + 0.25)
|
||||
.round()
|
||||
.max(1.);
|
||||
|
||||
let w = (t / (t / k + l * (2.0f64).powf(k + 1.0)) - 2.0).floor();
|
||||
(l as _, k as _, w as _)
|
||||
}
|
||||
|
||||
fn u64_to_bytes(q: u64) -> [u8; 8] {
|
||||
if false {
|
||||
// This use of `std::mem::transumte` is correct, but still not justified.
|
||||
unsafe { std::mem::transmute(q.to_be()) }
|
||||
} else {
|
||||
[
|
||||
(q >> 56) as u8,
|
||||
(q >> 48) as u8,
|
||||
(q >> 40) as u8,
|
||||
(q >> 32) as u8,
|
||||
(q >> 24) as u8,
|
||||
(q >> 16) as u8,
|
||||
(q >> 8) as u8,
|
||||
q as u8,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/// Quote:
|
||||
///
|
||||
/// > Creates a random prime based on input s.
|
||||
fn hash_prime<T: BigNum>(seed: &[&[u8]], t: u32) -> T {
|
||||
let mut j = 0u64;
|
||||
loop {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.input(b"prime");
|
||||
hasher.input(u64_to_bytes(j));
|
||||
for i in seed {
|
||||
hasher.input(i);
|
||||
}
|
||||
hasher.input(t.to_be_bytes());
|
||||
let n = T::from(&hasher.fixed_result()[..16]);
|
||||
if n.probab_prime(1) {
|
||||
break n;
|
||||
}
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Quote:
|
||||
///
|
||||
/// > Get“s the ith block of `2^T // B`, such that `sum(get_block(i) * 2^(k*i))
|
||||
/// > = t^T // B`
|
||||
fn get_block<T: BigNumExt>(i: u64, k: u8, t: u64, b: &T) -> T {
|
||||
let mut res = T::from(0);
|
||||
let two = T::from(2);
|
||||
res.mod_powm(&two, &T::from(t - u64::from(k) * (i + 1)), b);
|
||||
res *= &((two >> 1) << (k as usize));
|
||||
res / b
|
||||
}
|
||||
|
||||
fn eval_optimized<T, U: BigNumExt, L: ClassGroup<BigNum = U> + Eq + Hash>(
|
||||
h: &L,
|
||||
b: &U,
|
||||
t: usize,
|
||||
k: u8,
|
||||
l: usize,
|
||||
powers: &T,
|
||||
) -> L
|
||||
where
|
||||
T: for<'a> std::ops::Index<&'a u64, Output = L>,
|
||||
{
|
||||
assert!(k > 0, "k cannot be zero");
|
||||
assert!(l > 0, "l cannot be zero");
|
||||
let kl = (k as usize)
|
||||
.checked_mul(l)
|
||||
.expect("computing k*l overflowed a u64");
|
||||
assert!(kl <= u64::MAX as _);
|
||||
assert!((kl as u64) < (1u64 << 53), "k*l overflowed an f64");
|
||||
assert!((t as u64) < (1u64 << 53), "t overflows an f64");
|
||||
assert!(
|
||||
k < (mem::size_of::<usize>() << 3) as u8,
|
||||
"k must be less than the number of bits in a usize"
|
||||
);
|
||||
let k1 = k >> 1;
|
||||
let k0 = k - k1;
|
||||
let mut x = h.identity();
|
||||
let identity = h.identity();
|
||||
let k_exp = 1usize << k;
|
||||
let k0_exp = 1usize << k0;
|
||||
let k1_exp = 1usize << k1;
|
||||
for j in (0..l).rev() {
|
||||
x.pow(U::from(k_exp as u64));
|
||||
let mut ys: HashMap<U, L> = HashMap::new();
|
||||
for b in 0..1usize << k {
|
||||
ys.entry(U::from(b as u64))
|
||||
.or_insert_with(|| identity.clone());
|
||||
}
|
||||
let end_of_loop = ((t as f64) / kl as f64).ceil() as usize;
|
||||
assert!(end_of_loop == 0 || (end_of_loop as u64 - 1).checked_mul(l as u64).is_some());
|
||||
for i in 0..end_of_loop {
|
||||
if t < k as usize * (i * l + j + 1) {
|
||||
continue;
|
||||
}
|
||||
let b = get_block((i as u64) * (l as u64), k, t as _, b);
|
||||
*ys.get_mut(&b).unwrap() *= &powers[&((i * kl) as _)];
|
||||
}
|
||||
|
||||
for b1 in 0..k1_exp {
|
||||
let mut z = identity.clone();
|
||||
for b0 in 0..k0_exp {
|
||||
z *= &ys[&U::from((b1 * k0_exp + b0) as u64)]
|
||||
}
|
||||
z.pow(U::from((b1 as u64) * (k0_exp as u64)));
|
||||
x *= &z;
|
||||
}
|
||||
|
||||
for b0 in 0..k0_exp {
|
||||
let mut z = identity.clone();
|
||||
for b1 in 0..k1_exp {
|
||||
z *= &ys[&U::from((b1 * k0_exp + b0) as u64)];
|
||||
}
|
||||
z.pow(U::from(b0 as u64));
|
||||
x *= &z;
|
||||
}
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
pub fn generate_proof<U, T: BigNumExt, V: ClassGroup<BigNum = T> + Eq + Hash>(
|
||||
x: &V,
|
||||
iterations: u64,
|
||||
k: u8,
|
||||
l: usize,
|
||||
powers: &U,
|
||||
int_size_bits: usize,
|
||||
) -> V
|
||||
where
|
||||
U: for<'a> std::ops::Index<&'a u64, Output = V>,
|
||||
{
|
||||
let element_len = 2 * ((int_size_bits + 16) >> 4);
|
||||
let mut x_buf = vec![0; element_len];
|
||||
x.serialize(&mut x_buf[..])
|
||||
.expect(super::INCORRECT_BUFFER_SIZE);
|
||||
let mut y_buf = vec![0; element_len];
|
||||
powers[&iterations]
|
||||
.serialize(&mut y_buf[..])
|
||||
.expect(super::INCORRECT_BUFFER_SIZE);
|
||||
let b = hash_prime(
|
||||
&[&x_buf[..], &y_buf[..]],
|
||||
iterations.try_into().expect("iterations fit into u32")
|
||||
);
|
||||
eval_optimized(&x, &b, iterations as _, k, l, powers)
|
||||
}
|
||||
|
||||
/// Verify a proof, according to the Wesolowski paper.
|
||||
pub fn verify_proof<T: BigNum, V: ClassGroup<BigNum = T>>(
|
||||
mut x: V,
|
||||
y: &V,
|
||||
mut proof: V,
|
||||
t: u64,
|
||||
int_size_bits: usize,
|
||||
) -> Result<(), ()> {
|
||||
let element_len = 2 * ((int_size_bits + 16) >> 4);
|
||||
let mut x_buf = vec![0; element_len];
|
||||
x.serialize(&mut x_buf[..])
|
||||
.expect(super::INCORRECT_BUFFER_SIZE);
|
||||
let mut y_buf = vec![0; element_len];
|
||||
y.serialize(&mut y_buf[..])
|
||||
.expect(super::INCORRECT_BUFFER_SIZE);
|
||||
let b = hash_prime(
|
||||
&[&x_buf[..], &y_buf[..]],
|
||||
t.try_into().expect("iterations fit into u32")
|
||||
);
|
||||
let mut r = T::from(0);
|
||||
r.mod_powm(&T::from(2u64), &T::from(t), &b);
|
||||
proof.pow(b);
|
||||
x.pow(r);
|
||||
proof *= &x;
|
||||
if &proof == y {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_proof_of_time_wesolowski<T: BigNumExt, V: ClassGroup<BigNum = T> + Eq + Hash>(
|
||||
challenge: &[u8],
|
||||
iterations: usize,
|
||||
int_size_bits: u16,
|
||||
) -> Vec<u8>
|
||||
where
|
||||
for<'a, 'b> &'a V: std::ops::Mul<&'b V, Output = V>,
|
||||
for<'a, 'b> &'a V::BigNum: std::ops::Mul<&'b V::BigNum, Output = V::BigNum>,
|
||||
{
|
||||
let discriminant = super::create_discriminant::create_discriminant(&challenge, int_size_bits);
|
||||
let x = V::from_ab_discriminant(2.into(), 1.into(), discriminant);
|
||||
assert!((iterations as u128) < (1u128 << 53));
|
||||
let (l, k, _) = approximate_parameters(iterations as f64);
|
||||
let q = l.checked_mul(k as _).expect("bug");
|
||||
let powers = iterate_squarings(
|
||||
x.clone(),
|
||||
(0..=iterations / q + 1)
|
||||
.map(|i| i * q)
|
||||
.chain(Some(iterations))
|
||||
.map(|x| x as _),
|
||||
);
|
||||
let proof = generate_proof(&x, iterations as _, k, l, &powers, int_size_bits.into());
|
||||
serialize(&[proof], &powers[&(iterations as _)], int_size_bits.into())
|
||||
}
|
||||
|
||||
pub fn check_proof_of_time_wesolowski<T: BigNum, V: ClassGroup<BigNum = T>>(
|
||||
challenge: &[u8],
|
||||
proof_blob: &[u8],
|
||||
iterations: u64,
|
||||
int_size_bits: u16,
|
||||
) -> Result<(), ()>
|
||||
where
|
||||
T: BigNumExt,
|
||||
{
|
||||
let discriminant: T = super::create_discriminant::create_discriminant(challenge, int_size_bits);
|
||||
let x = V::from_ab_discriminant(2.into(), 1.into(), discriminant.clone());
|
||||
if (usize::MAX - 16) < int_size_bits.into() {
|
||||
return Err(());
|
||||
}
|
||||
let int_size = (usize::from(int_size_bits) + 16) >> 4;
|
||||
if int_size * 4 != proof_blob.len() {
|
||||
return Err(());
|
||||
}
|
||||
let (result_bytes, proof_bytes) = proof_blob.split_at(2 * int_size);
|
||||
let proof = ClassGroup::from_bytes(proof_bytes, discriminant.clone());
|
||||
let y = ClassGroup::from_bytes(result_bytes, discriminant);
|
||||
|
||||
verify_proof(x, &y, proof, iterations, int_size_bits.into())
|
||||
}
|
@ -7,14 +7,6 @@ services:
|
||||
node:
|
||||
image: ${QUILIBRIUM_IMAGE_NAME:-quilibrium}
|
||||
restart: unless-stopped
|
||||
command: ["--signature-check=false"]
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: '32G'
|
||||
reservations:
|
||||
cpus: '12'
|
||||
memory: '16G'
|
||||
environment:
|
||||
- DEFAULT_LISTEN_GRPC_MULTIADDR=/ip4/0.0.0.0/tcp/8337
|
||||
- DEFAULT_LISTEN_REST_MULTIADDR=/ip4/0.0.0.0/tcp/8338
|
||||
@ -28,7 +20,7 @@ services:
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 1m
|
||||
start_period: 15m
|
||||
volumes:
|
||||
- ./.config:/root/.config
|
||||
logging:
|
||||
|
811
docker/rustup-init.sh
Executable file
811
docker/rustup-init.sh
Executable file
@ -0,0 +1,811 @@
|
||||
#!/bin/sh
|
||||
# shellcheck shell=dash
|
||||
# shellcheck disable=SC2039 # local is non-POSIX
|
||||
|
||||
# This is just a little script that can be downloaded from the internet to
|
||||
# install rustup. It just does platform detection, downloads the installer
|
||||
# and runs it.
|
||||
|
||||
# It runs on Unix shells like {a,ba,da,k,z}sh. It uses the common `local`
|
||||
# extension. Note: Most shells limit `local` to 1 var per line, contra bash.
|
||||
|
||||
# Some versions of ksh have no `local` keyword. Alias it to `typeset`, but
|
||||
# beware this makes variables global with f()-style function syntax in ksh93.
|
||||
# mksh has this alias by default.
|
||||
has_local() {
|
||||
# shellcheck disable=SC2034 # deliberately unused
|
||||
local _has_local
|
||||
}
|
||||
|
||||
has_local 2>/dev/null || alias local=typeset
|
||||
|
||||
is_zsh() {
|
||||
[ -n "${ZSH_VERSION-}" ]
|
||||
}
|
||||
|
||||
set -u
|
||||
|
||||
# If RUSTUP_UPDATE_ROOT is unset or empty, default it.
|
||||
RUSTUP_UPDATE_ROOT="${RUSTUP_UPDATE_ROOT:-https://static.rust-lang.org/rustup}"
|
||||
|
||||
# NOTICE: If you change anything here, please make the same changes in setup_mode.rs
|
||||
usage() {
|
||||
cat <<EOF
|
||||
rustup-init 1.27.1 (a8e4f5c64 2024-04-24)
|
||||
|
||||
The installer for rustup
|
||||
|
||||
Usage: rustup-init[EXE] [OPTIONS]
|
||||
|
||||
Options:
|
||||
-v, --verbose
|
||||
Enable verbose output
|
||||
-q, --quiet
|
||||
Disable progress output
|
||||
-y
|
||||
Disable confirmation prompt.
|
||||
--default-host <default-host>
|
||||
Choose a default host triple
|
||||
--default-toolchain <default-toolchain>
|
||||
Choose a default toolchain to install. Use 'none' to not install any toolchains at all
|
||||
--profile <profile>
|
||||
[default: default] [possible values: minimal, default, complete]
|
||||
-c, --component <components>...
|
||||
Component name to also install
|
||||
-t, --target <targets>...
|
||||
Target name to also install
|
||||
--no-update-default-toolchain
|
||||
Don't update any existing default toolchain after install
|
||||
--no-modify-path
|
||||
Don't configure the PATH environment variable
|
||||
-h, --help
|
||||
Print help
|
||||
-V, --version
|
||||
Print version
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
downloader --check
|
||||
need_cmd uname
|
||||
need_cmd mktemp
|
||||
need_cmd chmod
|
||||
need_cmd mkdir
|
||||
need_cmd rm
|
||||
need_cmd rmdir
|
||||
|
||||
get_architecture || return 1
|
||||
local _arch="$RETVAL"
|
||||
assert_nz "$_arch" "arch"
|
||||
|
||||
local _ext=""
|
||||
case "$_arch" in
|
||||
*windows*)
|
||||
_ext=".exe"
|
||||
;;
|
||||
esac
|
||||
|
||||
local _url="${RUSTUP_UPDATE_ROOT}/dist/${_arch}/rustup-init${_ext}"
|
||||
|
||||
local _dir
|
||||
if ! _dir="$(ensure mktemp -d)"; then
|
||||
# Because the previous command ran in a subshell, we must manually
|
||||
# propagate exit status.
|
||||
exit 1
|
||||
fi
|
||||
local _file="${_dir}/rustup-init${_ext}"
|
||||
|
||||
local _ansi_escapes_are_valid=false
|
||||
if [ -t 2 ]; then
|
||||
if [ "${TERM+set}" = 'set' ]; then
|
||||
case "$TERM" in
|
||||
xterm*|rxvt*|urxvt*|linux*|vt*)
|
||||
_ansi_escapes_are_valid=true
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
# check if we have to use /dev/tty to prompt the user
|
||||
local need_tty=yes
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
OPTIND=1
|
||||
if [ "${arg%%--*}" = "" ]; then
|
||||
# Long option (other than --help);
|
||||
# don't attempt to interpret it.
|
||||
continue
|
||||
fi
|
||||
while getopts :hy sub_arg "$arg"; do
|
||||
case "$sub_arg" in
|
||||
h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
y)
|
||||
# user wants to skip the prompt --
|
||||
# we don't need /dev/tty
|
||||
need_tty=no
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if $_ansi_escapes_are_valid; then
|
||||
printf "\33[1minfo:\33[0m downloading installer\n" 1>&2
|
||||
else
|
||||
printf '%s\n' 'info: downloading installer' 1>&2
|
||||
fi
|
||||
|
||||
ensure mkdir -p "$_dir"
|
||||
ensure downloader "$_url" "$_file" "$_arch"
|
||||
ensure chmod u+x "$_file"
|
||||
if [ ! -x "$_file" ]; then
|
||||
printf '%s\n' "Cannot execute $_file (likely because of mounting /tmp as noexec)." 1>&2
|
||||
printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./rustup-init${_ext}." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$need_tty" = "yes" ] && [ ! -t 0 ]; then
|
||||
# The installer is going to want to ask for confirmation by
|
||||
# reading stdin. This script was piped into `sh` though and
|
||||
# doesn't have stdin to pass to its children. Instead we're going
|
||||
# to explicitly connect /dev/tty to the installer's stdin.
|
||||
if [ ! -t 1 ]; then
|
||||
err "Unable to run interactively. Run with -y to accept defaults, --help for additional options"
|
||||
fi
|
||||
|
||||
ignore "$_file" "$@" < /dev/tty
|
||||
else
|
||||
ignore "$_file" "$@"
|
||||
fi
|
||||
|
||||
local _retval=$?
|
||||
|
||||
ignore rm "$_file"
|
||||
ignore rmdir "$_dir"
|
||||
|
||||
return "$_retval"
|
||||
}
|
||||
|
||||
check_proc() {
|
||||
# Check for /proc by looking for the /proc/self/exe link
|
||||
# This is only run on Linux
|
||||
if ! test -L /proc/self/exe ; then
|
||||
err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc."
|
||||
fi
|
||||
}
|
||||
|
||||
get_bitness() {
|
||||
need_cmd head
|
||||
# Architecture detection without dependencies beyond coreutils.
|
||||
# ELF files start out "\x7fELF", and the following byte is
|
||||
# 0x01 for 32-bit and
|
||||
# 0x02 for 64-bit.
|
||||
# The printf builtin on some shells like dash only supports octal
|
||||
# escape sequences, so we use those.
|
||||
local _current_exe_head
|
||||
_current_exe_head=$(head -c 5 /proc/self/exe )
|
||||
if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then
|
||||
echo 32
|
||||
elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then
|
||||
echo 64
|
||||
else
|
||||
err "unknown platform bitness"
|
||||
fi
|
||||
}
|
||||
|
||||
is_host_amd64_elf() {
|
||||
need_cmd head
|
||||
need_cmd tail
|
||||
# ELF e_machine detection without dependencies beyond coreutils.
|
||||
# Two-byte field at offset 0x12 indicates the CPU,
|
||||
# but we're interested in it being 0x3E to indicate amd64, or not that.
|
||||
local _current_exe_machine
|
||||
_current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1)
|
||||
[ "$_current_exe_machine" = "$(printf '\076')" ]
|
||||
}
|
||||
|
||||
get_endianness() {
|
||||
local cputype=$1
|
||||
local suffix_eb=$2
|
||||
local suffix_el=$3
|
||||
|
||||
# detect endianness without od/hexdump, like get_bitness() does.
|
||||
need_cmd head
|
||||
need_cmd tail
|
||||
|
||||
local _current_exe_endianness
|
||||
_current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)"
|
||||
if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then
|
||||
echo "${cputype}${suffix_el}"
|
||||
elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then
|
||||
echo "${cputype}${suffix_eb}"
|
||||
else
|
||||
err "unknown platform endianness"
|
||||
fi
|
||||
}
|
||||
|
||||
# Detect the Linux/LoongArch UAPI flavor, with all errors being non-fatal.
|
||||
# Returns 0 or 234 in case of successful detection, 1 otherwise (/tmp being
|
||||
# noexec, or other causes).
|
||||
check_loongarch_uapi() {
|
||||
need_cmd base64
|
||||
|
||||
local _tmp
|
||||
if ! _tmp="$(ensure mktemp)"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Minimal Linux/LoongArch UAPI detection, exiting with 0 in case of
|
||||
# upstream ("new world") UAPI, and 234 (-EINVAL truncated) in case of
|
||||
# old-world (as deployed on several early commercial Linux distributions
|
||||
# for LoongArch).
|
||||
#
|
||||
# See https://gist.github.com/xen0n/5ee04aaa6cecc5c7794b9a0c3b65fc7f for
|
||||
# source to this helper binary.
|
||||
ignore base64 -d > "$_tmp" <<EOF
|
||||
f0VMRgIBAQAAAAAAAAAAAAIAAgEBAAAAeAAgAAAAAABAAAAAAAAAAAAAAAAAAAAAQQAAAEAAOAAB
|
||||
AAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAACAAAAAAAAAAIAAAAAAAJAAAAAAAAAAkAAAAAAAAAAAA
|
||||
AQAAAAAABCiAAwUAFQAGABUAByCAAwsYggMAACsAC3iBAwAAKwAxen0n
|
||||
EOF
|
||||
|
||||
ignore chmod u+x "$_tmp"
|
||||
if [ ! -x "$_tmp" ]; then
|
||||
ignore rm "$_tmp"
|
||||
return 1
|
||||
fi
|
||||
|
||||
"$_tmp"
|
||||
local _retval=$?
|
||||
|
||||
ignore rm "$_tmp"
|
||||
return "$_retval"
|
||||
}
|
||||
|
||||
ensure_loongarch_uapi() {
|
||||
check_loongarch_uapi
|
||||
case $? in
|
||||
0)
|
||||
return 0
|
||||
;;
|
||||
234)
|
||||
echo >&2
|
||||
echo 'Your Linux kernel does not provide the ABI required by this Rust' >&2
|
||||
echo 'distribution. Please check with your OS provider for how to obtain a' >&2
|
||||
echo 'compatible Rust package for your system.' >&2
|
||||
echo >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "Warning: Cannot determine current system's ABI flavor, continuing anyway." >&2
|
||||
echo >&2
|
||||
echo 'Note that the official Rust distribution only works with the upstream' >&2
|
||||
echo 'kernel ABI. Installation will fail if your running kernel happens to be' >&2
|
||||
echo 'incompatible.' >&2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_architecture() {
|
||||
local _ostype _cputype _bitness _arch _clibtype
|
||||
_ostype="$(uname -s)"
|
||||
_cputype="$(uname -m)"
|
||||
_clibtype="gnu"
|
||||
|
||||
if [ "$_ostype" = Linux ]; then
|
||||
if [ "$(uname -o)" = Android ]; then
|
||||
_ostype=Android
|
||||
fi
|
||||
if ldd --version 2>&1 | grep -q 'musl'; then
|
||||
_clibtype="musl"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$_ostype" = Darwin ]; then
|
||||
# Darwin `uname -m` can lie due to Rosetta shenanigans. If you manage to
|
||||
# invoke a native shell binary and then a native uname binary, you can
|
||||
# get the real answer, but that's hard to ensure, so instead we use
|
||||
# `sysctl` (which doesn't lie) to check for the actual architecture.
|
||||
if [ "$_cputype" = i386 ]; then
|
||||
# Handling i386 compatibility mode in older macOS versions (<10.15)
|
||||
# running on x86_64-based Macs.
|
||||
# Starting from 10.15, macOS explicitly bans all i386 binaries from running.
|
||||
# See: <https://support.apple.com/en-us/HT208436>
|
||||
|
||||
# Avoid `sysctl: unknown oid` stderr output and/or non-zero exit code.
|
||||
if sysctl hw.optional.x86_64 2> /dev/null || true | grep -q ': 1'; then
|
||||
_cputype=x86_64
|
||||
fi
|
||||
elif [ "$_cputype" = x86_64 ]; then
|
||||
# Handling x86-64 compatibility mode (a.k.a. Rosetta 2)
|
||||
# in newer macOS versions (>=11) running on arm64-based Macs.
|
||||
# Rosetta 2 is built exclusively for x86-64 and cannot run i386 binaries.
|
||||
|
||||
# Avoid `sysctl: unknown oid` stderr output and/or non-zero exit code.
|
||||
if sysctl hw.optional.arm64 2> /dev/null || true | grep -q ': 1'; then
|
||||
_cputype=arm64
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$_ostype" = SunOS ]; then
|
||||
# Both Solaris and illumos presently announce as "SunOS" in "uname -s"
|
||||
# so use "uname -o" to disambiguate. We use the full path to the
|
||||
# system uname in case the user has coreutils uname first in PATH,
|
||||
# which has historically sometimes printed the wrong value here.
|
||||
if [ "$(/usr/bin/uname -o)" = illumos ]; then
|
||||
_ostype=illumos
|
||||
fi
|
||||
|
||||
# illumos systems have multi-arch userlands, and "uname -m" reports the
|
||||
# machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86
|
||||
# systems. Check for the native (widest) instruction set on the
|
||||
# running kernel:
|
||||
if [ "$_cputype" = i86pc ]; then
|
||||
_cputype="$(isainfo -n)"
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$_ostype" in
|
||||
|
||||
Android)
|
||||
_ostype=linux-android
|
||||
;;
|
||||
|
||||
Linux)
|
||||
check_proc
|
||||
_ostype=unknown-linux-$_clibtype
|
||||
_bitness=$(get_bitness)
|
||||
;;
|
||||
|
||||
FreeBSD)
|
||||
_ostype=unknown-freebsd
|
||||
;;
|
||||
|
||||
NetBSD)
|
||||
_ostype=unknown-netbsd
|
||||
;;
|
||||
|
||||
DragonFly)
|
||||
_ostype=unknown-dragonfly
|
||||
;;
|
||||
|
||||
Darwin)
|
||||
_ostype=apple-darwin
|
||||
;;
|
||||
|
||||
illumos)
|
||||
_ostype=unknown-illumos
|
||||
;;
|
||||
|
||||
MINGW* | MSYS* | CYGWIN* | Windows_NT)
|
||||
_ostype=pc-windows-gnu
|
||||
;;
|
||||
|
||||
*)
|
||||
err "unrecognized OS type: $_ostype"
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
case "$_cputype" in
|
||||
|
||||
i386 | i486 | i686 | i786 | x86)
|
||||
_cputype=i686
|
||||
;;
|
||||
|
||||
xscale | arm)
|
||||
_cputype=arm
|
||||
if [ "$_ostype" = "linux-android" ]; then
|
||||
_ostype=linux-androideabi
|
||||
fi
|
||||
;;
|
||||
|
||||
armv6l)
|
||||
_cputype=arm
|
||||
if [ "$_ostype" = "linux-android" ]; then
|
||||
_ostype=linux-androideabi
|
||||
else
|
||||
_ostype="${_ostype}eabihf"
|
||||
fi
|
||||
;;
|
||||
|
||||
armv7l | armv8l)
|
||||
_cputype=armv7
|
||||
if [ "$_ostype" = "linux-android" ]; then
|
||||
_ostype=linux-androideabi
|
||||
else
|
||||
_ostype="${_ostype}eabihf"
|
||||
fi
|
||||
;;
|
||||
|
||||
aarch64 | arm64)
|
||||
_cputype=aarch64
|
||||
;;
|
||||
|
||||
x86_64 | x86-64 | x64 | amd64)
|
||||
_cputype=x86_64
|
||||
;;
|
||||
|
||||
mips)
|
||||
_cputype=$(get_endianness mips '' el)
|
||||
;;
|
||||
|
||||
mips64)
|
||||
if [ "$_bitness" -eq 64 ]; then
|
||||
# only n64 ABI is supported for now
|
||||
_ostype="${_ostype}abi64"
|
||||
_cputype=$(get_endianness mips64 '' el)
|
||||
fi
|
||||
;;
|
||||
|
||||
ppc)
|
||||
_cputype=powerpc
|
||||
;;
|
||||
|
||||
ppc64)
|
||||
_cputype=powerpc64
|
||||
;;
|
||||
|
||||
ppc64le)
|
||||
_cputype=powerpc64le
|
||||
;;
|
||||
|
||||
s390x)
|
||||
_cputype=s390x
|
||||
;;
|
||||
riscv64)
|
||||
_cputype=riscv64gc
|
||||
;;
|
||||
loongarch64)
|
||||
_cputype=loongarch64
|
||||
ensure_loongarch_uapi
|
||||
;;
|
||||
*)
|
||||
err "unknown CPU type: $_cputype"
|
||||
|
||||
esac
|
||||
|
||||
# Detect 64-bit linux with 32-bit userland
|
||||
if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then
|
||||
case $_cputype in
|
||||
x86_64)
|
||||
if [ -n "${RUSTUP_CPUTYPE:-}" ]; then
|
||||
_cputype="$RUSTUP_CPUTYPE"
|
||||
else {
|
||||
# 32-bit executable for amd64 = x32
|
||||
if is_host_amd64_elf; then {
|
||||
echo "This host is running an x32 userland; as it stands, x32 support is poor," 1>&2
|
||||
echo "and there isn't a native toolchain -- you will have to install" 1>&2
|
||||
echo "multiarch compatibility with i686 and/or amd64, then select one" 1>&2
|
||||
echo "by re-running this script with the RUSTUP_CPUTYPE environment variable" 1>&2
|
||||
echo "set to i686 or x86_64, respectively." 1>&2
|
||||
echo 1>&2
|
||||
echo "You will be able to add an x32 target after installation by running" 1>&2
|
||||
echo " rustup target add x86_64-unknown-linux-gnux32" 1>&2
|
||||
exit 1
|
||||
}; else
|
||||
_cputype=i686
|
||||
fi
|
||||
}; fi
|
||||
;;
|
||||
mips64)
|
||||
_cputype=$(get_endianness mips '' el)
|
||||
;;
|
||||
powerpc64)
|
||||
_cputype=powerpc
|
||||
;;
|
||||
aarch64)
|
||||
_cputype=armv7
|
||||
if [ "$_ostype" = "linux-android" ]; then
|
||||
_ostype=linux-androideabi
|
||||
else
|
||||
_ostype="${_ostype}eabihf"
|
||||
fi
|
||||
;;
|
||||
riscv64gc)
|
||||
err "riscv64 with 32-bit userland unsupported"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Detect armv7 but without the CPU features Rust needs in that build,
|
||||
# and fall back to arm.
|
||||
# See https://github.com/rust-lang/rustup.rs/issues/587.
|
||||
if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then
|
||||
if ensure grep '^Features' /proc/cpuinfo | grep -E -q -v 'neon|simd'; then
|
||||
# At least one processor does not have NEON (which is asimd on armv8+).
|
||||
_cputype=arm
|
||||
fi
|
||||
fi
|
||||
|
||||
_arch="${_cputype}-${_ostype}"
|
||||
|
||||
RETVAL="$_arch"
|
||||
}
|
||||
|
||||
say() {
|
||||
printf 'rustup: %s\n' "$1"
|
||||
}
|
||||
|
||||
err() {
|
||||
say "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
need_cmd() {
|
||||
if ! check_cmd "$1"; then
|
||||
err "need '$1' (command not found)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_cmd() {
|
||||
command -v "$1" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
assert_nz() {
|
||||
if [ -z "$1" ]; then err "assert_nz $2"; fi
|
||||
}
|
||||
|
||||
# Run a command that should never fail. If the command fails execution
|
||||
# will immediately terminate with an error showing the failing
|
||||
# command.
|
||||
ensure() {
|
||||
if ! "$@"; then err "command failed: $*"; fi
|
||||
}
|
||||
|
||||
# This is just for indicating that commands' results are being
|
||||
# intentionally ignored. Usually, because it's being executed
|
||||
# as part of error handling.
|
||||
ignore() {
|
||||
"$@"
|
||||
}
|
||||
|
||||
# This wraps curl or wget. Try curl first, if not installed,
|
||||
# use wget instead.
|
||||
downloader() {
|
||||
# zsh does not split words by default, Required for curl retry arguments below.
|
||||
is_zsh && setopt local_options shwordsplit
|
||||
|
||||
local _dld
|
||||
local _ciphersuites
|
||||
local _err
|
||||
local _status
|
||||
local _retry
|
||||
if check_cmd curl; then
|
||||
_dld=curl
|
||||
elif check_cmd wget; then
|
||||
_dld=wget
|
||||
else
|
||||
_dld='curl or wget' # to be used in error message of need_cmd
|
||||
fi
|
||||
|
||||
if [ "$1" = --check ]; then
|
||||
need_cmd "$_dld"
|
||||
elif [ "$_dld" = curl ]; then
|
||||
check_curl_for_retry_support
|
||||
_retry="$RETVAL"
|
||||
get_ciphersuites_for_curl
|
||||
_ciphersuites="$RETVAL"
|
||||
if [ -n "$_ciphersuites" ]; then
|
||||
_err=$(curl $_retry --proto '=https' --tlsv1.2 --ciphers "$_ciphersuites" --silent --show-error --fail --location "$1" --output "$2" 2>&1)
|
||||
_status=$?
|
||||
else
|
||||
echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
|
||||
if ! check_help_for "$3" curl --proto --tlsv1.2; then
|
||||
echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
|
||||
_err=$(curl $_retry --silent --show-error --fail --location "$1" --output "$2" 2>&1)
|
||||
_status=$?
|
||||
else
|
||||
_err=$(curl $_retry --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2" 2>&1)
|
||||
_status=$?
|
||||
fi
|
||||
fi
|
||||
if [ -n "$_err" ]; then
|
||||
echo "$_err" >&2
|
||||
if echo "$_err" | grep -q 404$; then
|
||||
err "installer for platform '$3' not found, this may be unsupported"
|
||||
fi
|
||||
fi
|
||||
return $_status
|
||||
elif [ "$_dld" = wget ]; then
|
||||
if [ "$(wget -V 2>&1|head -2|tail -1|cut -f1 -d" ")" = "BusyBox" ]; then
|
||||
echo "Warning: using the BusyBox version of wget. Not enforcing strong cipher suites for TLS or TLS v1.2, this is potentially less secure"
|
||||
_err=$(wget "$1" -O "$2" 2>&1)
|
||||
_status=$?
|
||||
else
|
||||
get_ciphersuites_for_wget
|
||||
_ciphersuites="$RETVAL"
|
||||
if [ -n "$_ciphersuites" ]; then
|
||||
_err=$(wget --https-only --secure-protocol=TLSv1_2 --ciphers "$_ciphersuites" "$1" -O "$2" 2>&1)
|
||||
_status=$?
|
||||
else
|
||||
echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure"
|
||||
if ! check_help_for "$3" wget --https-only --secure-protocol; then
|
||||
echo "Warning: Not enforcing TLS v1.2, this is potentially less secure"
|
||||
_err=$(wget "$1" -O "$2" 2>&1)
|
||||
_status=$?
|
||||
else
|
||||
_err=$(wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2" 2>&1)
|
||||
_status=$?
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ -n "$_err" ]; then
|
||||
echo "$_err" >&2
|
||||
if echo "$_err" | grep -q ' 404 Not Found$'; then
|
||||
err "installer for platform '$3' not found, this may be unsupported"
|
||||
fi
|
||||
fi
|
||||
return $_status
|
||||
else
|
||||
err "Unknown downloader" # should not reach here
|
||||
fi
|
||||
}
|
||||
|
||||
check_help_for() {
|
||||
local _arch
|
||||
local _cmd
|
||||
local _arg
|
||||
_arch="$1"
|
||||
shift
|
||||
_cmd="$1"
|
||||
shift
|
||||
|
||||
local _category
|
||||
if "$_cmd" --help | grep -q 'For all options use the manual or "--help all".'; then
|
||||
_category="all"
|
||||
else
|
||||
_category=""
|
||||
fi
|
||||
|
||||
case "$_arch" in
|
||||
|
||||
*darwin*)
|
||||
if check_cmd sw_vers; then
|
||||
case $(sw_vers -productVersion) in
|
||||
10.*)
|
||||
# If we're running on macOS, older than 10.13, then we always
|
||||
# fail to find these options to force fallback
|
||||
if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then
|
||||
# Older than 10.13
|
||||
echo "Warning: Detected macOS platform older than 10.13"
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
11.*)
|
||||
# We assume Big Sur will be OK for now
|
||||
;;
|
||||
*)
|
||||
# Unknown product version, warn and continue
|
||||
echo "Warning: Detected unknown macOS major version: $(sw_vers -productVersion)"
|
||||
echo "Warning TLS capabilities detection may fail"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
for _arg in "$@"; do
|
||||
if ! "$_cmd" --help "$_category" | grep -q -- "$_arg"; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
true # not strictly needed
|
||||
}
|
||||
|
||||
# Check if curl supports the --retry flag, then pass it to the curl invocation.
|
||||
check_curl_for_retry_support() {
|
||||
local _retry_supported=""
|
||||
# "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
|
||||
if check_help_for "notspecified" "curl" "--retry"; then
|
||||
_retry_supported="--retry 3"
|
||||
if check_help_for "notspecified" "curl" "--continue-at"; then
|
||||
# "-C -" tells curl to automatically find where to resume the download when retrying.
|
||||
_retry_supported="--retry 3 -C -"
|
||||
fi
|
||||
fi
|
||||
|
||||
RETVAL="$_retry_supported"
|
||||
}
|
||||
|
||||
# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
|
||||
# if support by local tools is detected. Detection currently supports these curl backends:
|
||||
# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
|
||||
get_ciphersuites_for_curl() {
|
||||
if [ -n "${RUSTUP_TLS_CIPHERSUITES-}" ]; then
|
||||
# user specified custom cipher suites, assume they know what they're doing
|
||||
RETVAL="$RUSTUP_TLS_CIPHERSUITES"
|
||||
return
|
||||
fi
|
||||
|
||||
local _openssl_syntax="no"
|
||||
local _gnutls_syntax="no"
|
||||
local _backend_supported="yes"
|
||||
if curl -V | grep -q ' OpenSSL/'; then
|
||||
_openssl_syntax="yes"
|
||||
elif curl -V | grep -iq ' LibreSSL/'; then
|
||||
_openssl_syntax="yes"
|
||||
elif curl -V | grep -iq ' BoringSSL/'; then
|
||||
_openssl_syntax="yes"
|
||||
elif curl -V | grep -iq ' GnuTLS/'; then
|
||||
_gnutls_syntax="yes"
|
||||
else
|
||||
_backend_supported="no"
|
||||
fi
|
||||
|
||||
local _args_supported="no"
|
||||
if [ "$_backend_supported" = "yes" ]; then
|
||||
# "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
|
||||
if check_help_for "notspecified" "curl" "--tlsv1.2" "--ciphers" "--proto"; then
|
||||
_args_supported="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
local _cs=""
|
||||
if [ "$_args_supported" = "yes" ]; then
|
||||
if [ "$_openssl_syntax" = "yes" ]; then
|
||||
_cs=$(get_strong_ciphersuites_for "openssl")
|
||||
elif [ "$_gnutls_syntax" = "yes" ]; then
|
||||
_cs=$(get_strong_ciphersuites_for "gnutls")
|
||||
fi
|
||||
fi
|
||||
|
||||
RETVAL="$_cs"
|
||||
}
|
||||
|
||||
# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites
|
||||
# if support by local tools is detected. Detection currently supports these wget backends:
|
||||
# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty.
|
||||
get_ciphersuites_for_wget() {
|
||||
if [ -n "${RUSTUP_TLS_CIPHERSUITES-}" ]; then
|
||||
# user specified custom cipher suites, assume they know what they're doing
|
||||
RETVAL="$RUSTUP_TLS_CIPHERSUITES"
|
||||
return
|
||||
fi
|
||||
|
||||
local _cs=""
|
||||
if wget -V | grep -q '\-DHAVE_LIBSSL'; then
|
||||
# "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
|
||||
if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
|
||||
_cs=$(get_strong_ciphersuites_for "openssl")
|
||||
fi
|
||||
elif wget -V | grep -q '\-DHAVE_LIBGNUTLS'; then
|
||||
# "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc.
|
||||
if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then
|
||||
_cs=$(get_strong_ciphersuites_for "gnutls")
|
||||
fi
|
||||
fi
|
||||
|
||||
RETVAL="$_cs"
|
||||
}
|
||||
|
||||
# Return strong TLS 1.2-1.3 cipher suites in OpenSSL or GnuTLS syntax. TLS 1.2
|
||||
# excludes non-ECDHE and non-AEAD cipher suites. DHE is excluded due to bad
|
||||
# DH params often found on servers (see RFC 7919). Sequence matches or is
|
||||
# similar to Firefox 68 ESR with weak cipher suites disabled via about:config.
|
||||
# $1 must be openssl or gnutls.
|
||||
get_strong_ciphersuites_for() {
|
||||
if [ "$1" = "openssl" ]; then
|
||||
# OpenSSL is forgiving of unknown values, no problems with TLS 1.3 values on versions that don't support it yet.
|
||||
echo "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
|
||||
elif [ "$1" = "gnutls" ]; then
|
||||
# GnuTLS isn't forgiving of unknown values, so this may require a GnuTLS version that supports TLS 1.3 even if wget doesn't.
|
||||
# Begin with SECURE128 (and higher) then remove/add to build cipher suites. Produces same 9 cipher suites as OpenSSL but in slightly different order.
|
||||
echo "SECURE128:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-DTLS-ALL:-CIPHER-ALL:-MAC-ALL:-KX-ALL:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+AES-128-GCM:+CHACHA20-POLY1305:+AES-256-GCM"
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@" || exit 1
|
@ -1,6 +1,7 @@
|
||||
package blossomsub
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
@ -9,12 +10,14 @@ import (
|
||||
|
||||
pb "source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub/pb"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/event"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/peerstore"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
"github.com/libp2p/go-libp2p/core/record"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -26,7 +29,7 @@ const (
|
||||
var (
|
||||
BlossomSubD = 6
|
||||
BlossomSubDlo = 5
|
||||
BlossomSubDhi = 10
|
||||
BlossomSubDhi = 12
|
||||
BlossomSubDscore = 4
|
||||
BlossomSubDout = 2
|
||||
BlossomSubHistoryLength = 5
|
||||
@ -219,6 +222,7 @@ func NewBlossomSubRouter(h host.Host, params BlossomSubParams) *BlossomSubRouter
|
||||
lastpub: make(map[string]int64),
|
||||
gossip: make(map[peer.ID][]*pb.ControlIHave),
|
||||
control: make(map[peer.ID]*pb.ControlMessage),
|
||||
cab: pstoremem.NewAddrBook(),
|
||||
backoff: make(map[string]map[peer.ID]time.Time),
|
||||
peerhave: make(map[peer.ID]int),
|
||||
iasked: make(map[peer.ID]int),
|
||||
@ -247,6 +251,7 @@ func DefaultBlossomSubRouter(h host.Host) *BlossomSubRouter {
|
||||
iasked: make(map[peer.ID]int),
|
||||
outbound: make(map[peer.ID]bool),
|
||||
connect: make(chan connectInfo, params.MaxPendingConnections),
|
||||
cab: pstoremem.NewAddrBook(),
|
||||
mcache: NewMessageCache(params.HistoryGossip, params.HistoryLength),
|
||||
protos: BlossomSubDefaultProtocols,
|
||||
feature: BlossomSubDefaultFeatures,
|
||||
@ -447,6 +452,7 @@ type BlossomSubRouter struct {
|
||||
outbound map[peer.ID]bool // connection direction cache, marks peers with outbound connections
|
||||
backoff map[string]map[peer.ID]time.Time // prune backoff
|
||||
connect chan connectInfo // px connection requests
|
||||
cab peerstore.AddrBook
|
||||
|
||||
protos []protocol.ID
|
||||
feature BlossomSubFeatureTest
|
||||
@ -525,6 +531,9 @@ func (bs *BlossomSubRouter) Attach(p *PubSub) {
|
||||
go bs.connector()
|
||||
}
|
||||
|
||||
// Manage our address book from events emitted by libp2p
|
||||
go bs.manageAddrBook()
|
||||
|
||||
// connect to direct peers
|
||||
if len(bs.direct) > 0 {
|
||||
go func() {
|
||||
@ -538,6 +547,46 @@ func (bs *BlossomSubRouter) Attach(p *PubSub) {
|
||||
}
|
||||
}
|
||||
|
||||
func (bs *BlossomSubRouter) manageAddrBook() {
|
||||
sub, err := bs.p.host.EventBus().Subscribe([]interface{}{
|
||||
&event.EvtPeerIdentificationCompleted{},
|
||||
&event.EvtPeerConnectednessChanged{},
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to subscribe to peer identification events: %v", err)
|
||||
return
|
||||
}
|
||||
defer sub.Close()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-bs.p.ctx.Done():
|
||||
return
|
||||
case ev := <-sub.Out():
|
||||
switch ev := ev.(type) {
|
||||
case event.EvtPeerIdentificationCompleted:
|
||||
if ev.SignedPeerRecord != nil {
|
||||
cab, ok := peerstore.GetCertifiedAddrBook(bs.cab)
|
||||
if ok {
|
||||
ttl := peerstore.RecentlyConnectedAddrTTL
|
||||
if bs.p.host.Network().Connectedness(ev.Peer) == network.Connected {
|
||||
ttl = peerstore.ConnectedAddrTTL
|
||||
}
|
||||
_, err := cab.ConsumePeerRecord(ev.SignedPeerRecord, ttl)
|
||||
if err != nil {
|
||||
log.Warnf("failed to consume signed peer record: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
case event.EvtPeerConnectednessChanged:
|
||||
if ev.Connectedness != network.Connected {
|
||||
bs.cab.UpdateAddrs(ev.Peer, peerstore.ConnectedAddrTTL, peerstore.RecentlyConnectedAddrTTL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (bs *BlossomSubRouter) AddPeer(p peer.ID, proto protocol.ID) {
|
||||
log.Debugf("PEERUP: Add new peer %s using %s", p, proto)
|
||||
bs.tracer.AddPeer(p, proto)
|
||||
@ -550,7 +599,7 @@ loop:
|
||||
for _, c := range conns {
|
||||
stat := c.Stat()
|
||||
|
||||
if stat.Transient {
|
||||
if stat.Limited {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -968,7 +1017,7 @@ func (bs *BlossomSubRouter) connector() {
|
||||
}
|
||||
|
||||
log.Debugf("connecting to %s", ci.p)
|
||||
cab, ok := peerstore.GetCertifiedAddrBook(bs.p.host.Peerstore())
|
||||
cab, ok := peerstore.GetCertifiedAddrBook(bs.cab)
|
||||
if ok && ci.spr != nil {
|
||||
_, err := cab.ConsumePeerRecord(ci.spr, peerstore.TempAddrTTL)
|
||||
if err != nil {
|
||||
@ -977,7 +1026,7 @@ func (bs *BlossomSubRouter) connector() {
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(bs.p.ctx, bs.params.ConnectionTimeout)
|
||||
err := bs.p.host.Connect(ctx, peer.AddrInfo{ID: ci.p})
|
||||
err := bs.p.host.Connect(ctx, peer.AddrInfo{ID: ci.p, Addrs: bs.cab.Addrs(ci.p)})
|
||||
cancel()
|
||||
if err != nil {
|
||||
log.Debugf("error connecting to %s: %s", ci.p, err)
|
||||
@ -1188,20 +1237,20 @@ func (bs *BlossomSubRouter) sendRPC(p peer.ID, out *RPC) {
|
||||
return
|
||||
}
|
||||
|
||||
// If we're too big, fragment into multiple RPCs and send each sequentially
|
||||
outRPCs, err := fragmentRPC(out, bs.p.maxMessageSize)
|
||||
if err != nil {
|
||||
bs.doDropRPC(out, p, fmt.Sprintf("unable to fragment RPC: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
// Potentially split the RPC into multiple RPCs that are below the max message size
|
||||
outRPCs := appendOrMergeRPC(nil, bs.p.maxMessageSize, *out)
|
||||
for _, rpc := range outRPCs {
|
||||
if rpc.Size() > bs.p.maxMessageSize {
|
||||
// This should only happen if a single message/control is above the maxMessageSize.
|
||||
bs.doDropRPC(out, p, fmt.Sprintf("Dropping oversized RPC. Size: %d, limit: %d. (Over by %d bytes)", rpc.Size(), bs.p.maxMessageSize, rpc.Size()-bs.p.maxMessageSize))
|
||||
continue
|
||||
}
|
||||
bs.doSendRPC(rpc, p, mch)
|
||||
}
|
||||
}
|
||||
|
||||
func (bs *BlossomSubRouter) doDropRPC(rpc *RPC, p peer.ID, reason string) {
|
||||
log.Debugf("dropping message to peer %s: %s", p.Pretty(), reason)
|
||||
log.Debugf("dropping message to peer %s: %s", p, reason)
|
||||
bs.tracer.DropRPC(rpc, p)
|
||||
// push control messages that need to be retried
|
||||
ctl := rpc.GetControl()
|
||||
@ -1219,119 +1268,134 @@ func (bs *BlossomSubRouter) doSendRPC(rpc *RPC, p peer.ID, mch chan *RPC) {
|
||||
}
|
||||
}
|
||||
|
||||
func fragmentRPC(rpc *RPC, limit int) ([]*RPC, error) {
|
||||
if rpc.Size() < limit {
|
||||
return []*RPC{rpc}, nil
|
||||
// appendOrMergeRPC appends the given RPCs to the slice, merging them if possible.
|
||||
// If any elem is too large to fit in a single RPC, it will be split into multiple RPCs.
|
||||
// If an RPC is too large and can't be split further (e.g. Message data is
|
||||
// bigger than the RPC limit), then it will be returned as an oversized RPC.
|
||||
// The caller should filter out oversized RPCs.
|
||||
func appendOrMergeRPC(slice []*RPC, limit int, elems ...RPC) []*RPC {
|
||||
if len(elems) == 0 {
|
||||
return slice
|
||||
}
|
||||
|
||||
c := (rpc.Size() / limit) + 1
|
||||
rpcs := make([]*RPC, 1, c)
|
||||
rpcs[0] = &RPC{RPC: pb.RPC{}, from: rpc.from}
|
||||
if len(slice) == 0 && len(elems) == 1 && elems[0].Size() < limit {
|
||||
// Fast path: no merging needed and only one element
|
||||
return append(slice, &elems[0])
|
||||
}
|
||||
|
||||
// outRPC returns the current RPC message if it will fit sizeToAdd more bytes
|
||||
// otherwise, it will create a new RPC message and add it to the list.
|
||||
// if withCtl is true, the returned message will have a non-nil empty Control message.
|
||||
outRPC := func(sizeToAdd int, withCtl bool) *RPC {
|
||||
current := rpcs[len(rpcs)-1]
|
||||
// check if we can fit the new data, plus an extra byte for the protobuf field tag
|
||||
if current.Size()+sizeToAdd+1 < limit {
|
||||
if withCtl && current.Control == nil {
|
||||
current.Control = &pb.ControlMessage{}
|
||||
out := slice
|
||||
if len(out) == 0 {
|
||||
out = append(out, &RPC{RPC: pb.RPC{}})
|
||||
out[0].from = elems[0].from
|
||||
}
|
||||
|
||||
for _, elem := range elems {
|
||||
lastRPC := out[len(out)-1]
|
||||
|
||||
// Merge/Append publish messages
|
||||
// TODO: Never merge messages. The current behavior is the same as the
|
||||
// old behavior. In the future let's not merge messages. Since,
|
||||
// it may increase message latency.
|
||||
for _, msg := range elem.GetPublish() {
|
||||
if lastRPC.Publish = append(lastRPC.Publish, msg); lastRPC.Size() > limit {
|
||||
lastRPC.Publish = lastRPC.Publish[:len(lastRPC.Publish)-1]
|
||||
lastRPC = &RPC{RPC: pb.RPC{}, from: elem.from}
|
||||
lastRPC.Publish = append(lastRPC.Publish, msg)
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
return current
|
||||
}
|
||||
var ctl *pb.ControlMessage
|
||||
if withCtl {
|
||||
ctl = &pb.ControlMessage{}
|
||||
|
||||
// Merge/Append Subscriptions
|
||||
for _, sub := range elem.GetSubscriptions() {
|
||||
if lastRPC.Subscriptions = append(lastRPC.Subscriptions, sub); lastRPC.Size() > limit {
|
||||
lastRPC.Subscriptions = lastRPC.Subscriptions[:len(lastRPC.Subscriptions)-1]
|
||||
lastRPC = &RPC{RPC: pb.RPC{}, from: elem.from}
|
||||
lastRPC.Subscriptions = append(lastRPC.Subscriptions, sub)
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
}
|
||||
next := &RPC{RPC: pb.RPC{Control: ctl}, from: rpc.from}
|
||||
rpcs = append(rpcs, next)
|
||||
return next
|
||||
}
|
||||
|
||||
for _, msg := range rpc.GetPublish() {
|
||||
s := msg.Size()
|
||||
// if an individual message is too large, we can't fragment it and have to fail entirely
|
||||
if s > limit {
|
||||
return nil, fmt.Errorf("message with len=%d exceeds limit %d", s, limit)
|
||||
}
|
||||
out := outRPC(s, false)
|
||||
out.Publish = append(out.Publish, msg)
|
||||
}
|
||||
// Merge/Append Control messages
|
||||
if ctl := elem.GetControl(); ctl != nil {
|
||||
if lastRPC.Control == nil {
|
||||
lastRPC.Control = &pb.ControlMessage{}
|
||||
if lastRPC.Size() > limit {
|
||||
lastRPC.Control = nil
|
||||
lastRPC = &RPC{RPC: pb.RPC{Control: &pb.ControlMessage{}}, from: elem.from}
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
}
|
||||
|
||||
for _, sub := range rpc.GetSubscriptions() {
|
||||
out := outRPC(sub.Size(), false)
|
||||
out.Subscriptions = append(out.Subscriptions, sub)
|
||||
}
|
||||
for _, graft := range ctl.GetGraft() {
|
||||
if lastRPC.Control.Graft = append(lastRPC.Control.Graft, graft); lastRPC.Size() > limit {
|
||||
lastRPC.Control.Graft = lastRPC.Control.Graft[:len(lastRPC.Control.Graft)-1]
|
||||
lastRPC = &RPC{RPC: pb.RPC{Control: &pb.ControlMessage{}}, from: elem.from}
|
||||
lastRPC.Control.Graft = append(lastRPC.Control.Graft, graft)
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
}
|
||||
|
||||
ctl := rpc.GetControl()
|
||||
if ctl == nil {
|
||||
// if there were no control messages, we're done
|
||||
return rpcs, nil
|
||||
}
|
||||
// if all the control messages fit into one RPC, we just add it to the end and return
|
||||
ctlOut := &RPC{RPC: pb.RPC{Control: ctl}, from: rpc.from}
|
||||
if ctlOut.Size() < limit {
|
||||
rpcs = append(rpcs, ctlOut)
|
||||
return rpcs, nil
|
||||
}
|
||||
for _, prune := range ctl.GetPrune() {
|
||||
if lastRPC.Control.Prune = append(lastRPC.Control.Prune, prune); lastRPC.Size() > limit {
|
||||
lastRPC.Control.Prune = lastRPC.Control.Prune[:len(lastRPC.Control.Prune)-1]
|
||||
lastRPC = &RPC{RPC: pb.RPC{Control: &pb.ControlMessage{}}, from: elem.from}
|
||||
lastRPC.Control.Prune = append(lastRPC.Control.Prune, prune)
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
}
|
||||
|
||||
// we need to split up the control messages into multiple RPCs
|
||||
for _, graft := range ctl.Graft {
|
||||
out := outRPC(graft.Size(), true)
|
||||
out.Control.Graft = append(out.Control.Graft, graft)
|
||||
}
|
||||
for _, prune := range ctl.Prune {
|
||||
out := outRPC(prune.Size(), true)
|
||||
out.Control.Prune = append(out.Control.Prune, prune)
|
||||
}
|
||||
for _, iwant := range ctl.GetIwant() {
|
||||
if len(lastRPC.Control.Iwant) == 0 {
|
||||
// Initialize with a single IWANT.
|
||||
// For IWANTs we don't need more than a single one,
|
||||
// since there are no bitmask IDs here.
|
||||
newIWant := &pb.ControlIWant{}
|
||||
if lastRPC.Control.Iwant = append(lastRPC.Control.Iwant, newIWant); lastRPC.Size() > limit {
|
||||
lastRPC.Control.Iwant = lastRPC.Control.Iwant[:len(lastRPC.Control.Iwant)-1]
|
||||
lastRPC = &RPC{RPC: pb.RPC{Control: &pb.ControlMessage{
|
||||
Iwant: []*pb.ControlIWant{newIWant},
|
||||
}}, from: elem.from}
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
}
|
||||
for _, msgID := range iwant.GetMessageIDs() {
|
||||
if lastRPC.Control.Iwant[0].MessageIDs = append(lastRPC.Control.Iwant[0].MessageIDs, msgID); lastRPC.Size() > limit {
|
||||
lastRPC.Control.Iwant[0].MessageIDs = lastRPC.Control.Iwant[0].MessageIDs[:len(lastRPC.Control.Iwant[0].MessageIDs)-1]
|
||||
lastRPC = &RPC{RPC: pb.RPC{Control: &pb.ControlMessage{
|
||||
Iwant: []*pb.ControlIWant{{MessageIDs: []string{msgID}}},
|
||||
}}, from: elem.from}
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// An individual IWANT or IHAVE message could be larger than the limit if we have
|
||||
// a lot of message IDs. fragmentMessageIds will split them into buckets that
|
||||
// fit within the limit, with some overhead for the control messages themselves
|
||||
for _, iwant := range ctl.Iwant {
|
||||
const protobufOverhead = 6
|
||||
idBuckets := fragmentMessageIds(iwant.MessageIDs, limit-protobufOverhead)
|
||||
for _, ids := range idBuckets {
|
||||
iwant := &pb.ControlIWant{MessageIDs: ids}
|
||||
out := outRPC(iwant.Size(), true)
|
||||
out.Control.Iwant = append(out.Control.Iwant, iwant)
|
||||
for _, ihave := range ctl.GetIhave() {
|
||||
if len(lastRPC.Control.Ihave) == 0 ||
|
||||
!bytes.Equal(lastRPC.Control.Ihave[len(lastRPC.Control.Ihave)-1].Bitmask, ihave.Bitmask) {
|
||||
// Start a new IHAVE if we are referencing a new bitmask ID
|
||||
newIhave := &pb.ControlIHave{Bitmask: ihave.Bitmask}
|
||||
if lastRPC.Control.Ihave = append(lastRPC.Control.Ihave, newIhave); lastRPC.Size() > limit {
|
||||
lastRPC.Control.Ihave = lastRPC.Control.Ihave[:len(lastRPC.Control.Ihave)-1]
|
||||
lastRPC = &RPC{RPC: pb.RPC{Control: &pb.ControlMessage{
|
||||
Ihave: []*pb.ControlIHave{newIhave},
|
||||
}}, from: elem.from}
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
}
|
||||
for _, msgID := range ihave.GetMessageIDs() {
|
||||
lastIHave := lastRPC.Control.Ihave[len(lastRPC.Control.Ihave)-1]
|
||||
if lastIHave.MessageIDs = append(lastIHave.MessageIDs, msgID); lastRPC.Size() > limit {
|
||||
lastIHave.MessageIDs = lastIHave.MessageIDs[:len(lastIHave.MessageIDs)-1]
|
||||
lastRPC = &RPC{RPC: pb.RPC{Control: &pb.ControlMessage{
|
||||
Ihave: []*pb.ControlIHave{{Bitmask: ihave.Bitmask, MessageIDs: []string{msgID}}},
|
||||
}}, from: elem.from}
|
||||
out = append(out, lastRPC)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, ihave := range ctl.Ihave {
|
||||
const protobufOverhead = 6
|
||||
idBuckets := fragmentMessageIds(ihave.MessageIDs, limit-protobufOverhead)
|
||||
for _, ids := range idBuckets {
|
||||
ihave := &pb.ControlIHave{MessageIDs: ids}
|
||||
out := outRPC(ihave.Size(), true)
|
||||
out.Control.Ihave = append(out.Control.Ihave, ihave)
|
||||
}
|
||||
}
|
||||
return rpcs, nil
|
||||
}
|
||||
|
||||
func fragmentMessageIds(msgIds []string, limit int) [][]string {
|
||||
// account for two bytes of protobuf overhead per array element
|
||||
const protobufOverhead = 2
|
||||
|
||||
out := [][]string{{}}
|
||||
var currentBucket int
|
||||
var bucketLen int
|
||||
for i := 0; i < len(msgIds); i++ {
|
||||
size := len(msgIds[i]) + protobufOverhead
|
||||
if size > limit {
|
||||
// pathological case where a single message ID exceeds the limit.
|
||||
log.Warnf("message ID length %d exceeds limit %d, removing from outgoing gossip", size, limit)
|
||||
continue
|
||||
}
|
||||
bucketLen += size
|
||||
if bucketLen > limit {
|
||||
out = append(out, []string{})
|
||||
currentBucket++
|
||||
bucketLen = size
|
||||
}
|
||||
out[currentBucket] = append(out[currentBucket], msgIds[i])
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,9 @@ func (p *PubSub) handleNewStream(s network.Stream) {
|
||||
|
||||
return
|
||||
}
|
||||
if len(msgbytes) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
rpc := new(RPC)
|
||||
err = rpc.Unmarshal(msgbytes)
|
||||
|
@ -66,10 +66,7 @@ require (
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.39.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/quic-go/qtls-go1-18 v0.2.0 // indirect
|
||||
github.com/quic-go/qtls-go1-19 v0.2.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.1.0 // indirect
|
||||
github.com/quic-go/quic-go v0.32.0 // indirect
|
||||
github.com/quic-go/quic-go v0.37.5 // indirect
|
||||
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
|
@ -18,7 +18,7 @@ func (p *PubSubNotif) ClosedStream(n network.Network, s network.Stream) {
|
||||
|
||||
func (p *PubSubNotif) Connected(n network.Network, c network.Conn) {
|
||||
// ignore transient connections
|
||||
if c.Stat().Transient {
|
||||
if c.Stat().Limited {
|
||||
return
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ func (p *PubSubNotif) ListenClose(n network.Network, _ ma.Multiaddr) {
|
||||
func (p *PubSubNotif) Initialize() {
|
||||
isTransient := func(pid peer.ID) bool {
|
||||
for _, c := range p.host.Network().ConnsToPeer(pid) {
|
||||
if !c.Stat().Transient {
|
||||
if !c.Stat().Limited {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ func (pg *peerGater) getPeerIP(p peer.ID) string {
|
||||
// most streams; it's a nightmare to track multiple IPs per peer, so pick the best one.
|
||||
streams := make(map[string]int)
|
||||
for _, c := range conns {
|
||||
if c.Stat().Transient {
|
||||
if c.Stat().Limited {
|
||||
// ignore transient
|
||||
continue
|
||||
}
|
||||
|
@ -990,7 +990,7 @@ func (ps *peerScore) getIPs(p peer.ID) []string {
|
||||
conns := ps.host.Network().ConnsToPeer(p)
|
||||
res := make([]string, 0, 1)
|
||||
for _, c := range conns {
|
||||
if c.Stat().Transient {
|
||||
if c.Stat().Limited {
|
||||
// ignore transient
|
||||
continue
|
||||
}
|
||||
|
@ -72,8 +72,7 @@ require (
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/procfs v0.11.1 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.2.3 // indirect
|
||||
github.com/quic-go/quic-go v0.36.3 // indirect
|
||||
github.com/quic-go/quic-go v0.37.5 // indirect
|
||||
github.com/quic-go/webtransport-go v0.5.3 // indirect
|
||||
github.com/raulk/go-watchdog v1.3.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
|
8
go-libp2p/.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
go-libp2p/.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Technical Questions
|
||||
url: https://github.com/libp2p/go-libp2p/discussions/new?category=q-a
|
||||
about: Please ask technical questions in the go-libp2p Github Discusions forum.
|
||||
- name: Community-wide libp2p Discussion
|
||||
url: https://discuss.libp2p.io
|
||||
about: Discussions and questions about the libp2p community.
|
11
go-libp2p/.github/workflows/automerge.yml
vendored
11
go-libp2p/.github/workflows/automerge.yml
vendored
@ -1,11 +0,0 @@
|
||||
# File managed by web3-bot. DO NOT EDIT.
|
||||
# See https://github.com/protocol/.github/ for details.
|
||||
|
||||
name: Automerge
|
||||
on: [ pull_request ]
|
||||
|
||||
jobs:
|
||||
automerge:
|
||||
uses: protocol/.github/.github/workflows/automerge.yml@master
|
||||
with:
|
||||
job: 'automerge'
|
81
go-libp2p/.github/workflows/go-check.yml
vendored
81
go-libp2p/.github/workflows/go-check.yml
vendored
@ -1,67 +1,20 @@
|
||||
# File managed by web3-bot. DO NOT EDIT.
|
||||
# See https://github.com/protocol/.github/ for details.
|
||||
|
||||
on: [push, pull_request]
|
||||
name: Go Checks
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: ["master","release-v0[0-9][0-9]"]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
unit:
|
||||
runs-on: ubuntu-latest
|
||||
name: All
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- id: config
|
||||
uses: protocol/.github/.github/actions/read-config@master
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
- name: Run repo-specific setup
|
||||
uses: ./.github/actions/go-check-setup
|
||||
if: hashFiles('./.github/actions/go-check-setup') != ''
|
||||
- name: Install staticcheck
|
||||
run: go install honnef.co/go/tools/cmd/staticcheck@4970552d932f48b71485287748246cf3237cebdf # 2023.1 (v0.4.0)
|
||||
- name: Check that go.mod is tidy
|
||||
uses: protocol/multiple-go-modules@v1.2
|
||||
with:
|
||||
run: |
|
||||
go mod tidy
|
||||
if [[ -n $(git ls-files --other --exclude-standard --directory -- go.sum) ]]; then
|
||||
echo "go.sum was added by go mod tidy"
|
||||
exit 1
|
||||
fi
|
||||
git diff --exit-code -- go.sum go.mod
|
||||
- name: gofmt
|
||||
if: success() || failure() # run this step even if the previous one failed
|
||||
run: |
|
||||
out=$(gofmt -s -l .)
|
||||
if [[ -n "$out" ]]; then
|
||||
echo $out | awk '{print "::error file=" $0 ",line=0,col=0::File is not gofmt-ed."}'
|
||||
exit 1
|
||||
fi
|
||||
- name: go vet
|
||||
if: success() || failure() # run this step even if the previous one failed
|
||||
uses: protocol/multiple-go-modules@v1.2
|
||||
with:
|
||||
run: go vet ./...
|
||||
- name: staticcheck
|
||||
if: success() || failure() # run this step even if the previous one failed
|
||||
uses: protocol/multiple-go-modules@v1.2
|
||||
with:
|
||||
run: |
|
||||
set -o pipefail
|
||||
staticcheck ./... | sed -e 's@\(.*\)\.go@./\1.go@g'
|
||||
- name: go generate
|
||||
uses: protocol/multiple-go-modules@v1.2
|
||||
if: (success() || failure()) && fromJSON(steps.config.outputs.json).gogenerate == true
|
||||
with:
|
||||
run: |
|
||||
git clean -fd # make sure there aren't untracked files / directories
|
||||
go generate -x ./...
|
||||
# check if go generate modified or added any files
|
||||
if ! $(git add . && git diff-index HEAD --exit-code --quiet); then
|
||||
echo "go generated caused changes to the repository:"
|
||||
git status --short
|
||||
exit 1
|
||||
fi
|
||||
go-check:
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/go-check.yml@v1.0
|
||||
with:
|
||||
go-generate-ignore-protoc-version-comments: true
|
||||
|
92
go-libp2p/.github/workflows/go-test.yml
vendored
92
go-libp2p/.github/workflows/go-test.yml
vendored
@ -1,76 +1,22 @@
|
||||
# File managed by web3-bot. DO NOT EDIT.
|
||||
# See https://github.com/protocol/.github/ for details.
|
||||
|
||||
on: [push, pull_request]
|
||||
name: Go Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches: ["master","release-v0[0-9][0-9]"]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
unit:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ "ubuntu", "windows", "macos" ]
|
||||
go: ["1.19.x","1.20.x"]
|
||||
env:
|
||||
COVERAGES: ""
|
||||
runs-on: ${{ fromJSON(vars[format('UCI_GO_TEST_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }}
|
||||
name: ${{ matrix.os }} (go ${{ matrix.go }})
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
- id: config
|
||||
uses: protocol/.github/.github/actions/read-config@master
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
- name: Go information
|
||||
run: |
|
||||
go version
|
||||
go env
|
||||
- name: Use msys2 on windows
|
||||
if: matrix.os == 'windows'
|
||||
shell: bash
|
||||
# The executable for msys2 is also called bash.cmd
|
||||
# https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#shells
|
||||
# If we prepend its location to the PATH
|
||||
# subsequent 'shell: bash' steps will use msys2 instead of gitbash
|
||||
run: echo "C:/msys64/usr/bin" >> $GITHUB_PATH
|
||||
- name: Run repo-specific setup
|
||||
uses: ./.github/actions/go-test-setup
|
||||
if: hashFiles('./.github/actions/go-test-setup') != ''
|
||||
- name: Run tests
|
||||
if: contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false
|
||||
uses: protocol/multiple-go-modules@v1.2
|
||||
with:
|
||||
# Use -coverpkg=./..., so that we include cross-package coverage.
|
||||
# If package ./A imports ./B, and ./A's tests also cover ./B,
|
||||
# this means ./B's coverage will be significantly higher than 0%.
|
||||
run: go test -v -shuffle=on -coverprofile=module-coverage.txt -coverpkg=./... ./...
|
||||
- name: Run tests (32 bit)
|
||||
# can't run 32 bit tests on OSX.
|
||||
if: matrix.os != 'macos' &&
|
||||
fromJSON(steps.config.outputs.json).skip32bit != true &&
|
||||
contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false
|
||||
uses: protocol/multiple-go-modules@v1.2
|
||||
env:
|
||||
GOARCH: 386
|
||||
with:
|
||||
run: |
|
||||
export "PATH=$PATH_386:$PATH"
|
||||
go test -v -shuffle=on ./...
|
||||
- name: Run tests with race detector
|
||||
# speed things up. Windows and OSX VMs are slow
|
||||
if: matrix.os == 'ubuntu' &&
|
||||
contains(fromJSON(steps.config.outputs.json).skipOSes, matrix.os) == false
|
||||
uses: protocol/multiple-go-modules@v1.2
|
||||
with:
|
||||
run: go test -v -race ./...
|
||||
- name: Collect coverage files
|
||||
shell: bash
|
||||
run: echo "COVERAGES=$(find . -type f -name 'module-coverage.txt' | tr -s '\n' ',' | sed 's/,$//')" >> $GITHUB_ENV
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1
|
||||
with:
|
||||
files: '${{ env.COVERAGES }}'
|
||||
env_vars: OS=${{ matrix.os }}, GO=${{ matrix.go }}
|
||||
go-test:
|
||||
uses: libp2p/uci/.github/workflows/go-test.yml@v1.0
|
||||
with:
|
||||
go-versions: '["1.21.x", "1.22.x"]'
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
19
go-libp2p/.github/workflows/interop-test.yml
vendored
19
go-libp2p/.github/workflows/interop-test.yml
vendored
@ -1,19 +1,32 @@
|
||||
name: Interoperability Testing
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'config/**'
|
||||
- 'core/**'
|
||||
- 'internal/**'
|
||||
- 'p2p/**'
|
||||
- 'test-plans/**'
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
paths:
|
||||
- 'config/**'
|
||||
- 'core/**'
|
||||
- 'internal/**'
|
||||
- 'p2p/**'
|
||||
- 'test-plans/**'
|
||||
|
||||
jobs:
|
||||
run-multidim-interop:
|
||||
name: Run multidimensional interoperability tests
|
||||
run-transport-interop:
|
||||
name: Run transport interoperability tests
|
||||
runs-on: ${{ fromJSON(vars['INTEROP_TEST_RUNNER_UBUNTU'] || '"ubuntu-22.04"') }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build image
|
||||
run: docker build -t go-libp2p-head -f test-plans/PingDockerfile .
|
||||
- uses: libp2p/test-plans/.github/actions/run-interop-ping-test@master
|
||||
- uses: libp2p/test-plans/.github/actions/run-transport-interop-test@master
|
||||
with:
|
||||
test-filter: go-libp2p-head
|
||||
extra-versions: ${{ github.workspace }}/test-plans/ping-version.json
|
||||
|
18
go-libp2p/.github/workflows/release-check.yml
vendored
18
go-libp2p/.github/workflows/release-check.yml
vendored
@ -1,13 +1,19 @@
|
||||
# File managed by web3-bot. DO NOT EDIT.
|
||||
# See https://github.com/protocol/.github/ for details.
|
||||
|
||||
name: Release Checker
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
paths: [ 'version.json' ]
|
||||
types: [ opened, synchronize, reopened, labeled, unlabeled ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
release-check:
|
||||
uses: protocol/.github/.github/workflows/release-check.yml@master
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/release-check.yml@v1.0
|
||||
|
14
go-libp2p/.github/workflows/releaser.yml
vendored
14
go-libp2p/.github/workflows/releaser.yml
vendored
@ -1,11 +1,17 @@
|
||||
# File managed by web3-bot. DO NOT EDIT.
|
||||
# See https://github.com/protocol/.github/ for details.
|
||||
|
||||
name: Releaser
|
||||
|
||||
on:
|
||||
push:
|
||||
paths: [ 'version.json' ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
releaser:
|
||||
uses: protocol/.github/.github/workflows/releaser.yml@master
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/releaser.yml@v1.0
|
||||
|
14
go-libp2p/.github/workflows/tagpush.yml
vendored
14
go-libp2p/.github/workflows/tagpush.yml
vendored
@ -1,12 +1,18 @@
|
||||
# File managed by web3-bot. DO NOT EDIT.
|
||||
# See https://github.com/protocol/.github/ for details.
|
||||
|
||||
name: Tag Push Checker
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
releaser:
|
||||
uses: protocol/.github/.github/workflows/tagpush.yml@master
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/tagpush.yml@v1.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
<h1 align="center">
|
||||
<a href="libp2p.io"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/black-bg-2.png?raw=true" alt="libp2p hex logo" /></a>
|
||||
<a href="https://libp2p.io/"><img width="250" src="https://github.com/libp2p/libp2p/blob/master/logo/black-bg-2.png?raw=true" alt="libp2p hex logo" /></a>
|
||||
</h1>
|
||||
|
||||
<h3 align="center">The Go implementation of the libp2p Networking Stack.</h3>
|
||||
@ -18,6 +18,7 @@
|
||||
- [Roadmap](#roadmap)
|
||||
- [Usage](#usage)
|
||||
- [Examples](#examples)
|
||||
- [Dashboards](#dashboards)
|
||||
- [Contribute](#contribute)
|
||||
- [Supported Go Versions](#supported-go-versions)
|
||||
- [Notable Users](#notable-users)
|
||||
@ -54,6 +55,13 @@ import "github.com/libp2p/go-libp2p"
|
||||
|
||||
Examples can be found in the [examples folder](examples).
|
||||
|
||||
## Dashboards
|
||||
|
||||
We provide prebuilt Grafana dashboards so that applications can better monitor libp2p in production.
|
||||
You can find the [dashboard JSON files here](https://github.com/libp2p/go-libp2p/tree/master/dashboards).
|
||||
|
||||
We also have live [Public Dashboards](https://github.com/libp2p/go-libp2p/tree/master/dashboards/README.md#public-dashboards) that you can check out to see real time monitoring in action.
|
||||
|
||||
|
||||
# Contribute
|
||||
|
||||
@ -75,7 +83,7 @@ There's a few things you can do right now to help out:
|
||||
## Supported Go Versions
|
||||
|
||||
We test against and support the two most recent major releases of Go. This is
|
||||
informed by Go's own [security policy](https://go.dev/security).
|
||||
informed by Go's own [security policy](https://go.dev/doc/security/policy).
|
||||
|
||||
# Notable Users
|
||||
Some notable users of go-libp2p are:
|
||||
|
@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -23,7 +24,6 @@ import (
|
||||
"github.com/libp2p/go-libp2p/p2p/host/autonat"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/autorelay"
|
||||
bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
blankhost "github.com/libp2p/go-libp2p/p2p/host/blank"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/eventbus"
|
||||
"github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem"
|
||||
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
|
||||
@ -38,6 +38,7 @@ import (
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
madns "github.com/multiformats/go-multiaddr-dns"
|
||||
"github.com/quic-go/quic-go"
|
||||
"go.uber.org/fx"
|
||||
"go.uber.org/fx/fxevent"
|
||||
)
|
||||
@ -128,6 +129,8 @@ type Config struct {
|
||||
DialRanker network.DialRanker
|
||||
|
||||
SwarmOpts []swarm.Option
|
||||
|
||||
DisableIdentifyAddressDiscovery bool
|
||||
}
|
||||
|
||||
func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swarm, error) {
|
||||
@ -190,20 +193,11 @@ func (cfg *Config) makeSwarm(eventBus event.Bus, enableMetrics bool) (*swarm.Swa
|
||||
return swarm.NewSwarm(pid, cfg.Peerstore, eventBus, opts...)
|
||||
}
|
||||
|
||||
func (cfg *Config) addTransports(h host.Host) error {
|
||||
swrm, ok := h.Network().(transport.TransportNetwork)
|
||||
if !ok {
|
||||
// Should probably skip this if no transports.
|
||||
return fmt.Errorf("swarm does not support transports")
|
||||
}
|
||||
|
||||
func (cfg *Config) addTransports() ([]fx.Option, error) {
|
||||
fxopts := []fx.Option{
|
||||
fx.WithLogger(func() fxevent.Logger { return getFXLogger() }),
|
||||
fx.Provide(fx.Annotate(tptu.New, fx.ParamTags(`name:"security"`))),
|
||||
fx.Supply(cfg.Muxers),
|
||||
fx.Supply(h.ID()),
|
||||
fx.Provide(func() host.Host { return h }),
|
||||
fx.Provide(func() crypto.PrivKey { return h.Peerstore().PrivKey(h.ID()) }),
|
||||
fx.Provide(func() connmgr.ConnectionGater { return cfg.ConnectionGater }),
|
||||
fx.Provide(func() pnet.PSK { return cfg.PSK }),
|
||||
fx.Provide(func() network.ResourceManager { return cfg.ResourceManager }),
|
||||
@ -261,15 +255,25 @@ func (cfg *Config) addTransports(h host.Host) error {
|
||||
}
|
||||
|
||||
fxopts = append(fxopts, fx.Provide(PrivKeyToStatelessResetKey))
|
||||
fxopts = append(fxopts, fx.Provide(PrivKeyToTokenGeneratorKey))
|
||||
if cfg.QUICReuse != nil {
|
||||
fxopts = append(fxopts, cfg.QUICReuse...)
|
||||
} else {
|
||||
fxopts = append(fxopts, fx.Provide(quicreuse.NewConnManager)) // TODO: close the ConnManager when shutting down the node
|
||||
fxopts = append(fxopts,
|
||||
fx.Provide(func(key quic.StatelessResetKey, tokenGenerator quic.TokenGeneratorKey, _ *swarm.Swarm, lifecycle fx.Lifecycle) (*quicreuse.ConnManager, error) {
|
||||
cm, err := quicreuse.NewConnManager(key, tokenGenerator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lifecycle.Append(fx.StopHook(cm.Close))
|
||||
return cm, nil
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fxopts = append(fxopts, fx.Invoke(
|
||||
fx.Annotate(
|
||||
func(tpts []transport.Transport) error {
|
||||
func(swrm *swarm.Swarm, tpts []transport.Transport) error {
|
||||
for _, t := range tpts {
|
||||
if err := swrm.AddTransport(t); err != nil {
|
||||
return err
|
||||
@ -277,54 +281,35 @@ func (cfg *Config) addTransports(h host.Host) error {
|
||||
}
|
||||
return nil
|
||||
},
|
||||
fx.ParamTags(`group:"transport"`),
|
||||
fx.ParamTags("", `group:"transport"`),
|
||||
)),
|
||||
)
|
||||
if cfg.Relay {
|
||||
fxopts = append(fxopts, fx.Invoke(circuitv2.AddTransport))
|
||||
}
|
||||
app := fx.New(fxopts...)
|
||||
if err := app.Err(); err != nil {
|
||||
h.Close()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return fxopts, nil
|
||||
}
|
||||
|
||||
// NewNode constructs a new libp2p Host from the Config.
|
||||
//
|
||||
// This function consumes the config. Do not reuse it (really!).
|
||||
func (cfg *Config) NewNode() (host.Host, error) {
|
||||
eventBus := eventbus.NewBus(eventbus.WithMetricsTracer(eventbus.NewMetricsTracer(eventbus.WithRegisterer(cfg.PrometheusRegisterer))))
|
||||
swrm, err := cfg.makeSwarm(eventBus, !cfg.DisableMetrics)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !cfg.DisableMetrics {
|
||||
rcmgr.MustRegisterWith(cfg.PrometheusRegisterer)
|
||||
}
|
||||
|
||||
func (cfg *Config) newBasicHost(swrm *swarm.Swarm, eventBus event.Bus) (*bhost.BasicHost, error) {
|
||||
h, err := bhost.NewHost(swrm, &bhost.HostOpts{
|
||||
EventBus: eventBus,
|
||||
ConnManager: cfg.ConnManager,
|
||||
AddrsFactory: cfg.AddrsFactory,
|
||||
NATManager: cfg.NATManager,
|
||||
EnablePing: !cfg.DisablePing,
|
||||
UserAgent: cfg.UserAgent,
|
||||
ProtocolVersion: cfg.ProtocolVersion,
|
||||
EnableHolePunching: cfg.EnableHolePunching,
|
||||
HolePunchingOptions: cfg.HolePunchingOptions,
|
||||
EnableRelayService: cfg.EnableRelayService,
|
||||
RelayServiceOpts: cfg.RelayServiceOpts,
|
||||
EnableMetrics: !cfg.DisableMetrics,
|
||||
PrometheusRegisterer: cfg.PrometheusRegisterer,
|
||||
EventBus: eventBus,
|
||||
ConnManager: cfg.ConnManager,
|
||||
AddrsFactory: cfg.AddrsFactory,
|
||||
NATManager: cfg.NATManager,
|
||||
EnablePing: !cfg.DisablePing,
|
||||
UserAgent: cfg.UserAgent,
|
||||
ProtocolVersion: cfg.ProtocolVersion,
|
||||
EnableHolePunching: cfg.EnableHolePunching,
|
||||
HolePunchingOptions: cfg.HolePunchingOptions,
|
||||
EnableRelayService: cfg.EnableRelayService,
|
||||
RelayServiceOpts: cfg.RelayServiceOpts,
|
||||
EnableMetrics: !cfg.DisableMetrics,
|
||||
PrometheusRegisterer: cfg.PrometheusRegisterer,
|
||||
DisableIdentifyAddressDiscovery: cfg.DisableIdentifyAddressDiscovery,
|
||||
})
|
||||
if err != nil {
|
||||
swrm.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.Relay {
|
||||
// If we've enabled the relay, we should filter out relay
|
||||
// addresses by default.
|
||||
@ -335,60 +320,144 @@ func (cfg *Config) NewNode() (host.Host, error) {
|
||||
return oldFactory(autorelay.Filter(addrs))
|
||||
}
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
if err := cfg.addTransports(h); err != nil {
|
||||
h.Close()
|
||||
return nil, err
|
||||
// NewNode constructs a new libp2p Host from the Config.
|
||||
//
|
||||
// This function consumes the config. Do not reuse it (really!).
|
||||
func (cfg *Config) NewNode() (host.Host, error) {
|
||||
if cfg.EnableAutoRelay && !cfg.Relay {
|
||||
return nil, fmt.Errorf("cannot enable autorelay; relay is not enabled")
|
||||
}
|
||||
// If possible check that the resource manager conn limit is higher than the
|
||||
// limit set in the conn manager.
|
||||
if l, ok := cfg.ResourceManager.(connmgr.GetConnLimiter); ok {
|
||||
err := cfg.ConnManager.CheckLimit(l)
|
||||
if err != nil {
|
||||
log.Warn(fmt.Sprintf("rcmgr limit conflicts with connmgr limit: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This method succeeds if listening on one address succeeds. We
|
||||
// should probably fail if listening on *any* addr fails.
|
||||
if err := h.Network().Listen(cfg.ListenAddrs...); err != nil {
|
||||
h.Close()
|
||||
if !cfg.DisableMetrics {
|
||||
rcmgr.MustRegisterWith(cfg.PrometheusRegisterer)
|
||||
}
|
||||
|
||||
fxopts := []fx.Option{
|
||||
fx.Provide(func() event.Bus {
|
||||
return eventbus.NewBus(eventbus.WithMetricsTracer(eventbus.NewMetricsTracer(eventbus.WithRegisterer(cfg.PrometheusRegisterer))))
|
||||
}),
|
||||
fx.Provide(func(eventBus event.Bus, lifecycle fx.Lifecycle) (*swarm.Swarm, error) {
|
||||
sw, err := cfg.makeSwarm(eventBus, !cfg.DisableMetrics)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lifecycle.Append(fx.StopHook(sw.Close))
|
||||
return sw, nil
|
||||
}),
|
||||
// Make sure the swarm constructor depends on the quicreuse.ConnManager.
|
||||
// That way, the ConnManager will be started before the swarm, and more importantly,
|
||||
// the swarm will be stopped before the ConnManager.
|
||||
fx.Decorate(func(sw *swarm.Swarm, _ *quicreuse.ConnManager, lifecycle fx.Lifecycle) *swarm.Swarm {
|
||||
lifecycle.Append(fx.Hook{
|
||||
OnStart: func(context.Context) error {
|
||||
// TODO: This method succeeds if listening on one address succeeds. We
|
||||
// should probably fail if listening on *any* addr fails.
|
||||
return sw.Listen(cfg.ListenAddrs...)
|
||||
},
|
||||
OnStop: func(context.Context) error {
|
||||
return sw.Close()
|
||||
},
|
||||
})
|
||||
return sw
|
||||
}),
|
||||
fx.Provide(cfg.newBasicHost),
|
||||
fx.Provide(func(bh *bhost.BasicHost) host.Host {
|
||||
return bh
|
||||
}),
|
||||
fx.Provide(func(h *swarm.Swarm) peer.ID { return h.LocalPeer() }),
|
||||
fx.Provide(func(h *swarm.Swarm) crypto.PrivKey { return h.Peerstore().PrivKey(h.LocalPeer()) }),
|
||||
}
|
||||
transportOpts, err := cfg.addTransports()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fxopts = append(fxopts, transportOpts...)
|
||||
|
||||
// Configure routing and autorelay
|
||||
var router routing.PeerRouting
|
||||
if cfg.Routing != nil {
|
||||
router, err = cfg.Routing(h)
|
||||
if err != nil {
|
||||
h.Close()
|
||||
return nil, err
|
||||
}
|
||||
fxopts = append(fxopts,
|
||||
fx.Provide(cfg.Routing),
|
||||
fx.Provide(func(h host.Host, router routing.PeerRouting) *routed.RoutedHost {
|
||||
return routed.Wrap(h, router)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// Note: h.AddrsFactory may be changed by relayFinder, but non-relay version is
|
||||
// used by AutoNAT below.
|
||||
var ar *autorelay.AutoRelay
|
||||
addrF := h.AddrsFactory
|
||||
if cfg.EnableAutoRelay {
|
||||
if !cfg.Relay {
|
||||
h.Close()
|
||||
return nil, fmt.Errorf("cannot enable autorelay; relay is not enabled")
|
||||
}
|
||||
if !cfg.DisableMetrics {
|
||||
mt := autorelay.WithMetricsTracer(
|
||||
autorelay.NewMetricsTracer(autorelay.WithRegisterer(cfg.PrometheusRegisterer)))
|
||||
mtOpts := []autorelay.Option{mt}
|
||||
cfg.AutoRelayOpts = append(mtOpts, cfg.AutoRelayOpts...)
|
||||
}
|
||||
|
||||
ar, err = autorelay.NewAutoRelay(h, cfg.AutoRelayOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fxopts = append(fxopts,
|
||||
fx.Invoke(func(h *bhost.BasicHost, lifecycle fx.Lifecycle) (*autorelay.AutoRelay, error) {
|
||||
ar, err := autorelay.NewAutoRelay(h, cfg.AutoRelayOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lifecycle.Append(fx.StartStopHook(ar.Start, ar.Close))
|
||||
return ar, nil
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
var bh *bhost.BasicHost
|
||||
fxopts = append(fxopts, fx.Invoke(func(bho *bhost.BasicHost) { bh = bho }))
|
||||
fxopts = append(fxopts, fx.Invoke(func(h *bhost.BasicHost, lifecycle fx.Lifecycle) {
|
||||
lifecycle.Append(fx.StartHook(h.Start))
|
||||
}))
|
||||
|
||||
var rh *routed.RoutedHost
|
||||
if cfg.Routing != nil {
|
||||
fxopts = append(fxopts, fx.Invoke(func(bho *routed.RoutedHost) { rh = bho }))
|
||||
}
|
||||
|
||||
app := fx.New(fxopts...)
|
||||
if err := app.Start(context.Background()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := cfg.addAutoNAT(bh); err != nil {
|
||||
app.Stop(context.Background())
|
||||
if cfg.Routing != nil {
|
||||
rh.Close()
|
||||
} else {
|
||||
bh.Close()
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.Routing != nil {
|
||||
return &closableRoutedHost{App: app, RoutedHost: rh}, nil
|
||||
}
|
||||
return &closableBasicHost{App: app, BasicHost: bh}, nil
|
||||
}
|
||||
|
||||
func (cfg *Config) addAutoNAT(h *bhost.BasicHost) error {
|
||||
addrF := h.AddrsFactory
|
||||
autonatOpts := []autonat.Option{
|
||||
autonat.UsingAddresses(func() []ma.Multiaddr {
|
||||
return addrF(h.AllAddrs())
|
||||
}),
|
||||
}
|
||||
if !cfg.DisableMetrics {
|
||||
autonatOpts = append(autonatOpts,
|
||||
autonat.WithMetricsTracer(
|
||||
autonat.NewMetricsTracer(autonat.WithRegisterer(cfg.PrometheusRegisterer))))
|
||||
autonatOpts = append(autonatOpts, autonat.WithMetricsTracer(
|
||||
autonat.NewMetricsTracer(autonat.WithRegisterer(cfg.PrometheusRegisterer)),
|
||||
))
|
||||
}
|
||||
if cfg.AutoNATConfig.ThrottleInterval != 0 {
|
||||
autonatOpts = append(autonatOpts,
|
||||
@ -398,16 +467,15 @@ func (cfg *Config) NewNode() (host.Host, error) {
|
||||
if cfg.AutoNATConfig.EnableService {
|
||||
autonatPrivKey, _, err := crypto.GenerateEd25519Key(rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
ps, err := pstoremem.NewPeerstore()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// Pull out the pieces of the config that we _actually_ care about.
|
||||
// Specifically, don't set up things like autorelay, listeners,
|
||||
// identify, etc.
|
||||
// Specifically, don't set up things like listeners, identify, etc.
|
||||
autoNatCfg := Config{
|
||||
Transports: cfg.Transports,
|
||||
Muxers: cfg.Muxers,
|
||||
@ -419,23 +487,47 @@ func (cfg *Config) NewNode() (host.Host, error) {
|
||||
PeerKey: autonatPrivKey,
|
||||
Peerstore: ps,
|
||||
DialRanker: swarm.NoDelayDialRanker,
|
||||
SwarmOpts: []swarm.Option{
|
||||
// It is better to disable black hole detection and just attempt a dial for autonat
|
||||
swarm.WithUDPBlackHoleConfig(false, 0, 0),
|
||||
swarm.WithIPv6BlackHoleConfig(false, 0, 0),
|
||||
},
|
||||
}
|
||||
|
||||
dialer, err := autoNatCfg.makeSwarm(eventbus.NewBus(), false)
|
||||
fxopts, err := autoNatCfg.addTransports()
|
||||
if err != nil {
|
||||
h.Close()
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
dialerHost := blankhost.NewBlankHost(dialer)
|
||||
if err := autoNatCfg.addTransports(dialerHost); err != nil {
|
||||
dialerHost.Close()
|
||||
h.Close()
|
||||
return nil, err
|
||||
var dialer *swarm.Swarm
|
||||
|
||||
fxopts = append(fxopts,
|
||||
fx.Provide(eventbus.NewBus),
|
||||
fx.Provide(func(lifecycle fx.Lifecycle, b event.Bus) (*swarm.Swarm, error) {
|
||||
lifecycle.Append(fx.Hook{
|
||||
OnStop: func(context.Context) error {
|
||||
return ps.Close()
|
||||
}})
|
||||
var err error
|
||||
dialer, err = autoNatCfg.makeSwarm(b, false)
|
||||
return dialer, err
|
||||
|
||||
}),
|
||||
fx.Provide(func(s *swarm.Swarm) peer.ID { return s.LocalPeer() }),
|
||||
fx.Provide(func() crypto.PrivKey { return autonatPrivKey }),
|
||||
)
|
||||
app := fx.New(fxopts...)
|
||||
if err := app.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
// NOTE: We're dropping the blank host here but that's fine. It
|
||||
// doesn't really _do_ anything and doesn't even need to be
|
||||
// closed (as long as we close the underlying network).
|
||||
autonatOpts = append(autonatOpts, autonat.EnableService(dialerHost.Network()))
|
||||
err = app.Start(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
<-dialer.Done() // The swarm used for autonat has closed, we can cleanup now
|
||||
app.Stop(context.Background())
|
||||
}()
|
||||
autonatOpts = append(autonatOpts, autonat.EnableService(dialer))
|
||||
}
|
||||
if cfg.AutoNATConfig.ForceReachability != nil {
|
||||
autonatOpts = append(autonatOpts, autonat.WithReachability(*cfg.AutoNATConfig.ForceReachability))
|
||||
@ -443,25 +535,10 @@ func (cfg *Config) NewNode() (host.Host, error) {
|
||||
|
||||
autonat, err := autonat.New(h, autonatOpts...)
|
||||
if err != nil {
|
||||
h.Close()
|
||||
return nil, fmt.Errorf("cannot enable autorelay; autonat failed to start: %v", err)
|
||||
return fmt.Errorf("cannot enable autorelay; autonat failed to start: %v", err)
|
||||
}
|
||||
h.SetAutoNat(autonat)
|
||||
|
||||
// start the host background tasks
|
||||
h.Start()
|
||||
|
||||
var ho host.Host
|
||||
ho = h
|
||||
if router != nil {
|
||||
ho = routed.Wrap(h, router)
|
||||
}
|
||||
if ar != nil {
|
||||
arh := autorelay.NewAutoRelayHost(ho, ar)
|
||||
arh.Start()
|
||||
ho = arh
|
||||
}
|
||||
return ho, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Option is a libp2p config option that can be given to the libp2p constructor
|
||||
|
30
go-libp2p/config/host.go
Normal file
30
go-libp2p/config/host.go
Normal file
@ -0,0 +1,30 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
basichost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
||||
routed "github.com/libp2p/go-libp2p/p2p/host/routed"
|
||||
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
type closableBasicHost struct {
|
||||
*fx.App
|
||||
*basichost.BasicHost
|
||||
}
|
||||
|
||||
func (h *closableBasicHost) Close() error {
|
||||
_ = h.App.Stop(context.Background())
|
||||
return h.BasicHost.Close()
|
||||
}
|
||||
|
||||
type closableRoutedHost struct {
|
||||
*fx.App
|
||||
*routed.RoutedHost
|
||||
}
|
||||
|
||||
func (h *closableRoutedHost) Close() error {
|
||||
_ = h.App.Stop(context.Background())
|
||||
return h.RoutedHost.Close()
|
||||
}
|
@ -11,7 +11,10 @@ import (
|
||||
"github.com/quic-go/quic-go"
|
||||
)
|
||||
|
||||
const statelessResetKeyInfo = "libp2p quic stateless reset key"
|
||||
const (
|
||||
statelessResetKeyInfo = "libp2p quic stateless reset key"
|
||||
tokenGeneratorKeyInfo = "libp2p quic token generator key"
|
||||
)
|
||||
|
||||
func PrivKeyToStatelessResetKey(key crypto.PrivKey) (quic.StatelessResetKey, error) {
|
||||
var statelessResetKey quic.StatelessResetKey
|
||||
@ -25,3 +28,16 @@ func PrivKeyToStatelessResetKey(key crypto.PrivKey) (quic.StatelessResetKey, err
|
||||
}
|
||||
return statelessResetKey, nil
|
||||
}
|
||||
|
||||
func PrivKeyToTokenGeneratorKey(key crypto.PrivKey) (quic.TokenGeneratorKey, error) {
|
||||
var tokenKey quic.TokenGeneratorKey
|
||||
keyBytes, err := key.Raw()
|
||||
if err != nil {
|
||||
return tokenKey, err
|
||||
}
|
||||
keyReader := hkdf.New(sha256.New, keyBytes, nil, []byte(tokenGeneratorKeyInfo))
|
||||
if _, err := io.ReadFull(keyReader, tokenKey[:]); err != nil {
|
||||
return tokenKey, err
|
||||
}
|
||||
return tokenKey, nil
|
||||
}
|
@ -74,6 +74,10 @@ type ConnManager interface {
|
||||
// then it will return true if the peer is protected for any tag
|
||||
IsProtected(id peer.ID, tag string) (protected bool)
|
||||
|
||||
// CheckLimit will return an error if the connection manager's internal
|
||||
// connection limit exceeds the provided system limit.
|
||||
CheckLimit(l GetConnLimiter) error
|
||||
|
||||
// Close closes the connection manager and stops background processes.
|
||||
Close() error
|
||||
}
|
||||
@ -89,3 +93,9 @@ type TagInfo struct {
|
||||
// Conns maps connection ids (such as remote multiaddr) to their creation time.
|
||||
Conns map[string]time.Time
|
||||
}
|
||||
|
||||
// GetConnLimiter provides access to a component's total connection limit.
|
||||
type GetConnLimiter interface {
|
||||
// GetConnLimit returns the total connection limit of the implementing component.
|
||||
GetConnLimit() int
|
||||
}
|
||||
|
@ -21,4 +21,5 @@ func (NullConnMgr) Notifee() network.Notifiee { return network.Gl
|
||||
func (NullConnMgr) Protect(peer.ID, string) {}
|
||||
func (NullConnMgr) Unprotect(peer.ID, string) bool { return false }
|
||||
func (NullConnMgr) IsProtected(peer.ID, string) bool { return false }
|
||||
func (NullConnMgr) CheckLimit(l GetConnLimiter) error { return nil }
|
||||
func (NullConnMgr) Close() error { return nil }
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
@ -12,8 +13,6 @@ import (
|
||||
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
|
||||
"github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
// ECDSAPrivateKey is an implementation of an ECDSA private key
|
||||
|
@ -25,7 +25,7 @@ func TestECDSABasicSignAndVerify(t *testing.T) {
|
||||
}
|
||||
|
||||
if !ok {
|
||||
t.Fatal("signature didnt match")
|
||||
t.Fatal("signature didn't match")
|
||||
}
|
||||
|
||||
// change data
|
||||
|
@ -4,12 +4,10 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
@ -129,51 +127,6 @@ func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, e
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateEKeyPair returns an ephemeral public key and returns a function that will compute
|
||||
// the shared secret key. Used in the identify module.
|
||||
//
|
||||
// Focuses only on ECDH now, but can be made more general in the future.
|
||||
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
|
||||
var curve elliptic.Curve
|
||||
|
||||
switch curveName {
|
||||
case "P-256":
|
||||
curve = elliptic.P256()
|
||||
case "P-384":
|
||||
curve = elliptic.P384()
|
||||
case "P-521":
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown curve name")
|
||||
}
|
||||
|
||||
priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pubKey := elliptic.Marshal(curve, x, y)
|
||||
|
||||
done := func(theirPub []byte) ([]byte, error) {
|
||||
// Verify and unpack node's public key.
|
||||
x, y := elliptic.Unmarshal(curve, theirPub)
|
||||
if x == nil {
|
||||
return nil, fmt.Errorf("malformed public key: %d %v", len(theirPub), theirPub)
|
||||
}
|
||||
|
||||
if !curve.IsOnCurve(x, y) {
|
||||
return nil, errors.New("invalid public key")
|
||||
}
|
||||
|
||||
// Generate shared secret.
|
||||
secret, _ := curve.ScalarMult(x, y, priv)
|
||||
|
||||
return secret.Bytes(), nil
|
||||
}
|
||||
|
||||
return pubKey, done, nil
|
||||
}
|
||||
|
||||
// UnmarshalPublicKey converts a protobuf serialized public key into its
|
||||
// representative object
|
||||
func UnmarshalPublicKey(data []byte) (PubKey, error) {
|
||||
|
@ -8,19 +8,19 @@ import (
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cloudflare/circl/sign/ed448"
|
||||
. "github.com/libp2p/go-libp2p/core/crypto"
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/test"
|
||||
|
||||
"github.com/cloudflare/circl/sign/ed448"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
secp256k1ecdsa "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
|
||||
"github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
func TestKeys(t *testing.T) {
|
||||
@ -307,15 +307,3 @@ func testKeyEquals(t *testing.T, k Key) {
|
||||
t.Fatal("Keys should not equal.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnknownCurveErrors(t *testing.T) {
|
||||
_, _, err := GenerateEKeyPair("P-256")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, _, err = GenerateEKeyPair("error-please")
|
||||
if err == nil {
|
||||
t.Fatal("expected invalid key type to error")
|
||||
}
|
||||
}
|
||||
|
@ -28,16 +28,16 @@ func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) {
|
||||
pub, _ := pubIfc.(ed25519.PublicKey)
|
||||
return &Ed25519PrivateKey{*p}, &Ed25519PublicKey{pub}, nil
|
||||
|
||||
case *secp256k1.PrivateKey:
|
||||
sPriv := Secp256k1PrivateKey(*p)
|
||||
sPub := Secp256k1PublicKey(*p.PubKey())
|
||||
return &sPriv, &sPub, nil
|
||||
|
||||
case *ed448.PrivateKey:
|
||||
pubIfc := p.Public()
|
||||
pub, _ := pubIfc.(ed448.PublicKey)
|
||||
return &Ed448PrivateKey{*p}, &Ed448PublicKey{pub}, nil
|
||||
|
||||
case *secp256k1.PrivateKey:
|
||||
sPriv := Secp256k1PrivateKey(*p)
|
||||
sPub := Secp256k1PublicKey(*p.PubKey())
|
||||
return &sPriv, &sPub, nil
|
||||
|
||||
default:
|
||||
return nil, nil, ErrBadKeyType
|
||||
}
|
||||
@ -56,10 +56,10 @@ func PrivKeyToStdKey(priv PrivKey) (crypto.PrivateKey, error) {
|
||||
return p.priv, nil
|
||||
case *Ed25519PrivateKey:
|
||||
return &p.k, nil
|
||||
case *Secp256k1PrivateKey:
|
||||
return p, nil
|
||||
case *Ed448PrivateKey:
|
||||
return &p.k, nil
|
||||
case *Secp256k1PrivateKey:
|
||||
return p, nil
|
||||
default:
|
||||
return nil, ErrBadKeyType
|
||||
}
|
||||
@ -78,10 +78,10 @@ func PubKeyToStdKey(pub PubKey) (crypto.PublicKey, error) {
|
||||
return p.pub, nil
|
||||
case *Ed25519PublicKey:
|
||||
return p.k, nil
|
||||
case *Secp256k1PublicKey:
|
||||
return p, nil
|
||||
case *Ed448PublicKey:
|
||||
return p.k, nil
|
||||
case *Secp256k1PublicKey:
|
||||
return p, nil
|
||||
default:
|
||||
return nil, ErrBadKeyType
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ var (
|
||||
1: "Ed25519",
|
||||
2: "Secp256k1",
|
||||
3: "ECDSA",
|
||||
4: "Ed448",
|
||||
}
|
||||
KeyType_value = map[string]int32{
|
||||
"RSA": 0,
|
||||
|
@ -4,14 +4,13 @@ import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
pb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||
"github.com/libp2p/go-libp2p/core/internal/catch"
|
||||
|
||||
"github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
// RsaPrivateKey is a rsa private key
|
||||
|
@ -24,7 +24,7 @@ func TestRSABasicSignAndVerify(t *testing.T) {
|
||||
}
|
||||
|
||||
if !ok {
|
||||
t.Fatal("signature didnt match")
|
||||
t.Fatal("signature didn't match")
|
||||
}
|
||||
|
||||
// change data
|
||||
|
@ -1,6 +1,7 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
@ -9,7 +10,6 @@ import (
|
||||
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
|
||||
"github.com/minio/sha256-simd"
|
||||
)
|
||||
|
||||
// Secp256k1PrivateKey is a Secp256k1 private key
|
||||
|
@ -24,7 +24,7 @@ func TestSecp256k1BasicSignAndVerify(t *testing.T) {
|
||||
}
|
||||
|
||||
if !ok {
|
||||
t.Fatal("signature didnt match")
|
||||
t.Fatal("signature didn't match")
|
||||
}
|
||||
|
||||
// change data
|
||||
|
@ -1,11 +1,40 @@
|
||||
package event
|
||||
|
||||
import "github.com/libp2p/go-libp2p/core/peer"
|
||||
import (
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/protocol"
|
||||
"github.com/libp2p/go-libp2p/core/record"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// EvtPeerIdentificationCompleted is emitted when the initial identification round for a peer is completed.
|
||||
type EvtPeerIdentificationCompleted struct {
|
||||
// Peer is the ID of the peer whose identification succeeded.
|
||||
Peer peer.ID
|
||||
|
||||
// Conn is the connection we identified.
|
||||
Conn network.Conn
|
||||
|
||||
// ListenAddrs is the list of addresses the peer is listening on.
|
||||
ListenAddrs []multiaddr.Multiaddr
|
||||
|
||||
// Protocols is the list of protocols the peer advertised on this connection.
|
||||
Protocols []protocol.ID
|
||||
|
||||
// SignedPeerRecord is the provided signed peer record of the peer. May be nil.
|
||||
SignedPeerRecord *record.Envelope
|
||||
|
||||
// AgentVersion is like a UserAgent string in browsers, or client version in
|
||||
// bittorrent includes the client name and client.
|
||||
AgentVersion string
|
||||
|
||||
// ProtocolVersion is the protocolVersion field in the identify message
|
||||
ProtocolVersion string
|
||||
|
||||
// ObservedAddr is the our side's connection address as observed by the
|
||||
// peer. This is not verified, the peer could return anything here.
|
||||
ObservedAddr multiaddr.Multiaddr
|
||||
}
|
||||
|
||||
// EvtPeerIdentificationFailed is emitted when the initial identification round for a peer failed.
|
||||
|
@ -13,12 +13,12 @@ var DialPeerTimeout = 60 * time.Second
|
||||
type noDialCtxKey struct{}
|
||||
type dialPeerTimeoutCtxKey struct{}
|
||||
type forceDirectDialCtxKey struct{}
|
||||
type useTransientCtxKey struct{}
|
||||
type allowLimitedConnCtxKey struct{}
|
||||
type simConnectCtxKey struct{ isClient bool }
|
||||
|
||||
var noDial = noDialCtxKey{}
|
||||
var forceDirectDial = forceDirectDialCtxKey{}
|
||||
var useTransient = useTransientCtxKey{}
|
||||
var allowLimitedConn = allowLimitedConnCtxKey{}
|
||||
var simConnectIsServer = simConnectCtxKey{}
|
||||
var simConnectIsClient = simConnectCtxKey{isClient: true}
|
||||
|
||||
@ -94,15 +94,35 @@ func WithDialPeerTimeout(ctx context.Context, timeout time.Duration) context.Con
|
||||
return context.WithValue(ctx, dialPeerTimeoutCtxKey{}, timeout)
|
||||
}
|
||||
|
||||
// WithUseTransient constructs a new context with an option that instructs the network
|
||||
// that it is acceptable to use a transient connection when opening a new stream.
|
||||
func WithUseTransient(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, useTransient, reason)
|
||||
// WithAllowLimitedConn constructs a new context with an option that instructs
|
||||
// the network that it is acceptable to use a limited connection when opening a
|
||||
// new stream.
|
||||
func WithAllowLimitedConn(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, allowLimitedConn, reason)
|
||||
}
|
||||
|
||||
// GetUseTransient returns true if the use transient option is set in the context.
|
||||
func GetUseTransient(ctx context.Context) (usetransient bool, reason string) {
|
||||
v := ctx.Value(useTransient)
|
||||
// WithUseTransient constructs a new context with an option that instructs the network
|
||||
// that it is acceptable to use a transient connection when opening a new stream.
|
||||
//
|
||||
// Deprecated: Use WithAllowLimitedConn instead.
|
||||
func WithUseTransient(ctx context.Context, reason string) context.Context {
|
||||
return context.WithValue(ctx, allowLimitedConn, reason)
|
||||
}
|
||||
|
||||
// GetAllowLimitedConn returns true if the allow limited conn option is set in the context.
|
||||
func GetAllowLimitedConn(ctx context.Context) (usetransient bool, reason string) {
|
||||
v := ctx.Value(allowLimitedConn)
|
||||
if v != nil {
|
||||
return true, v.(string)
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// GetUseTransient returns true if the use transient option is set in the context.
|
||||
//
|
||||
// Deprecated: Use GetAllowLimitedConn instead.
|
||||
func GetUseTransient(ctx context.Context) (usetransient bool, reason string) {
|
||||
v := ctx.Value(allowLimitedConn)
|
||||
if v != nil {
|
||||
return true, v.(string)
|
||||
}
|
||||
|
@ -47,13 +47,13 @@ func TestSimultaneousConnect(t *testing.T) {
|
||||
ok, isClient, reason := GetSimultaneousConnect(serverCtx)
|
||||
require.True(t, ok)
|
||||
require.False(t, isClient)
|
||||
require.Equal(t, reason, "foobar")
|
||||
require.Equal(t, "foobar", reason)
|
||||
})
|
||||
t.Run("for the client", func(t *testing.T) {
|
||||
serverCtx := WithSimultaneousConnect(context.Background(), true, "foo")
|
||||
ok, isClient, reason := GetSimultaneousConnect(serverCtx)
|
||||
require.True(t, ok)
|
||||
require.True(t, isClient)
|
||||
require.Equal(t, reason, "foo")
|
||||
require.Equal(t, "foo", reason)
|
||||
})
|
||||
}
|
||||
|
@ -22,7 +22,13 @@ var ErrNoConn = errors.New("no usable connection to peer")
|
||||
|
||||
// ErrTransientConn is returned when attempting to open a stream to a peer with only a transient
|
||||
// connection, without specifying the UseTransient option.
|
||||
var ErrTransientConn = errors.New("transient connection to peer")
|
||||
//
|
||||
// Deprecated: Use ErrLimitedConn instead.
|
||||
var ErrTransientConn = ErrLimitedConn
|
||||
|
||||
// ErrLimitedConn is returned when attempting to open a stream to a peer with only a conn
|
||||
// connection, without specifying the AllowLimitedConn option.
|
||||
var ErrLimitedConn = errors.New("limited connection to peer")
|
||||
|
||||
// ErrResourceLimitExceeded is returned when attempting to perform an operation that would
|
||||
// exceed system resource limits.
|
||||
|
@ -1,5 +1,10 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ConnManagementScope)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package mocknetwork -destination mock_conn_management_scope.go github.com/libp2p/go-libp2p/core/network ConnManagementScope
|
||||
//
|
||||
|
||||
// Package mocknetwork is a generated GoMock package.
|
||||
package mocknetwork
|
||||
@ -7,9 +12,9 @@ package mocknetwork
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
network "github.com/libp2p/go-libp2p/core/network"
|
||||
peer "github.com/libp2p/go-libp2p/core/peer"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockConnManagementScope is a mock of ConnManagementScope interface.
|
||||
@ -83,7 +88,7 @@ func (m *MockConnManagementScope) ReleaseMemory(arg0 int) {
|
||||
}
|
||||
|
||||
// ReleaseMemory indicates an expected call of ReleaseMemory.
|
||||
func (mr *MockConnManagementScopeMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnManagementScopeMockRecorder) ReleaseMemory(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockConnManagementScope)(nil).ReleaseMemory), arg0)
|
||||
}
|
||||
@ -97,7 +102,7 @@ func (m *MockConnManagementScope) ReserveMemory(arg0 int, arg1 byte) error {
|
||||
}
|
||||
|
||||
// ReserveMemory indicates an expected call of ReserveMemory.
|
||||
func (mr *MockConnManagementScopeMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockConnManagementScopeMockRecorder) ReserveMemory(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockConnManagementScope)(nil).ReserveMemory), arg0, arg1)
|
||||
}
|
||||
@ -111,7 +116,7 @@ func (m *MockConnManagementScope) SetPeer(arg0 peer.ID) error {
|
||||
}
|
||||
|
||||
// SetPeer indicates an expected call of SetPeer.
|
||||
func (mr *MockConnManagementScopeMockRecorder) SetPeer(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockConnManagementScopeMockRecorder) SetPeer(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPeer", reflect.TypeOf((*MockConnManagementScope)(nil).SetPeer), arg0)
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/libp2p/go-libp2p/core/network (interfaces: PeerScope)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package mocknetwork -destination mock_peer_scope.go github.com/libp2p/go-libp2p/core/network PeerScope
|
||||
//
|
||||
|
||||
// Package mocknetwork is a generated GoMock package.
|
||||
package mocknetwork
|
||||
@ -7,9 +12,9 @@ package mocknetwork
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
network "github.com/libp2p/go-libp2p/core/network"
|
||||
peer "github.com/libp2p/go-libp2p/core/peer"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockPeerScope is a mock of PeerScope interface.
|
||||
@ -71,7 +76,7 @@ func (m *MockPeerScope) ReleaseMemory(arg0 int) {
|
||||
}
|
||||
|
||||
// ReleaseMemory indicates an expected call of ReleaseMemory.
|
||||
func (mr *MockPeerScopeMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockPeerScopeMockRecorder) ReleaseMemory(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockPeerScope)(nil).ReleaseMemory), arg0)
|
||||
}
|
||||
@ -85,7 +90,7 @@ func (m *MockPeerScope) ReserveMemory(arg0 int, arg1 byte) error {
|
||||
}
|
||||
|
||||
// ReserveMemory indicates an expected call of ReserveMemory.
|
||||
func (mr *MockPeerScopeMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockPeerScopeMockRecorder) ReserveMemory(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockPeerScope)(nil).ReserveMemory), arg0, arg1)
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ProtocolScope)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package mocknetwork -destination mock_protocol_scope.go github.com/libp2p/go-libp2p/core/network ProtocolScope
|
||||
//
|
||||
|
||||
// Package mocknetwork is a generated GoMock package.
|
||||
package mocknetwork
|
||||
@ -7,9 +12,9 @@ package mocknetwork
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
network "github.com/libp2p/go-libp2p/core/network"
|
||||
protocol "github.com/libp2p/go-libp2p/core/protocol"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockProtocolScope is a mock of ProtocolScope interface.
|
||||
@ -71,7 +76,7 @@ func (m *MockProtocolScope) ReleaseMemory(arg0 int) {
|
||||
}
|
||||
|
||||
// ReleaseMemory indicates an expected call of ReleaseMemory.
|
||||
func (mr *MockProtocolScopeMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockProtocolScopeMockRecorder) ReleaseMemory(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockProtocolScope)(nil).ReleaseMemory), arg0)
|
||||
}
|
||||
@ -85,7 +90,7 @@ func (m *MockProtocolScope) ReserveMemory(arg0 int, arg1 byte) error {
|
||||
}
|
||||
|
||||
// ReserveMemory indicates an expected call of ReserveMemory.
|
||||
func (mr *MockProtocolScopeMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockProtocolScopeMockRecorder) ReserveMemory(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockProtocolScope)(nil).ReserveMemory), arg0, arg1)
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ResourceManager)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package mocknetwork -destination mock_resource_manager.go github.com/libp2p/go-libp2p/core/network ResourceManager
|
||||
//
|
||||
|
||||
// Package mocknetwork is a generated GoMock package.
|
||||
package mocknetwork
|
||||
@ -7,11 +12,11 @@ package mocknetwork
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
network "github.com/libp2p/go-libp2p/core/network"
|
||||
peer "github.com/libp2p/go-libp2p/core/peer"
|
||||
protocol "github.com/libp2p/go-libp2p/core/protocol"
|
||||
multiaddr "github.com/multiformats/go-multiaddr"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockResourceManager is a mock of ResourceManager interface.
|
||||
@ -61,7 +66,7 @@ func (m *MockResourceManager) OpenConnection(arg0 network.Direction, arg1 bool,
|
||||
}
|
||||
|
||||
// OpenConnection indicates an expected call of OpenConnection.
|
||||
func (mr *MockResourceManagerMockRecorder) OpenConnection(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceManagerMockRecorder) OpenConnection(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenConnection", reflect.TypeOf((*MockResourceManager)(nil).OpenConnection), arg0, arg1, arg2)
|
||||
}
|
||||
@ -76,7 +81,7 @@ func (m *MockResourceManager) OpenStream(arg0 peer.ID, arg1 network.Direction) (
|
||||
}
|
||||
|
||||
// OpenStream indicates an expected call of OpenStream.
|
||||
func (mr *MockResourceManagerMockRecorder) OpenStream(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceManagerMockRecorder) OpenStream(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OpenStream", reflect.TypeOf((*MockResourceManager)(nil).OpenStream), arg0, arg1)
|
||||
}
|
||||
@ -90,7 +95,7 @@ func (m *MockResourceManager) ViewPeer(arg0 peer.ID, arg1 func(network.PeerScope
|
||||
}
|
||||
|
||||
// ViewPeer indicates an expected call of ViewPeer.
|
||||
func (mr *MockResourceManagerMockRecorder) ViewPeer(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceManagerMockRecorder) ViewPeer(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewPeer", reflect.TypeOf((*MockResourceManager)(nil).ViewPeer), arg0, arg1)
|
||||
}
|
||||
@ -104,7 +109,7 @@ func (m *MockResourceManager) ViewProtocol(arg0 protocol.ID, arg1 func(network.P
|
||||
}
|
||||
|
||||
// ViewProtocol indicates an expected call of ViewProtocol.
|
||||
func (mr *MockResourceManagerMockRecorder) ViewProtocol(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceManagerMockRecorder) ViewProtocol(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewProtocol", reflect.TypeOf((*MockResourceManager)(nil).ViewProtocol), arg0, arg1)
|
||||
}
|
||||
@ -118,7 +123,7 @@ func (m *MockResourceManager) ViewService(arg0 string, arg1 func(network.Service
|
||||
}
|
||||
|
||||
// ViewService indicates an expected call of ViewService.
|
||||
func (mr *MockResourceManagerMockRecorder) ViewService(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceManagerMockRecorder) ViewService(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewService", reflect.TypeOf((*MockResourceManager)(nil).ViewService), arg0, arg1)
|
||||
}
|
||||
@ -132,7 +137,7 @@ func (m *MockResourceManager) ViewSystem(arg0 func(network.ResourceScope) error)
|
||||
}
|
||||
|
||||
// ViewSystem indicates an expected call of ViewSystem.
|
||||
func (mr *MockResourceManagerMockRecorder) ViewSystem(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceManagerMockRecorder) ViewSystem(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewSystem", reflect.TypeOf((*MockResourceManager)(nil).ViewSystem), arg0)
|
||||
}
|
||||
@ -146,7 +151,7 @@ func (m *MockResourceManager) ViewTransient(arg0 func(network.ResourceScope) err
|
||||
}
|
||||
|
||||
// ViewTransient indicates an expected call of ViewTransient.
|
||||
func (mr *MockResourceManagerMockRecorder) ViewTransient(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceManagerMockRecorder) ViewTransient(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ViewTransient", reflect.TypeOf((*MockResourceManager)(nil).ViewTransient), arg0)
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/libp2p/go-libp2p/core/network (interfaces: ResourceScopeSpan)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package mocknetwork -destination mock_resource_scope_span.go github.com/libp2p/go-libp2p/core/network ResourceScopeSpan
|
||||
//
|
||||
|
||||
// Package mocknetwork is a generated GoMock package.
|
||||
package mocknetwork
|
||||
@ -7,8 +12,8 @@ package mocknetwork
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
network "github.com/libp2p/go-libp2p/core/network"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockResourceScopeSpan is a mock of ResourceScopeSpan interface.
|
||||
@ -68,7 +73,7 @@ func (m *MockResourceScopeSpan) ReleaseMemory(arg0 int) {
|
||||
}
|
||||
|
||||
// ReleaseMemory indicates an expected call of ReleaseMemory.
|
||||
func (mr *MockResourceScopeSpanMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceScopeSpanMockRecorder) ReleaseMemory(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockResourceScopeSpan)(nil).ReleaseMemory), arg0)
|
||||
}
|
||||
@ -82,7 +87,7 @@ func (m *MockResourceScopeSpan) ReserveMemory(arg0 int, arg1 byte) error {
|
||||
}
|
||||
|
||||
// ReserveMemory indicates an expected call of ReserveMemory.
|
||||
func (mr *MockResourceScopeSpanMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockResourceScopeSpanMockRecorder) ReserveMemory(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockResourceScopeSpan)(nil).ReserveMemory), arg0, arg1)
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/libp2p/go-libp2p/core/network (interfaces: StreamManagementScope)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package mocknetwork -destination mock_stream_management_scope.go github.com/libp2p/go-libp2p/core/network StreamManagementScope
|
||||
//
|
||||
|
||||
// Package mocknetwork is a generated GoMock package.
|
||||
package mocknetwork
|
||||
@ -7,9 +12,9 @@ package mocknetwork
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
network "github.com/libp2p/go-libp2p/core/network"
|
||||
protocol "github.com/libp2p/go-libp2p/core/protocol"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockStreamManagementScope is a mock of StreamManagementScope interface.
|
||||
@ -97,7 +102,7 @@ func (m *MockStreamManagementScope) ReleaseMemory(arg0 int) {
|
||||
}
|
||||
|
||||
// ReleaseMemory indicates an expected call of ReleaseMemory.
|
||||
func (mr *MockStreamManagementScopeMockRecorder) ReleaseMemory(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamManagementScopeMockRecorder) ReleaseMemory(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseMemory", reflect.TypeOf((*MockStreamManagementScope)(nil).ReleaseMemory), arg0)
|
||||
}
|
||||
@ -111,7 +116,7 @@ func (m *MockStreamManagementScope) ReserveMemory(arg0 int, arg1 byte) error {
|
||||
}
|
||||
|
||||
// ReserveMemory indicates an expected call of ReserveMemory.
|
||||
func (mr *MockStreamManagementScopeMockRecorder) ReserveMemory(arg0, arg1 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamManagementScopeMockRecorder) ReserveMemory(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReserveMemory", reflect.TypeOf((*MockStreamManagementScope)(nil).ReserveMemory), arg0, arg1)
|
||||
}
|
||||
@ -139,7 +144,7 @@ func (m *MockStreamManagementScope) SetProtocol(arg0 protocol.ID) error {
|
||||
}
|
||||
|
||||
// SetProtocol indicates an expected call of SetProtocol.
|
||||
func (mr *MockStreamManagementScopeMockRecorder) SetProtocol(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamManagementScopeMockRecorder) SetProtocol(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetProtocol", reflect.TypeOf((*MockStreamManagementScope)(nil).SetProtocol), arg0)
|
||||
}
|
||||
@ -153,7 +158,7 @@ func (m *MockStreamManagementScope) SetService(arg0 string) error {
|
||||
}
|
||||
|
||||
// SetService indicates an expected call of SetService.
|
||||
func (mr *MockStreamManagementScopeMockRecorder) SetService(arg0 interface{}) *gomock.Call {
|
||||
func (mr *MockStreamManagementScopeMockRecorder) SetService(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetService", reflect.TypeOf((*MockStreamManagementScope)(nil).SetService), arg0)
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package mocknetwork
|
||||
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocknetwork -destination mock_resource_manager.go github.com/libp2p/go-libp2p/core/network ResourceManager"
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocknetwork -destination mock_conn_management_scope.go github.com/libp2p/go-libp2p/core/network ConnManagementScope"
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocknetwork -destination mock_stream_management_scope.go github.com/libp2p/go-libp2p/core/network StreamManagementScope"
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocknetwork -destination mock_peer_scope.go github.com/libp2p/go-libp2p/core/network PeerScope"
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocknetwork -destination mock_protocol_scope.go github.com/libp2p/go-libp2p/core/network ProtocolScope"
|
||||
//go:generate sh -c "go run github.com/golang/mock/mockgen -package mocknetwork -destination mock_resource_scope_span.go github.com/libp2p/go-libp2p/core/network ResourceScopeSpan"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocknetwork -destination mock_resource_manager.go github.com/libp2p/go-libp2p/core/network ResourceManager"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocknetwork -destination mock_conn_management_scope.go github.com/libp2p/go-libp2p/core/network ConnManagementScope"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocknetwork -destination mock_stream_management_scope.go github.com/libp2p/go-libp2p/core/network StreamManagementScope"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocknetwork -destination mock_peer_scope.go github.com/libp2p/go-libp2p/core/network PeerScope"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocknetwork -destination mock_protocol_scope.go github.com/libp2p/go-libp2p/core/network ProtocolScope"
|
||||
//go:generate sh -c "go run go.uber.org/mock/mockgen -package mocknetwork -destination mock_resource_scope_span.go github.com/libp2p/go-libp2p/core/network ResourceScopeSpan"
|
||||
|
@ -55,16 +55,23 @@ const (
|
||||
// Connected means has an open, live connection to peer
|
||||
Connected
|
||||
|
||||
// Deprecated: CanConnect is deprecated and will be removed in a future release.
|
||||
//
|
||||
// CanConnect means recently connected to peer, terminated gracefully
|
||||
CanConnect
|
||||
|
||||
// Deprecated: CannotConnect is deprecated and will be removed in a future release.
|
||||
//
|
||||
// CannotConnect means recently attempted connecting but failed to connect.
|
||||
// (should signal "made effort, failed")
|
||||
CannotConnect
|
||||
|
||||
// Limited means we have a transient connection to the peer, but aren't fully connected.
|
||||
Limited
|
||||
)
|
||||
|
||||
func (c Connectedness) String() string {
|
||||
str := [...]string{"NotConnected", "Connected", "CanConnect", "CannotConnect"}
|
||||
str := [...]string{"NotConnected", "Connected", "CanConnect", "CannotConnect", "Limited"}
|
||||
if c < 0 || int(c) >= len(str) {
|
||||
return unrecognized
|
||||
}
|
||||
@ -111,8 +118,10 @@ type Stats struct {
|
||||
Direction Direction
|
||||
// Opened is the timestamp when this connection was opened.
|
||||
Opened time.Time
|
||||
// Transient indicates that this connection is transient and may be closed soon.
|
||||
Transient bool
|
||||
// Limited indicates that this connection is Limited. It maybe limited by
|
||||
// bytes or time. In practice, this is a connection formed over a circuit v2
|
||||
// relay.
|
||||
Limited bool
|
||||
// Extra stores additional metadata about this connection.
|
||||
Extra map[interface{}]interface{}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ func AddrInfoFromP2pAddr(m ma.Multiaddr) (*AddrInfo, error) {
|
||||
|
||||
// AddrInfoToP2pAddrs converts an AddrInfo to a list of Multiaddrs.
|
||||
func AddrInfoToP2pAddrs(pi *AddrInfo) ([]ma.Multiaddr, error) {
|
||||
p2ppart, err := ma.NewComponent("p2p", Encode(pi.ID))
|
||||
p2ppart, err := ma.NewComponent("p2p", pi.ID.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -102,7 +102,7 @@ func AddrInfoToP2pAddrs(pi *AddrInfo) ([]ma.Multiaddr, error) {
|
||||
|
||||
func (pi *AddrInfo) Loggable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"peerID": pi.ID.Pretty(),
|
||||
"peerID": pi.ID.String(),
|
||||
"addrs": pi.Addrs,
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ package peer_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
|
||||
. "github.com/libp2p/go-libp2p/core/peer"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -19,7 +19,7 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
maddrPeer = ma.StringCast("/p2p/" + Encode(testID))
|
||||
maddrPeer = ma.StringCast("/p2p/" + testID.String())
|
||||
maddrTpt = ma.StringCast("/ip4/127.0.0.1/tcp/1234")
|
||||
maddrFull = maddrTpt.Encapsulate(maddrPeer)
|
||||
}
|
||||
@ -115,7 +115,7 @@ func TestAddrInfosFromP2pAddrs(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, info := range infos {
|
||||
exaddrs, ok := expected[info.ID.Pretty()]
|
||||
exaddrs, ok := expected[info.ID.String()]
|
||||
if !ok {
|
||||
t.Fatalf("didn't expect peer %s", info.ID)
|
||||
}
|
||||
@ -129,7 +129,7 @@ func TestAddrInfosFromP2pAddrs(t *testing.T) {
|
||||
t.Fatalf("expected %s, got %s", exaddrs[i], addr)
|
||||
}
|
||||
}
|
||||
delete(expected, info.ID.Pretty())
|
||||
delete(expected, info.ID.String())
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ func TestAddrInfoJSON(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if addrInfo.ID != testID {
|
||||
t.Fatalf("expected ID to equal %s, got %s", testID.Pretty(), addrInfo.ID.Pretty())
|
||||
t.Fatalf("expected ID to equal %s, got %s", testID, addrInfo.ID)
|
||||
}
|
||||
if len(addrInfo.Addrs) != 1 || !addrInfo.Addrs[0].Equal(maddrFull) {
|
||||
t.Fatalf("expected addrs to match %v, got %v", maddrFull, addrInfo.Addrs)
|
||||
|
@ -41,12 +41,6 @@ const maxInlineKeyLength = 42
|
||||
// hash output as a multihash. See IDFromPublicKey for details.
|
||||
type ID string
|
||||
|
||||
// Pretty returns a base58-encoded string representation of the ID.
|
||||
// Deprecated: use String() instead.
|
||||
func (id ID) Pretty() string {
|
||||
return id.String()
|
||||
}
|
||||
|
||||
// Loggable returns a pretty peer ID string in loggable JSON format.
|
||||
func (id ID) Loggable() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
@ -145,16 +139,6 @@ func Decode(s string) (ID, error) {
|
||||
return FromCid(c)
|
||||
}
|
||||
|
||||
// Encode encodes a peer ID as a string.
|
||||
//
|
||||
// At the moment, it base58 encodes the peer ID but, in the future, it will
|
||||
// switch to encoding it as a CID by default.
|
||||
//
|
||||
// Deprecated: use id.String instead.
|
||||
func Encode(id ID) string {
|
||||
return id.String()
|
||||
}
|
||||
|
||||
// FromCid converts a CID to a peer ID, if possible.
|
||||
func FromCid(c cid.Cid) (ID, error) {
|
||||
code := mc.Code(c.Type())
|
||||
|
@ -45,7 +45,7 @@ func (id ID) Size() int {
|
||||
}
|
||||
|
||||
func (id ID) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(Encode(id))
|
||||
return json.Marshal(id.String())
|
||||
}
|
||||
|
||||
func (id *ID) UnmarshalJSON(data []byte) (err error) {
|
||||
@ -59,7 +59,7 @@ func (id *ID) UnmarshalJSON(data []byte) (err error) {
|
||||
|
||||
// MarshalText returns the text encoding of the ID.
|
||||
func (id ID) MarshalText() ([]byte, error) {
|
||||
return []byte(Encode(id)), nil
|
||||
return []byte(id.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText restores the ID from its text encoding.
|
||||
|
@ -28,9 +28,10 @@ var (
|
||||
|
||||
// RecentlyConnectedAddrTTL is used when we recently connected to a peer.
|
||||
// It means that we are reasonably certain of the peer's address.
|
||||
RecentlyConnectedAddrTTL = time.Minute * 30
|
||||
RecentlyConnectedAddrTTL = time.Minute * 15
|
||||
|
||||
// OwnObservedAddrTTL is used for our own external addresses observed by peers.
|
||||
// Deprecated: observed addresses are maintained till we disconnect from the peer which provided it
|
||||
OwnObservedAddrTTL = time.Minute * 30
|
||||
)
|
||||
|
||||
|
@ -76,7 +76,7 @@ type Routing interface {
|
||||
ValueStore
|
||||
|
||||
// Bootstrap allows callers to hint to the routing system to get into a
|
||||
// Boostrapped state and remain there. It is not a synchronous call.
|
||||
// Bootstrapped state and remain there. It is not a synchronous call.
|
||||
Bootstrap(context.Context) error
|
||||
|
||||
// TODO expose io.Closer or plain-old Close error
|
||||
|
@ -3,6 +3,7 @@ package sec
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
@ -29,3 +30,14 @@ type SecureTransport interface {
|
||||
// ID is the protocol ID of the security protocol.
|
||||
ID() protocol.ID
|
||||
}
|
||||
|
||||
type ErrPeerIDMismatch struct {
|
||||
Expected peer.ID
|
||||
Actual peer.ID
|
||||
}
|
||||
|
||||
func (e ErrPeerIDMismatch) Error() string {
|
||||
return fmt.Sprintf("peer id mismatch: expected %s, but remote key matches %s", e.Expected, e.Actual)
|
||||
}
|
||||
|
||||
var _ error = (*ErrPeerIDMismatch)(nil)
|
||||
|
@ -5,6 +5,7 @@ package transport
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
@ -124,3 +125,47 @@ type Upgrader interface {
|
||||
// Upgrade upgrades the multiaddr/net connection into a full libp2p-transport connection.
|
||||
Upgrade(ctx context.Context, t Transport, maconn manet.Conn, dir network.Direction, p peer.ID, scope network.ConnManagementScope) (CapableConn, error)
|
||||
}
|
||||
|
||||
// DialUpdater provides updates on in progress dials.
|
||||
type DialUpdater interface {
|
||||
// DialWithUpdates dials a remote peer and provides updates on the passed channel.
|
||||
DialWithUpdates(context.Context, ma.Multiaddr, peer.ID, chan<- DialUpdate) (CapableConn, error)
|
||||
}
|
||||
|
||||
// DialUpdateKind indicates the type of DialUpdate event.
|
||||
type DialUpdateKind int
|
||||
|
||||
const (
|
||||
// UpdateKindDialFailed indicates dial failed.
|
||||
UpdateKindDialFailed DialUpdateKind = iota
|
||||
// UpdateKindDialSuccessful indicates dial succeeded.
|
||||
UpdateKindDialSuccessful
|
||||
// UpdateKindHandshakeProgressed indicates successful completion of the TCP 3-way
|
||||
// handshake
|
||||
UpdateKindHandshakeProgressed
|
||||
)
|
||||
|
||||
func (k DialUpdateKind) String() string {
|
||||
switch k {
|
||||
case UpdateKindDialFailed:
|
||||
return "DialFailed"
|
||||
case UpdateKindDialSuccessful:
|
||||
return "DialSuccessful"
|
||||
case UpdateKindHandshakeProgressed:
|
||||
return "UpdateKindHandshakeProgressed"
|
||||
default:
|
||||
return fmt.Sprintf("DialUpdateKind<Unknown-%d>", k)
|
||||
}
|
||||
}
|
||||
|
||||
// DialUpdate is used by DialUpdater to provide dial updates.
|
||||
type DialUpdate struct {
|
||||
// Kind is the kind of update event.
|
||||
Kind DialUpdateKind
|
||||
// Addr is the peer's address.
|
||||
Addr ma.Multiaddr
|
||||
// Conn is the resulting connection on success.
|
||||
Conn CapableConn
|
||||
// Err is the reason for dial failure.
|
||||
Err error
|
||||
}
|
||||
|
@ -3,6 +3,20 @@
|
||||
This directory contains prebuilt dashboards (provided as JSON files) for various components.
|
||||
For steps on how to import and use them [please read the official Grafana documentation.](https://grafana.com/docs/grafana/latest/dashboards/export-import/#import-dashboard)
|
||||
|
||||
## Public dashboards
|
||||
|
||||
You can check the following prebuilt dashboards in action:
|
||||
|
||||
1. [AutoNAT](https://protocollabs.grafana.net/public-dashboards/fce8fdeb629742c89bd70f0ce38dfd97)
|
||||
2. [Auto Relay](https://protocollabs.grafana.net/public-dashboards/380d52aded12404e9cf6ceccb824b7f9)
|
||||
3. [Eventbus](https://protocollabs.grafana.net/public-dashboards/048029ac2d7e4a71b281ffea3535026e)
|
||||
4. [Identify](https://protocollabs.grafana.net/public-dashboards/96b70328253d47c0b352dfae06f12a1b)
|
||||
5. [Relay Service](https://protocollabs.grafana.net/public-dashboards/4a8cb5d245294893874ed65279b049be)
|
||||
6. [Swarm](https://protocollabs.grafana.net/public-dashboards/2bd3f1bee9964d40b6786fbe3eafd9fc)
|
||||
|
||||
These metrics come from one of the public IPFS DHT [bootstrap nodes](https://docs.ipfs.tech/concepts/nodes/#bootstrap) run by Protocol Labs.
|
||||
At the time of writing (2023-08), these nodes handle many connections across various libp2p implementations, versions, and configurations (they don't handle large file transfers).
|
||||
|
||||
## Using locally
|
||||
|
||||
For local development and debugging, it can be useful to spin up a local Prometheus and Grafana instance.
|
||||
|
@ -730,7 +730,7 @@
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "libp2p autonat",
|
||||
"title": "go-libp2p autonat",
|
||||
"uid": "YNWSyiJ4k",
|
||||
"version": 5,
|
||||
"weekStart": ""
|
||||
|
@ -26,3 +26,4 @@ services:
|
||||
- ./identify/identify.json:/var/lib/grafana/dashboards/identify.json
|
||||
- ./relaysvc/relaysvc.json:/var/lib/grafana/dashboards/relaysvc.json
|
||||
- ./swarm/swarm.json:/var/lib/grafana/dashboards/swarm.json
|
||||
- ./resource-manager/resource-manager.json:/var/lib/grafana/dashboards/resource-manager.json
|
||||
|
@ -554,7 +554,7 @@
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "libp2p EventBus",
|
||||
"title": "go-libp2p EventBus",
|
||||
"uid": "ZFbI6NAVn",
|
||||
"version": 4,
|
||||
"weekStart": ""
|
||||
|
@ -1129,7 +1129,7 @@
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "libp2p Hole Punches",
|
||||
"title": "go-libp2p Hole Punches",
|
||||
"uid": "Ao24vOBVk",
|
||||
"version": 6,
|
||||
"weekStart": ""
|
||||
|
@ -877,7 +877,7 @@
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "libp2p Identify",
|
||||
"title": "go-libp2p Identify",
|
||||
"uid": "0NDzQQ0Vz",
|
||||
"version": 2,
|
||||
"weekStart": ""
|
||||
|
@ -1229,7 +1229,7 @@
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "libp2p Relay Service",
|
||||
"title": "go-libp2p Relay Service",
|
||||
"uid": "C6RUfAx4z",
|
||||
"version": 5,
|
||||
"weekStart": ""
|
||||
|
@ -1821,7 +1821,7 @@
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "libp2p Resource Manager",
|
||||
"title": "go-libp2p Resource Manager",
|
||||
"uid": "MgmGIjjnj",
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
|
@ -232,9 +232,7 @@
|
||||
"options": {
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -1139,9 +1137,7 @@
|
||||
},
|
||||
"pieType": "pie",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -1816,9 +1812,7 @@
|
||||
},
|
||||
"pieType": "pie",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -2016,9 +2010,7 @@
|
||||
},
|
||||
"pieType": "pie",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -2110,9 +2102,7 @@
|
||||
},
|
||||
"pieType": "pie",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -2205,9 +2195,7 @@
|
||||
},
|
||||
"pieType": "pie",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -2251,7 +2239,113 @@
|
||||
},
|
||||
"mappings": []
|
||||
},
|
||||
"overrides": []
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "canceled: concurrent dial successful"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "super-light-blue",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "application canceled"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "blue",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "canceled: other"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "dark-blue",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "timeout"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "orange",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "other"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "red",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "deadline"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "super-light-orange",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "connection refused"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "green",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
@ -2261,16 +2355,16 @@
|
||||
},
|
||||
"id": 15,
|
||||
"options": {
|
||||
"displayLabels": [],
|
||||
"legend": {
|
||||
"displayMode": "list",
|
||||
"displayMode": "table",
|
||||
"placement": "right",
|
||||
"showLegend": true
|
||||
"showLegend": true,
|
||||
"values": ["percent"]
|
||||
},
|
||||
"pieType": "donut",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -2542,9 +2636,7 @@
|
||||
},
|
||||
"pieType": "pie",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -2688,22 +2780,16 @@
|
||||
},
|
||||
"id": 38,
|
||||
"options": {
|
||||
"displayLabels": [
|
||||
"percent"
|
||||
],
|
||||
"displayLabels": ["percent"],
|
||||
"legend": {
|
||||
"displayMode": "table",
|
||||
"placement": "right",
|
||||
"showLegend": true,
|
||||
"values": [
|
||||
"percent"
|
||||
]
|
||||
"values": ["percent"]
|
||||
},
|
||||
"pieType": "donut",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -2795,7 +2881,7 @@
|
||||
"uid": "${DS_PROMETHEUS}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "sum(increase(libp2p_swarm_dial_ranking_delay_seconds_bucket{instance=~\"$instance\",le=\"inf\"}[$__range])) - ignoring(le) sum(increase(libp2p_swarm_dial_ranking_delay_seconds_bucket{instance=~\"$instance\",le=\"0.75\"}[$__range]))",
|
||||
"expr": "sum(increase(libp2p_swarm_dial_ranking_delay_seconds_bucket{instance=~\"$instance\",le=\"+Inf\"}[$__range])) - ignoring(le) sum(increase(libp2p_swarm_dial_ranking_delay_seconds_bucket{instance=~\"$instance\",le=\"0.75\"}[$__range]))",
|
||||
"hide": false,
|
||||
"legendFormat": ">750ms",
|
||||
"range": true,
|
||||
@ -2926,23 +3012,16 @@
|
||||
},
|
||||
"id": 42,
|
||||
"options": {
|
||||
"displayLabels": [
|
||||
"percent",
|
||||
"name"
|
||||
],
|
||||
"displayLabels": ["percent", "name"],
|
||||
"legend": {
|
||||
"displayMode": "table",
|
||||
"placement": "right",
|
||||
"showLegend": true,
|
||||
"values": [
|
||||
"percent"
|
||||
]
|
||||
"values": ["percent"]
|
||||
},
|
||||
"pieType": "donut",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
@ -3186,15 +3265,13 @@
|
||||
"justifyMode": "auto",
|
||||
"orientation": "horizontal",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "value_and_name"
|
||||
},
|
||||
"pluginVersion": "9.3.6",
|
||||
"pluginVersion": "10.0.1",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
@ -3222,7 +3299,7 @@
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"max": 10,
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
@ -3250,16 +3327,14 @@
|
||||
"options": {
|
||||
"orientation": "vertical",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"calcs": ["lastNotNull"],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true
|
||||
},
|
||||
"pluginVersion": "9.3.6",
|
||||
"pluginVersion": "10.0.1",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
@ -3275,12 +3350,12 @@
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Black Hole Filter Success Percentage",
|
||||
"title": "Dial Success Rate",
|
||||
"type": "gauge"
|
||||
}
|
||||
],
|
||||
"refresh": false,
|
||||
"schemaVersion": 37,
|
||||
"refresh": "",
|
||||
"schemaVersion": 38,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
@ -3312,7 +3387,6 @@
|
||||
"refId": "StandardVariableQuery"
|
||||
},
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 0,
|
||||
"type": "query"
|
||||
@ -3320,13 +3394,13 @@
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"from": "now-15m",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "libp2p Swarm",
|
||||
"title": "go-libp2p Swarm",
|
||||
"uid": "a15PyhO4z",
|
||||
"version": 7,
|
||||
"version": 4,
|
||||
"weekStart": ""
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ import (
|
||||
// Useful when you want to extend, but not replace, the supported transport
|
||||
// security protocols.
|
||||
var DefaultSecurity = ChainOptions(
|
||||
Security(noise.ID, noise.New),
|
||||
Security(tls.ID, tls.New),
|
||||
Security(noise.ID, noise.New),
|
||||
)
|
||||
|
||||
// DefaultMuxers configures libp2p to use the stream connection multiplexers.
|
||||
@ -79,11 +79,9 @@ var RandomIdentity = func(cfg *Config) error {
|
||||
var DefaultListenAddrs = func(cfg *Config) error {
|
||||
addrs := []string{
|
||||
"/ip4/0.0.0.0/tcp/0",
|
||||
"/ip4/0.0.0.0/udp/0/quic",
|
||||
"/ip4/0.0.0.0/udp/0/quic-v1",
|
||||
"/ip4/0.0.0.0/udp/0/quic-v1/webtransport",
|
||||
"/ip6/::/tcp/0",
|
||||
"/ip6/::/udp/0/quic",
|
||||
"/ip6/::/udp/0/quic-v1",
|
||||
"/ip6/::/udp/0/quic-v1/webtransport",
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ processes are vying for CPU time.
|
||||
sudo cgset -r cpu.cfs_quota_us=10000 cpulimit
|
||||
sudo cgset -r cpu.cfs_period_us=1000000 cpulimit
|
||||
|
||||
# Run a shell with in our limited environemnt
|
||||
# Run a shell with in our limited environment
|
||||
sudo cgexec -g cpu:cpulimit bash
|
||||
|
||||
# In the shell, run the test
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user