├── .gitignore ├── .gitmodules ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── cgconfig.conf.tmpl ├── cgconfigparser.service.tmpl ├── cgrules.conf.tmpl ├── cgrulesgend.service.tmpl ├── config-bsc.json ├── config-heco.json ├── config-hecotest.json ├── config-okchain.json ├── config.json ├── config.toml.tmpl ├── configuration ├── config.go └── config_test.go ├── dos.sh ├── dos_docker.sh ├── dosnode ├── dos_chain_handler.go ├── dos_query_handler.go ├── dos_restapis.go ├── dos_stages.go ├── dos_stages_test.go ├── dosnode.go └── dosnode_test.go ├── geth.service ├── geth.service.tmpl ├── go.mod ├── go.sum ├── group ├── bn256 │ ├── LICENSE │ ├── README.md │ ├── constants.go │ ├── curve.go │ ├── gfp.go │ ├── gfp.h │ ├── gfp.s │ ├── gfp12.go │ ├── gfp2.go │ ├── gfp6.go │ ├── group.go │ ├── mul.h │ ├── mul_bmi2.h │ ├── optate.go │ ├── point.go │ ├── suite.go │ ├── suite_test.go │ └── twist.go ├── edwards25519 │ ├── LICENSE │ ├── allow_test.go │ ├── allowvt_test.go │ ├── const.go │ ├── curve.go │ ├── curve_test.go │ ├── elligator.go │ ├── elligator_test_go │ ├── fe.go │ ├── ge.go │ ├── ge_mult.go │ ├── ge_mult_vartime.go │ ├── point.go │ ├── point_vartime.go │ ├── scalar.go │ ├── scalar_test.go │ └── suite.go ├── internal │ └── marshalling │ │ └── marshal.go ├── mod │ ├── int.go │ └── int_test.go └── nist │ ├── curve.go │ ├── doc.go │ ├── group_test.go │ ├── p256.go │ ├── qrsuite.go │ ├── residue.go │ └── suite.go ├── log ├── logger.go └── root.go ├── main.go ├── media └── logo-white.jpg ├── onchain ├── chain_adaptor.go ├── commitreveal │ ├── CommitReveal.abi │ ├── CommitReveal.bin │ ├── CommitReveal.go │ ├── DOSAddressBridgeI.abi │ └── DOSAddressBridgeI.bin ├── dosbridge │ ├── DOSAddressBridge.abi │ ├── DOSAddressBridge.bin │ ├── DOSAddressBridge.go │ ├── Ownable.abi │ └── Ownable.bin ├── dospayment │ ├── DOSAddressBridgeInterface.abi │ ├── DOSAddressBridgeInterface.bin │ ├── DOSPayment.abi │ ├── DOSPayment.bin │ ├── DOSPayment.go │ ├── ERC20.abi │ └── ERC20.bin ├── dosproxy │ ├── BN256.abi │ ├── BN256.bin │ ├── DOSProxy.abi │ ├── DOSProxy.bin │ ├── DOSProxy.go │ ├── ICommitReveal.abi │ ├── ICommitReveal.bin │ ├── IDOSAddressBridge.abi │ ├── IDOSAddressBridge.bin │ ├── IDOSPayment.abi │ ├── IDOSPayment.bin │ ├── IDOSStaking.abi │ ├── IDOSStaking.bin │ ├── IUserContract.abi │ └── IUserContract.bin ├── dosstaking │ ├── AddressBridgeI.abi │ ├── AddressBridgeI.bin │ ├── DSMath.abi │ ├── DSMath.bin │ ├── ERC20I.abi │ ├── ERC20I.bin │ ├── Staking.abi │ ├── Staking.bin │ └── Staking.go ├── errors.go ├── eth_get.go ├── eth_helpers.go ├── eth_helpers_test.go ├── eth_proxy.go ├── eth_set.go ├── eth_subscribe.go ├── eventMsg.go └── request.go ├── p2p ├── client.go ├── client_test.go ├── discover │ ├── membership.go │ └── simulator.go ├── error.go ├── internal │ ├── package.pb.go │ └── package.proto ├── nat │ ├── nat.go │ ├── natpmp.go │ └── upnp.go ├── p2p_interface.go ├── package.pb.go ├── package.proto ├── request.go ├── server.go ├── server_test.go └── util.go ├── share ├── dkg │ └── pedersen │ │ ├── dkg.go │ │ ├── dkg.pb.go │ │ ├── dkg.proto │ │ ├── dkg_test.go │ │ ├── errorrs.go │ │ ├── pdkg.go │ │ ├── pdkg_pipes.go │ │ ├── pdkg_test.go │ │ └── request.go ├── poly.go ├── poly_test.go └── vss │ └── pedersen │ ├── dh.go │ ├── vss.go │ ├── vss.pb.go │ ├── vss.proto │ └── vss_test.go ├── sign ├── bls │ ├── bls.go │ └── bls_test.go ├── schnorr │ ├── schnorr.go │ └── schnorr_test.go └── tbls │ ├── tbls.go │ └── tbls_test.go ├── suites ├── all.go └── suites.go ├── upgrade.md ├── upgrade.sh └── utils └── utils.go /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | dosclient 3 | testAccounts/ 4 | credential/ 5 | vault/ 6 | .idea 7 | *.*.swp 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "onchain/eth"] 2 | path = onchain/eth 3 | url = https://github.com/DOSNetwork/smart-contracts 4 | branch = master 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.13 as builder 2 | ENV GOPROXY=https://goproxy.cn,direct 3 | WORKDIR /go/src/github.com/DOSNetwork/core 4 | COPY go.mod . 5 | COPY go.sum . 6 | RUN go mod download 7 | COPY . . 8 | RUN env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 && make client-static 9 | 10 | FROM alpine:latest 11 | RUN apk --no-cache add ca-certificates 12 | COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ 13 | COPY --from=builder /go/src/github.com/DOSNetwork/core/dosclient / 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | MIT License 3 | 4 | Copyright (c) 2018 DOS NETWORK 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .DEFAULT_GOAL := build 2 | 3 | DOSPROXY_PATH := onchain/eth/contracts/DOSProxy.sol 4 | DOSPROXY_GOPATH := onchain/dosproxy 5 | DOSPAYMENT_GOPATH := onchain/dospayment 6 | DOSBRIDGE_GOPATH := onchain/dosbridge 7 | COMMITREVEAL_GOPATH := onchain/commitreveal 8 | DOSSTAKING_GOPATH := onchain/dosstaking 9 | GENERATED_FILES := $(shell find $(DOSPROXY_GOPATH) $(DOSBRIDGE_GOPATH) $(DOSPAYMENT_GOPATH) $(DOSSTAKING_GOPATH) $(COMMITREVEAL_GOPATH) -name '*.go' -o -name '*.abi' -o -name '*.bin') 10 | ETH_CONTRACTS := onchain/eth/contracts 11 | BOOT_CREDENTIAL := testAccounts/bootCredential 12 | UNAME_S := $(shell uname -s) 13 | 14 | VERSION=`git describe --tags` 15 | BUILD=`date +%FT%T%z` 16 | 17 | # Setup the -ldflags option for go build here, interpolate the variable values 18 | LDFLAGS_STATIC=-ldflags "-linkmode external -extldflags -static -w -s -X main.Version=${VERSION} -X main.Build=${BUILD}" 19 | LDFLAGS=-ldflags "-w -s -X main.Version=${VERSION} -X main.Build=${BUILD}" 20 | 21 | .PHONY: build 22 | build: client 23 | 24 | 25 | .PHONY: devClient 26 | # Build a development version client node 27 | devClient: gen 28 | go build -a -o dosclient.dev 29 | 30 | 31 | .PHONY: client 32 | # Build a prod/release version client node 33 | client: 34 | go build ${LDFLAGS} -o dosclient 35 | 36 | client-static: 37 | go build ${LDFLAGS_STATIC} -o dosclient 38 | 39 | .PHONY: client-docker 40 | client-docker: 41 | docker build -t dosnode -f Dockerfile . 42 | 43 | 44 | .PHONY: install 45 | install: client 46 | go install ${LDFLAGS} 47 | 48 | 49 | .PHONY: updateSubmodule 50 | updateSubmodule: 51 | test -f $(DOSPROXY_PATH) || git submodule update --init --recursive 52 | git submodule update --remote 53 | 54 | 55 | .PHONY: gen 56 | gen: updateSubmodule 57 | solc --optimize --overwrite --abi --bin $(ETH_CONTRACTS)/DOSAddressBridge.sol -o $(DOSBRIDGE_GOPATH) 58 | abigen --abi="$(DOSBRIDGE_GOPATH)/DOSAddressBridge.abi" --bin="$(DOSBRIDGE_GOPATH)/DOSAddressBridge.bin" --pkg dosbridge --out $(DOSBRIDGE_GOPATH)/DOSAddressBridge.go 59 | solc --optimize --overwrite --abi --bin $(ETH_CONTRACTS)/DOSProxy.sol -o $(DOSPROXY_GOPATH) 60 | abigen --abi="$(DOSPROXY_GOPATH)/DOSProxy.abi" --bin="$(DOSPROXY_GOPATH)/DOSProxy.bin" --pkg dosproxy --out $(DOSPROXY_GOPATH)/DOSProxy.go 61 | solc --optimize --overwrite --abi --bin $(ETH_CONTRACTS)/DOSPayment.sol -o $(DOSPAYMENT_GOPATH) 62 | abigen --abi="$(DOSPAYMENT_GOPATH)/DOSPayment.abi" --bin="$(DOSPAYMENT_GOPATH)/DOSPayment.bin" --pkg dospayment --out $(DOSPAYMENT_GOPATH)/DOSPayment.go 63 | solc --optimize --overwrite --abi --bin $(ETH_CONTRACTS)/CommitReveal.sol -o $(COMMITREVEAL_GOPATH) 64 | abigen --abi="$(COMMITREVEAL_GOPATH)/CommitReveal.abi" --bin="$(COMMITREVEAL_GOPATH)/CommitReveal.bin" --pkg commitreveal --out $(COMMITREVEAL_GOPATH)/CommitReveal.go 65 | solc --optimize --overwrite --abi --bin $(ETH_CONTRACTS)/Staking.sol -o $(DOSSTAKING_GOPATH) 66 | abigen --abi="$(DOSSTAKING_GOPATH)/Staking.abi" --bin="$(DOSSTAKING_GOPATH)/Staking.bin" --pkg staking --out $(DOSSTAKING_GOPATH)/Staking.go 67 | 68 | 69 | .PHONY: clean-gen 70 | clean-gen: 71 | @ rm -f $(GENERATED_FILES) 72 | 73 | 74 | .PHONY: clean 75 | clean: 76 | @ rm -f dosclient* 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DOS Client and Core Libraries 2 | [![Go Report Card](https://goreportcard.com/badge/github.com/DOSNetwork/core)](https://goreportcard.com/report/github.com/DOSNetwork/core) 3 | [![Maintainability](https://api.codeclimate.com/v1/badges/a2eb5767f8984835fb3b/maintainability)](https://codeclimate.com/github/DOSNetwork/core/maintainability) 4 | [![GoDoc](https://godoc.org/github.com/DOSNetwork/core?status.svg)](https://godoc.org/github.com/DOSNetwork/core) 5 | 6 | 7 | ## Prerequisites: 8 | ##### Cloud Server / VPS Recommendations 9 | - [AWS Lightsail](https://aws.amazon.com/lightsail/pricing) - Linux virtual server (1 cpu, 1GB memory, 40GB ssd, 2TB bandwidth) 10 | - [Google Cloud Platform](https://cloud.google.com) - Compute Engine General purpose (N2) 11 | - [Vultr](https://www.vultr.com/products/cloud-compute/) - Cloud Compute (1 cpu, 1GB memory, 25GB ssd, 1TB bandwidth) 12 | - [Digital Ocean](https://www.digitalocean.com/products/droplets/) - Droplet (1 cpu, 25GB ssd, 1TB bandwidth) 13 | - [Linode](https://www.linode.com/products/shared/) - Shared virtual Instances (1 cpu, 1GB memory, 25GB ssd, 1TB bandwidth) 14 | - [Others] 15 | 16 | ##### Verified and recommended installation environment 17 | - Ubuntu 18.04 x64 LTS or higher 18 | - An IPv4 address 19 | - Run `$ dig +short myip.opendns.com @resolver1.opendns.com` 20 | - Or get it from cloud server providers. Most vps / cloud server 21 | - With below ports open: 22 | - **udp** port `7946` 23 | - **tcp** port `7946`,`9501` 24 | - It's recommended to generate ssh login key pairs and setup public key authentication instead of using password login for server security and funds safety: 25 | - Learn [how to](https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys-on-ubuntu-1604) setup SSH public key authentication on Ubuntu 18.04 and disable password logins. 26 | 27 | 28 | ##### Bonding enough DOS tokens to run a node 29 | - Acquire at least 800,000 [DOS tokens](https://etherscan.io/address/0x70861e862e1ac0c96f853c8231826e469ead37b1), (and optional - acquire several [DropBurn token](https://etherscan.io/address/0x68423B3B0769c739D1fe4C398C3d91F0d646424f) to reduce (up to 30%) the amount of DOS tokens needed to start a node, distribution plan be out later). 30 | - Replace your node ip address in [config.json](https://github.com/DOSNetwork/core/blob/master/config.json#L3) 31 | - Node runners currently earn three types of incomes: (Self-bonded) staking rewards, (other delegators') staking reward shares, oracle request processing fees. 32 | 33 | 34 | ##### Register and setup Infura api key 35 | - Register and get [Infura api key](https://ethereumico.io/knowledge-base/infura-api-key-guide/) 36 | - Replace your infura api key in [config.json](https://github.com/DOSNetwork/core/blob/master/config.json#L11) 37 | 38 | 39 | 40 | ## Run with docker image 41 | - https://medium.com/dos-network/instructions-of-launching-a-node-in-dos-network-932e73a91a75 42 | 43 | 44 | ## Building binary from source 45 | - [Install](https://golang.org/doc/install) **go1.11 or higher** and setup golang workingspace like below: 46 | ```sh 47 | $ sudo apt-get install golang 48 | $ sudo apt-get install build-essential 49 | ``` 50 | 51 | - Open `~/.bashrc` and set `$GOPATH` and `$PATH` environmental variables: 52 | ```sh 53 | $ vim ~/.bashrc 54 | export GOPATH=$HOME/go 55 | export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin 56 | $ source ~/.bashrc 57 | ``` 58 | 59 | - Download source code: 60 | ```sh 61 | $ mkdir -p $GOPATH/src/github.com/DOSNetwork 62 | $ cd $GOPATH/src/github.com/DOSNetwork && git clone https://github.com/DOSNetwork/core.git 63 | $ cd core 64 | $ git checkout v1.0.4-m 65 | ``` 66 | 67 | - Build: 68 | - `$ GO111MODULE=on go mod download` - to download building dependencies 69 | - Dev dependencies: solc-v0.5.17, abigen-v1.9.18-stable 70 | - `$ make` - to build release version client 71 | 72 | - Run: 73 | ```sh 74 | $ ./dos.sh start 75 | ``` 76 | 77 | - Dev tips: 78 | - `$ go fmt ./...` to reformat go source code. 79 | - `$ golint` to fix style mistakes conflicting with [effective go](https://golang.org/doc/effective_go.html). ([golint](https://github.com/golang/lint) tool for vim users.) 80 | - `$ make devClient` to build develoment version client. 81 | - `$ make updateSubmodule` to fetch latest system contracts from [repo](https://github.com/DOSNetwork/eth-contracts), instead of making contract modifications locally. 82 | - `$ make gen` to generate binding files for system contracts. 83 | - `$ make clean` to remove built binaries or unnecessary generated files. 84 | - Use [solc-select](https://github.com/crytic/solc-select) tool to select / pin to specific solidity compiler version. 85 | -------------------------------------------------------------------------------- /cgconfig.conf.tmpl: -------------------------------------------------------------------------------- 1 | group dos/geth { 2 | cpu { 3 | cpu.shares = 400; 4 | } 5 | memory { 6 | memory.limit_in_bytes = 400000000; 7 | } 8 | } 9 | 10 | group dos/client { 11 | cpu { 12 | cpu.shares = 600; 13 | } 14 | memory { 15 | memory.limit_in_bytes = 600000000; 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /cgconfigparser.service.tmpl: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=cgroup config parser 3 | 4 | [Service] 5 | User=root 6 | Group=root 7 | ExecStart=/usr/sbin/cgconfigparser -l /etc/cgconfig.conf 8 | Type=oneshot 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /cgrules.conf.tmpl: -------------------------------------------------------------------------------- 1 | *:geth cpu,memory dos/geth/ 2 | *:client cpu,memory dos/client/ 3 | -------------------------------------------------------------------------------- /cgrulesgend.service.tmpl: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=cgroup rules generator 3 | After=cgconfigparser.service 4 | 5 | [Service] 6 | User=root 7 | Group=root 8 | Type=forking 9 | EnvironmentFile=-/etc/cgred.conf 10 | ExecStart=/usr/sbin/cgrulesengd 11 | Restart=on-failure 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /config-bsc.json: -------------------------------------------------------------------------------- 1 | { 2 | "VERSION": "v1.0.5-m", 3 | "NodeIP": "#REPLACE-WITH-IP", 4 | "NodePort": "9501", 5 | "ChainID": "56", 6 | "ChainType": "BSC", 7 | "BlockTime": "3", 8 | "DOSAddressBridgeAddress": "0x70157cf10404170EEc183043354D0a886Fa51d73", 9 | "EthGasLimit": "1000000", 10 | "EthGasPrice": "0", 11 | "BootStrapIPs": [ 12 | ], 13 | "ChainNodePool": [ 14 | "https://bsc-dataseed1.defibit.io/", 15 | "#REPLACE-WITH: https://docs.binance.org/smart-chain/developer/rpc.html#3rd-party-provider" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /config-heco.json: -------------------------------------------------------------------------------- 1 | { 2 | "VERSION": "v1.0.5-m", 3 | "NodeIP": "#REPLACE-WITH-IP", 4 | "NodePort": "9501", 5 | "ChainID": "128", 6 | "ChainType": "Heco", 7 | "BlockTime": "3", 8 | "DOSAddressBridgeAddress": "0x9Ee7F642d3955ecf17D7223705DCb285dbA679fc", 9 | "EthGasLimit": "1000000", 10 | "EthGasPrice": "0", 11 | "BootStrapIPs": [ 12 | ], 13 | "ChainNodePool": [ 14 | "wss://ws-mainnet.hecochain.com", 15 | "https://http-mainnet.hecochain.com" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /config-hecotest.json: -------------------------------------------------------------------------------- 1 | { 2 | "VERSION": "v1.0.5-m", 3 | "NodeIP": "#REPLACE-WITH-IP", 4 | "NodePort": "9501", 5 | "ChainID": "256", 6 | "ChainType": "Heco", 7 | "BlockTime": "3", 8 | "DOSAddressBridgeAddress": "0x797D0f474dDcAa8F4066A263684B540C074801b3", 9 | "EthGasLimit": "1000000", 10 | "EthGasPrice": "0", 11 | "BootStrapIPs": [ 12 | ], 13 | "ChainNodePool": [ 14 | "wss://ws-testnet.hecochain.com", 15 | "https://http-testnet.hecochain.com" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /config-okchain.json: -------------------------------------------------------------------------------- 1 | { 2 | "VERSION": "v1.0.5-m", 3 | "NodeIP": "#REPLACE-WITH-IP", 4 | "NodePort": "9501", 5 | "ChainID": "66", 6 | "ChainType": "Okchain", 7 | "BlockTime": "4", 8 | "DOSAddressBridgeAddress": "0xD1aFEa6D7745c9d168A77Abd80124A0592B0D48e", 9 | "EthGasLimit": "1000000", 10 | "EthGasPrice": "0", 11 | "BootStrapIPs": [ 12 | ], 13 | "ChainNodePool": [ 14 | "http://54.255.11.97:8545", 15 | "ws://54.255.11.97:8546" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "VERSION": "v1.0.5-m", 3 | "NodeIP": "#REPLACE-WITH-IP", 4 | "NodePort": "9501", 5 | "ChainID": "1", 6 | "ChainType": "ETH", 7 | "BlockTime": "14", 8 | "DOSAddressBridgeAddress": "0x98A0E7026778840Aacd28B9c03137D32e06F5ff1", 9 | "EthGasLimit": "1000000", 10 | "EthGasPrice": "0", 11 | "BootStrapIPs": [ 12 | ], 13 | "ChainNodePool": [ 14 | "wss://mainnet.infura.io/ws/v3/#REPLACE-WITH-INFURA-APIKEY", 15 | "https://mainnet.infura.io/v3/#REPLACE-WITH-INFURA-APIKEY" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /configuration/config.go: -------------------------------------------------------------------------------- 1 | package configuration 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "io/ioutil" 8 | "net" 9 | "os" 10 | "strings" 11 | ) 12 | 13 | const ( 14 | envChainType = "CHAINTYPE" 15 | envConfigPath = "CONFIGPATH" 16 | envBootStrapIP = "BOOTSTRAPIP" 17 | envNodeIP = "NODEIP" 18 | envNodePort = "NODEPORT" 19 | envGethPool = "GETHPOOL" 20 | defaultChainType = "ETH" 21 | defaultPort = "9501" 22 | ) 23 | 24 | var path string 25 | 26 | // Config is the configuration for creating a DOS client instance. 27 | type Config struct { 28 | VERSION string 29 | NodeIP string 30 | NodePort string 31 | ChainID string 32 | ChainType string 33 | BlockTime string 34 | DOSAddressBridgeAddress string 35 | EthGasLimit string 36 | EthGasPrice string 37 | BootStrapIPs []string 38 | ChainNodePool []string 39 | } 40 | 41 | // LoadConfig loads configuration file from path. 42 | func LoadConfig(path string, c interface{}) (err error) { 43 | var jsonFile *os.File 44 | var byteValue []byte 45 | 46 | fmt.Println("Path ", path) 47 | // Open our jsonFile 48 | jsonFile, err = os.Open(path) 49 | // if we os.Open returns an error then handle it 50 | if err != nil { 51 | fmt.Println("LoadConfig error ", err) 52 | return 53 | } 54 | fmt.Println("Successfully Opened json") 55 | // defer the closing of our jsonFile so that we can parse it later on 56 | defer jsonFile.Close() 57 | 58 | // read our opened xmlFile as a byte array. 59 | byteValue, err = ioutil.ReadAll(jsonFile) 60 | if err != nil { 61 | fmt.Println("ReadAll error ", err) 62 | return 63 | } 64 | 65 | err = json.Unmarshal(byteValue, &c) 66 | if err != nil { 67 | fmt.Println("Unmarshal error ", err) 68 | return 69 | } 70 | return 71 | } 72 | 73 | // LoadConfig loads configuration file from path. 74 | func (c *Config) LoadConfig() (err error) { 75 | path = os.Getenv(envConfigPath) 76 | if path == "" { 77 | path, err = os.Getwd() 78 | if err != nil { 79 | return 80 | } 81 | if path == "/" { 82 | path = "." 83 | } 84 | } 85 | path = path + "/config.json" 86 | 87 | err = LoadConfig(path, c) 88 | if err != nil { 89 | fmt.Println("LoadConfig err", err) 90 | return 91 | } 92 | err = c.overWrite() 93 | 94 | return 95 | } 96 | 97 | func (c *Config) overWrite() (err error) { 98 | ip := os.Getenv(envNodeIP) 99 | if ip != "" { 100 | testInput := net.ParseIP(ip) 101 | if testInput.To4() == nil { 102 | fmt.Printf("%v is not a valid IPv4 address\n", testInput) 103 | return errors.New("not a valid IPv4 address") 104 | } else { 105 | c.NodeIP = ip 106 | } 107 | } 108 | port := os.Getenv(envNodePort) 109 | if port != "" { 110 | c.NodePort = port 111 | } else if c.NodePort == "" { 112 | c.NodePort = defaultPort 113 | } 114 | 115 | chainType := os.Getenv(envChainType) 116 | if chainType != "" { 117 | c.ChainType = chainType 118 | } else if c.ChainType == "" { 119 | c.ChainType = defaultChainType 120 | } 121 | 122 | gethIP := os.Getenv(envGethPool) 123 | if gethIP != "" { 124 | nodeList := make(map[string]bool) 125 | for _, ethNode := range c.ChainNodePool { 126 | nodeList[ethNode] = true 127 | } 128 | ipPool := strings.Split(gethIP, ",") 129 | for _, ip := range ipPool { 130 | if !nodeList[ip] { 131 | c.ChainNodePool = append(c.ChainNodePool, ip) 132 | } 133 | } 134 | } 135 | return 136 | } 137 | 138 | // UpdateConfig saves configuration to a file. 139 | func (c *Config) UpdateConfig() (err error) { 140 | configJson, _ := json.MarshalIndent(c, "", " ") 141 | err = ioutil.WriteFile(path, configJson, 0644) 142 | return 143 | } 144 | -------------------------------------------------------------------------------- /configuration/config_test.go: -------------------------------------------------------------------------------- 1 | package configuration 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func TestLoadConfig(t *testing.T) { 12 | config := OffChainConfig{} 13 | LoadConfig("../offChain.json", &config) 14 | require.Equal(t, "BootstrapNode", config.NodeRole) 15 | 16 | config2 := OnChainConfig{} 17 | LoadConfig("../onChain.json", &config2) 18 | require.Equal(t, "ETH", config2.ChainConfigs[0].ChainType) 19 | } 20 | 21 | func TestOffChainReadConfig(t *testing.T) { 22 | config := OffChainConfig{} 23 | os.Setenv("CONFIGPATH", "..") 24 | config.LoadConfig() 25 | assert.Equal(t, "BootstrapNode", config.NodeRole) 26 | } 27 | 28 | func TestOnChainReadConfig(t *testing.T) { 29 | os.Setenv("CONFIGPATH", "..") 30 | os.Setenv("CHAINNODE", "rinkebyPrivateNode") 31 | config := OnChainConfig{} 32 | config.LoadConfig() 33 | 34 | actualResult := config.GetChainConfig().RemoteNodeType 35 | expectedResult := "rinkebyPrivateNode" 36 | 37 | require.Equal(t, expectedResult, actualResult) 38 | } 39 | 40 | func TestOnChainUpdate(t *testing.T) { 41 | config := OnChainConfig{} 42 | os.Setenv("CONFIGPATH", "..") 43 | os.Setenv("CHAINNODE", "rinkebyPrivateNode") 44 | config.LoadConfig() 45 | chainConfig := config.GetChainConfig() 46 | chainConfig.DOSAddressBridgeAddress = "0x12345" 47 | config.UpdateConfig(chainConfig) 48 | 49 | config.LoadConfig() 50 | chainConfig = config.GetChainConfig() 51 | actualResult := config.GetChainConfig().DOSAddressBridgeAddress 52 | expectedResult := "0x12345" 53 | 54 | require.Equal(t, expectedResult, actualResult) 55 | } 56 | -------------------------------------------------------------------------------- /dos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | RELEASE=$(grep VERSION config.json | awk '{print $2}'| sed -e 's/.*"\(.*\)".*/\1/') 3 | findNodeIP() { 4 | if [ -z "$nodeIP" ]; then 5 | nodeIP=$(host myip.opendns.com resolver1.opendns.com | grep "myip.opendns.com has address" | awk -F " " '{print $NF}') 6 | echo "node public IP :"$nodeIP 7 | echo -n "Press [Enter] to continue or reply no if IP is not correct:" 8 | read reply 9 | if [ "$reply" == "no" ]; then 10 | echo -n "Enter your public IP [Enter]: " 11 | read nodeIP 12 | fi 13 | fi 14 | } 15 | 16 | startClient() { 17 | mkdir -p $(pwd)/vault 18 | echo "1) Check if dosclient exists" 19 | if [ ! -f $(pwd)/dosclient ]; then 20 | URL="https://github.com/DOSNetwork/core/releases/download/"$RELEASE"/dosclient" 21 | echo "-->Downloading dosnode from "$URL 22 | wget $URL 23 | chmod +x dosclient 24 | fi 25 | if [ ! -f $(pwd)/dosclient ]; then 26 | echo "dosclient doesn't exist" 27 | exit 28 | fi 29 | echo "2) Check if config.json includes Infura API key" 30 | if grep -q "#REPLACE-WITH-INFURA-APIKEY" $(pwd)/config.json; then 31 | echo -n "Enter your infura api key [Enter]: " 32 | read apikey 33 | sed -i -e 's?#REPLACE-WITH-INFURA-APIKEY?'$apikey'?g' $(pwd)/config.json 34 | fi 35 | echo "3) Check if config.json includes a node public IP" 36 | if grep -q "#REPLACE-WITH-IP" $(pwd)/config.json; then 37 | findNodeIP 38 | sed -i -e 's?#REPLACE-WITH-IP?'$nodeIP'?g' $(pwd)/config.json 39 | fi 40 | echo "4) Check if node keystore exists" 41 | $(pwd)/dosclient wallet create 42 | echo -n Keystore Password [Enter]: 43 | read -s password 44 | echo "" 45 | export PASSPHRASE=$password 46 | echo "5) Run dosclient" 47 | nohup ./dosclient start >dos.out 2>&1 & 48 | sleep 3 49 | pgrep -x dosclient >/dev/null && echo "dosclient is running" || echo "dosclient is not running" 50 | } 51 | 52 | status() { 53 | curl http://localhost:8080/ 54 | if [ "$?" = "7" ]; then 55 | log 56 | fi 57 | } 58 | 59 | stop() { 60 | ./dosclient stop 61 | } 62 | 63 | log() { 64 | cat $(pwd)/vault/doslog.txt 65 | } 66 | 67 | case "$1" in 68 | "start") 69 | startClient 70 | ;; 71 | "stop") 72 | stop 73 | ;; 74 | "status") 75 | status 76 | ;; 77 | "log") 78 | log 79 | ;; 80 | *) 81 | echo "Usage: bash dos.sh [OPTION]" 82 | echo "OPTION:" 83 | echo " start Start dosclient from Docker Hub" 84 | echo " stop Stop dosclient" 85 | echo " status Show dosclient status" 86 | echo " log Show dosclient log" 87 | ;; 88 | esac 89 | -------------------------------------------------------------------------------- /dos_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | RELEASE=$(grep VERSION config.json | awk '{print $2}'| sed -e 's/.*"\(.*\)".*/\1/') 3 | install_docker() { 4 | if [ ! -x "$(command -v docker)" ]; then 5 | echo "Install docker" 6 | yes | sudo dpkg --configure -a 7 | yes | sudo apt-get update 8 | yes | sudo apt-get install docker.io 9 | sudo usermod -aG docker $USER 10 | echo "Rebooting!!!" 11 | yes | sudo reboot 12 | fi 13 | } 14 | 15 | uninstall_docker() { 16 | if [ -x "$(command -v docker)" ]; then 17 | sudo apt-get purge -y docker-engine docker docker.io docker-ce 18 | sudo apt-get autoremove -y --purge docker-engine docker docker.io docker-ce 19 | sudo rm -rf /var/lib/docker /etc/docker 20 | sudo rm /etc/apparmor.d/docker 21 | sudo groupdel docker 22 | sudo rm -rf /var/run/docker.sock 23 | fi 24 | } 25 | 26 | findNodeIP() { 27 | if [ -z "$nodeIP" ]; then 28 | nodeIP=$(host myip.opendns.com resolver1.opendns.com | grep "myip.opendns.com has address" | awk -F " " '{print $NF}') 29 | echo "node public IP :"$nodeIP 30 | echo -n "Press [Enter] to continue or no if IP is not correct:" 31 | read reply 32 | if [ "$reply" == "no" ]; then 33 | echo -n "Enter your public IP [Enter]: " 34 | read nodeIP 35 | fi 36 | fi 37 | } 38 | 39 | startClient() { 40 | mkdir -p $(pwd)/vault 41 | install_docker 42 | echo "1) Get dosclient from dosnetwork/dosnode:"$RELEASE 43 | docker pull dosnetwork/dosnode:$RELEASE 44 | echo "2) Check if config.json includes Infura API key" 45 | if grep -q "#REPLACE-WITH-INFURA-APIKEY" $(pwd)/config.json; then 46 | echo -n "Enter your infura api key [Enter]: " 47 | read apikey 48 | sed -i -e 's?#REPLACE-WITH-INFURA-APIKEY?'$apikey'?g' $(pwd)/config.json 49 | fi 50 | echo "3) Check if config.json includes a node public IP" 51 | if grep -q "#REPLACE-WITH-IP" $(pwd)/config.json; then 52 | findNodeIP 53 | sed -i -e 's?#REPLACE-WITH-IP?'$nodeIP'?g' $(pwd)/config.json 54 | fi 55 | echo "4) Check if node keystore exists" 56 | docker run -it --mount type=bind,source=$(pwd)/vault,target=/vault \ 57 | dosnetwork/dosnode:$RELEASE /dosclient wallet create 58 | echo "5) Run dosclient" 59 | echo -n Keystore Password [Enter]: 60 | read -s password 61 | docker run -it -d -p 7946:7946 -p 8080:8080 -p 9501:9501 \ 62 | --hostname $(hostname) \ 63 | --mount type=bind,source=$(pwd),target=/config \ 64 | --mount type=bind,source=$(pwd)/vault,target=/vault \ 65 | -e CONFIGPATH=config -e PASSPHRASE=$password \ 66 | dosnetwork/dosnode:$RELEASE /dosclient start 67 | sleep 3 68 | pgrep -x dosclient >/dev/null && echo "dosclient is running" || echo "dosclient is not running" 69 | } 70 | 71 | status() { 72 | curl http://localhost:8080/ 73 | if [ "$?" = "7" ]; then 74 | log 75 | fi 76 | } 77 | 78 | stop() { 79 | docker stop $(docker ps -a -q) 80 | } 81 | 82 | log() { 83 | cat $(pwd)/vault/doslog.txt 84 | } 85 | 86 | case "$1" in 87 | "start") 88 | startClient 89 | ;; 90 | "stop") 91 | stop 92 | ;; 93 | "status") 94 | status 95 | ;; 96 | "log") 97 | log 98 | ;; 99 | *) 100 | echo "Usage: bash dos_docker.sh [OPTION]" 101 | echo "OPTION:" 102 | echo " start Start dosclient from Docker Hub" 103 | echo " stop Stop dosclient" 104 | echo " status Show dosclient status" 105 | echo " log Show dosclient log" 106 | ;; 107 | esac 108 | -------------------------------------------------------------------------------- /dosnode/dos_query_handler.go: -------------------------------------------------------------------------------- 1 | package dosnode 2 | 3 | import ( 4 | "context" 5 | "crypto/sha256" 6 | "fmt" 7 | "math/big" 8 | "time" 9 | 10 | "github.com/DOSNetwork/core/onchain" 11 | "github.com/DOSNetwork/core/share" 12 | "github.com/DOSNetwork/core/share/vss/pedersen" 13 | ) 14 | 15 | func (d *DosNode) queryLoop() { 16 | defer d.logger.Info("End queryLoop") 17 | bufSign := make(map[string][]*vss.Signature) 18 | reqSign := make(map[string]request) 19 | peerMsg, _ := d.p.SubscribeMsg(50, vss.Signature{}) 20 | defer d.p.UnSubscribeMsg(vss.Signature{}) 21 | watchdog := time.NewTicker(30 * time.Minute) 22 | defer watchdog.Stop() 23 | for { 24 | select { 25 | case <-d.ctx.Done(): 26 | defer d.logger.Info("End queryLoop ctx.Done") 27 | return 28 | case <-watchdog.C: 29 | for _, req := range reqSign { 30 | select { 31 | case <-req.ctx.Done(): 32 | close(req.reply) 33 | delete(bufSign, req.requestID) 34 | delete(reqSign, req.requestID) 35 | default: 36 | } 37 | } 38 | case msg, ok := <-peerMsg: 39 | if ok { 40 | if content, ok := msg.Msg.Message.(*vss.Signature); ok { 41 | requestID := string(content.RequestId) 42 | if req := reqSign[requestID]; req.requestID == requestID { 43 | select { 44 | case <-req.ctx.Done(): 45 | case req.reply <- content: 46 | } 47 | } else { 48 | bufSign[requestID] = append(bufSign[requestID], content) 49 | } 50 | } 51 | } 52 | case req, ok := <-d.reqSignc: 53 | if ok { 54 | //1)Check buf to see if it has enough signatures 55 | reqSign[req.requestID] = req 56 | if signs := bufSign[req.requestID]; len(signs) >= 0 { 57 | for _, sign := range signs { 58 | select { 59 | case <-req.ctx.Done(): 60 | case req.reply <- sign: 61 | } 62 | } 63 | bufSign[req.requestID] = nil 64 | } 65 | } 66 | } 67 | } 68 | } 69 | 70 | func (d *DosNode) handleQuery(ids [][]byte, pubPoly *share.PubPoly, sec *share.PriShare, groupID string, requestID, lastRand, useSeed *big.Int, url, selector string, pType uint32) { 71 | queryCtx, cancel := context.WithTimeout(context.Background(), time.Duration(60*d.chain.GetBlockTime())*time.Second) 72 | defer cancel() 73 | queryCtxWithValue := context.WithValue(context.WithValue(queryCtx, ctxKey("RequestID"), fmt.Sprintf("%x", requestID)), ctxKey("GroupID"), groupID) 74 | d.logger.Event("HandleQuery", map[string]interface{}{"GroupID": groupID, "RequestID": fmt.Sprintf("%x", requestID)}) 75 | defer d.logger.TimeTrack(time.Now(), "TimeHandleQuery", map[string]interface{}{"GroupID": groupID, "RequestID": fmt.Sprintf("%x", requestID)}) 76 | defer cancel() 77 | var nonce []byte 78 | //Generate an unique id 79 | switch pType { 80 | case onchain.TrafficSystemRandom: 81 | var bytes []byte 82 | bytes = append(bytes, []byte(groupID)...) 83 | bytes = append(bytes, requestID.Bytes()...) 84 | bytes = append(bytes, lastRand.Bytes()...) 85 | nHash := sha256.Sum256(bytes) 86 | nonce = nHash[:] 87 | case onchain.TrafficUserRandom: 88 | var bytes []byte 89 | bytes = append(bytes, []byte(groupID)...) 90 | bytes = append(bytes, requestID.Bytes()...) 91 | bytes = append(bytes, lastRand.Bytes()...) 92 | bytes = append(bytes, useSeed.Bytes()...) 93 | nHash := sha256.Sum256(bytes) 94 | nonce = nHash[:] 95 | case onchain.TrafficUserQuery: 96 | var bytes []byte 97 | bytes = append(bytes, []byte(groupID)...) 98 | bytes = append(bytes, requestID.Bytes()...) 99 | bytes = append(bytes, lastRand.Bytes()...) 100 | bytes = append(bytes, []byte(url)...) 101 | bytes = append(bytes, []byte(selector)...) 102 | nHash := sha256.Sum256(bytes) 103 | nonce = nHash[:] 104 | } 105 | sign := &vss.Signature{ 106 | Index: pType, 107 | RequestId: requestID.Bytes(), 108 | Nonce: nonce, 109 | } 110 | //Build a pipeline 111 | var errcList []chan error 112 | 113 | submitterc, errc := choseSubmitter(queryCtxWithValue, d.p, d.chain, lastRand, ids, 2, d.logger) 114 | errcList = append(errcList, errc) 115 | 116 | var contentc chan []byte 117 | switch pType { 118 | case onchain.TrafficSystemRandom: 119 | contentc = genSysRandom(queryCtxWithValue, submitterc[0], lastRand.Bytes(), d.logger) 120 | case onchain.TrafficUserRandom: 121 | contentc = genUserRandom(queryCtxWithValue, submitterc[0], requestID.Bytes(), lastRand.Bytes(), useSeed.Bytes(), d.logger) 122 | case onchain.TrafficUserQuery: 123 | contentc, errc = genQueryResult(queryCtxWithValue, submitterc[0], url, selector, d.logger) 124 | errcList = append(errcList, errc) 125 | } 126 | 127 | signc, errc := genSign(queryCtxWithValue, contentc, sec, d.suite, sign, d.logger) 128 | errcList = append(errcList, errc) 129 | signAllc := dispatchSign(queryCtxWithValue, submitterc[1], signc, d.reqSignc, d.p, requestID.Bytes(), (len(ids)/2 + 1), d.logger) 130 | errcList = append(errcList, errc) 131 | recoveredSignc, errc := recoverSign(queryCtxWithValue, signAllc, d.suite, pubPoly, (len(ids)/2 + 1), len(ids), d.logger) 132 | errcList = append(errcList, errc) 133 | errcList = append(errcList, reportQueryResult(queryCtxWithValue, d.chain, pType, recoveredSignc)) 134 | 135 | allErrc := mergeErrors(queryCtxWithValue, errcList...) 136 | for { 137 | select { 138 | case err, ok := <-allErrc: 139 | if !ok { 140 | return 141 | } 142 | d.logger.Event("handleQueryError", map[string]interface{}{"Error": err.Error(), "GroupID": groupID}) 143 | case <-queryCtxWithValue.Done(): 144 | d.logger.Event("handleQueryError", map[string]interface{}{"Error": queryCtxWithValue.Err(), "GroupID": groupID}) 145 | return 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /dosnode/dos_stages_test.go: -------------------------------------------------------------------------------- 1 | package dosnode 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "math/big" 7 | "os" 8 | "testing" 9 | "time" 10 | 11 | "github.com/DOSNetwork/core/log" 12 | "github.com/DOSNetwork/core/onchain" 13 | "github.com/DOSNetwork/core/p2p" 14 | ) 15 | 16 | var ( 17 | urls = []string{"https://rinkeby.infura.io/v3/2a6901876ca54406960499e888e70439", "wss://rinkeby.infura.io/ws/v3/3a3e5d776961418e93a8b33fef2f6642"} 18 | proxyAddr = "0x3b8Cb935bDdFAF59EFa11aFfDfc8760387624fa2" 19 | crAddr = "0xE04B34A113BB707eCF8dc01D51f8A56213Bdcb81" 20 | credentialPath = "/Users/chenhaonien/go/src/github.com/DOSNetwork/core/testing/testAccounts/1/credential/" 21 | credential2Path = "/Users/chenhaonien/go/src/github.com/DOSNetwork/core/testing/testAccounts/2/credential/" 22 | credential3Path = "/Users/chenhaonien/go/src/github.com/DOSNetwork/core/testing/testAccounts/3/credential/" 23 | 24 | passphrase = "123" 25 | ) 26 | 27 | func buildComponents(port, credentialPath string, t *testing.T) (p2p.P2PInterface, onchain.ProxyAdapter) { 28 | key, err := onchain.ReadEthKey(credentialPath, passphrase) 29 | if err != nil { 30 | t.Errorf("TestChoseSubmitter Failed, got an error : %s.", err.Error()) 31 | } 32 | adaptor, err := onchain.NewEthAdaptor(key, proxyAddr, crAddr, urls) 33 | if err != nil { 34 | t.Errorf("TestChoseSubmitter Failed, got an Error : %s.", err.Error()) 35 | } 36 | adaptor.Start() 37 | nodeId := key.Address.Bytes() 38 | 39 | os.Setenv("PUBLICIP", "127.0.0.1") 40 | 41 | p, err := p2p.CreateP2PNetwork(nodeId, port, p2p.NoDiscover) 42 | if err != nil { 43 | t.Errorf("Error %s", err) 44 | } 45 | p.Listen() 46 | return p, adaptor 47 | } 48 | 49 | func TestChoseSubmitter(t *testing.T) { 50 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 51 | defer cancel() 52 | os.Setenv("LOGIP", "163.172.36.173:9500") 53 | log.Init([]byte{'a'}) 54 | 55 | p1, e1 := buildComponents("9905", credentialPath, t) 56 | p2, e2 := buildComponents("9904", credential2Path, t) 57 | p3, _ := buildComponents("9904", credential3Path, t) 58 | 59 | var ids [][]byte 60 | ids = append(ids, p1.GetID()) 61 | ids = append(ids, p2.GetID()) 62 | ids = append(ids, p3.GetID()) 63 | 64 | logger := log.New("module", "dostage") 65 | lastSysRand := big.NewInt(2) 66 | outCount := 1 67 | p1.SetPort("9904") 68 | _, _ = p1.ConnectTo(ctx, "127.0.0.1", nil) 69 | 70 | p2.SetPort("9905") 71 | _, _ = p2.ConnectTo(ctx, "127.0.0.1", nil) 72 | 73 | submitterc, errc := choseSubmitter(ctx, p1, e1, lastSysRand, ids, outCount, logger) 74 | select { 75 | case s := <-submitterc[0]: 76 | if string(s) == string(p3.GetID()) { 77 | t.Errorf("TestChoseSubmitter failed ") 78 | } 79 | case err := <-errc: 80 | fmt.Println("choseSubmitter err ", err) 81 | case <-ctx.Done(): 82 | t.Errorf("Error %s", ctx.Err()) 83 | } 84 | 85 | submitterc, errc = choseSubmitter(ctx, p2, e2, lastSysRand, ids, outCount, logger) 86 | select { 87 | case s := <-submitterc[0]: 88 | if string(s) == string(p3.GetID()) { 89 | t.Errorf("TestChoseSubmitter failed ") 90 | } 91 | case err := <-errc: 92 | fmt.Println("choseSubmitter err ", err) 93 | case <-ctx.Done(): 94 | t.Errorf("Error %s", ctx.Err()) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /dosnode/dosnode_test.go: -------------------------------------------------------------------------------- 1 | package dosnode 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPipeCheckURL(test *testing.T) { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /geth.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Geth Node 3 | After=network-online.target 4 | Wants=network-online.target 5 | 6 | [Service] 7 | ExecStart=/usr/bin/geth --datadir xxx/.rinkeby --networkid=4 --syncmode "light" --rpc --rpcport "8545" --rpcaddr "0.0.0.0" --rpccorsdomain "*" --ws --wsaddr 0.0.0.0 --wsorigins '*' --bootnodes=enode://a24ac7c5484ef4ed0c5eb2d36620ba4e4aa13b8c84684e1b4aab0cebea2ae45cb4d375b77eab56516d34bfbd3c1a833fc51296ff084b770b94fb9028c4d25ccf@52.169.42.101:30303,enode://6986a90dc17efce88197df61bb1079baff1cf367a4f613d67dcf5ce85a0956e77f11a25fa4f06a4c86187b4c6c7a054ac8a61346f3daf2d88c21cb7e98bf303c@18.236.117.126:30303,enode://9ea2d243b1a621518a901d8d2dcb6f5306e38a6f7e2c14e2f8d0c73f9edf5eef45d84e407727e2c32e06009a7ef28273676988ee54245040f383230ba8cf5e3e@18.236.199.131:30303,enode://22cfb9395a1699866c49c5dcd55e10dd9dd82c3633c6cdd6213e2bf2c0780491e4e19eba3d82f90ecfc62f1232871091b11fd0c72d63fea68f513bffd12021b8@18.236.80.51:30303,enode://40af478307e6d224b5a40b425db0dbdd4f99a736dd8dce53ae906048ff00b731204669334f2317f7872285dba414994e934f65bfe848cace344e2fb9d1e1b9f6@18.237.0.120:30303,enode://1ba15be53e3766b9386c8d066aa62d1b8fcb13159d43a033bfd9fe5ec6df4fd4548fc19f9cb3a5d8326e5aa10a235ca5b126d8267e4b13389bd92d9dc22c32ae@18.237.179.193:30303 8 | Restart=always 9 | RestartSec=5s 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /geth.service.tmpl: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Geth Node 3 | After=network-online.target 4 | Wants=network-online.target 5 | 6 | [Service] 7 | ExecStart=/usr/bin/geth --rinkeby --config #REPLACE-WITH-PATH/config.toml --datadir #REPLACE-WITH-PATH/.rinkeby --nat=extip:#REPLACE-WITH-IP --cache 256 --verbosity 4 8 | Restart=always 9 | RestartSec=5s 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/DOSNetwork/core 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/allegro/bigcache v1.2.1 // indirect 7 | github.com/antchfx/xmlquery v0.0.0-20181204011708-431a9e9e7c44 8 | github.com/antchfx/xpath v0.0.0-20181208024549-4bbdf6db12aa // indirect 9 | github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect 10 | github.com/bshuster-repo/logrus-logstash-hook v0.4.1 11 | github.com/cespare/cp v1.1.1 // indirect 12 | github.com/deckarep/golang-set v1.7.1 // indirect 13 | github.com/dedis/fixbuf v1.0.2 14 | github.com/dedis/kyber v0.0.0-20181211160045-59837fd0c24b 15 | github.com/dedis/protobuf v1.0.3 16 | github.com/ethereum/go-ethereum v1.10.9 17 | github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect 18 | github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect 19 | github.com/golang/protobuf v1.4.3 20 | github.com/hashicorp/go-msgpack v0.5.5 // indirect 21 | github.com/hashicorp/go-sockaddr v1.0.2 // indirect 22 | github.com/hashicorp/memberlist v0.1.4 // indirect 23 | github.com/hashicorp/serf v0.8.3 24 | github.com/huin/goupnp v1.0.2 25 | github.com/jackpal/gateway v1.0.5 26 | github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 27 | github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect 28 | github.com/jonboulle/clockwork v0.2.2 // indirect 29 | github.com/lestrrat-go/file-rotatelogs v2.2.0+incompatible 30 | github.com/lestrrat-go/strftime v1.0.0 // indirect 31 | github.com/miekg/dns v1.1.25 // indirect 32 | github.com/prometheus/tsdb v0.10.0 // indirect 33 | github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 34 | github.com/rjeczalik/notify v0.9.2 // indirect 35 | github.com/sirupsen/logrus v1.2.0 36 | github.com/spyzhov/ajson v0.4.2 37 | github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect 38 | github.com/stretchr/testify v1.7.0 39 | github.com/tebeka/strftime v0.1.5 // indirect 40 | github.com/tyler-smith/go-bip39 v1.1.0 // indirect 41 | github.com/urfave/cli v1.22.1 42 | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 43 | golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 44 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 45 | ) 46 | -------------------------------------------------------------------------------- /group/bn256/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /group/bn256/README.md: -------------------------------------------------------------------------------- 1 | bn256 2 | ----- 3 | 4 | Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig 5 | curve targeting a 128-bit security level as described in the paper 6 | [New Software Speed Records for Cryptocraphic Pairings](http://cryptojedi.org/papers/dclxvi-20100714.pdf). 7 | Its output is compatible with the implementation described in that paper. 8 | 9 | The basis for this package is [Cloudflare's bn256 implementation](https://github.com/cloudflare/bn256) 10 | which itself is an improved version of the [official bn256 package](https://golang.org/x/crypto/bn256). 11 | The package at hand maintains compatibility to Cloudflare's library. The biggest difference is the replacement of their 12 | [public API](https://github.com/cloudflare/bn256/blob/master/bn256.go) by a new 13 | one that is compatible to Kyber's scalar, point, group, and suite interfaces. 14 | 15 | [Bilinear groups](https://en.wikipedia.org/wiki/Pairing-based_cryptography) are 16 | the basis for many new cryptographic protocols that have been proposed over the 17 | past decade. They consist of a triplet of groups (G₁, G₂ and GT) such that there 18 | exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ is a generator of the respective 19 | group) which is called a pairing. 20 | 21 | 22 | -------------------------------------------------------------------------------- /group/bn256/constants.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | import ( 4 | "math/big" 5 | ) 6 | 7 | func bigFromBase10(s string) *big.Int { 8 | n, _ := new(big.Int).SetString(s, 10) 9 | return n 10 | } 11 | 12 | // u is the BN parameter that determines the prime: 1868033³. 13 | var u = bigFromBase10("4965661367192848881") 14 | 15 | // Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1. 16 | var Order = bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495617") 17 | 18 | // P is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1. 19 | var P = bigFromBase10("21888242871839275222246405745257275088696311157297823662689037894645226208583") 20 | 21 | // p2 is p, represented as little-endian 64-bit words. 22 | var p2 = [4]uint64{0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029} 23 | 24 | // np is the negative inverse of p, mod 2^256. 25 | var np = [4]uint64{0x87d20782e4866389, 0x9ede7d651eca6ac9, 0xd8afcbd01833da80, 0xf57a22b791888c6b} 26 | 27 | // rN1 is R^-1 where R = 2^256 mod p. 28 | var rN1 = &gfP{0xed84884a014afa37, 0xeb2022850278edf8, 0xcf63e9cfb74492d9, 0x2e67157159e5c639} 29 | 30 | // r2 is R^2 where R = 2^256 mod p. 31 | var r2 = &gfP{0xf32cfc5b538afa89, 0xb5e71911d44501fb, 0x47ab1eff0a417ff6, 0x06d89f71cab8351f} 32 | 33 | // r3 is R^3 where R = 2^256 mod p. 34 | var r3 = &gfP{0xb1cd6dafda1530df, 0x62f210e6a7283db6, 0xef7f0b0c0ada0afb, 0x20fd6e902d592544} 35 | 36 | // xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+9. 37 | var xiToPMinus1Over6 = &gfP2{gfP{0xa222ae234c492d72, 0xd00f02a4565de15b, 0xdc2ff3a253dfc926, 0x10a75716b3899551}, gfP{0xaf9ba69633144907, 0xca6b1d7387afb78a, 0x11bded5ef08a2087, 0x02f34d751a1f3a7c}} 38 | 39 | // xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+9. 40 | var xiToPMinus1Over3 = &gfP2{gfP{0x6e849f1ea0aa4757, 0xaa1c7b6d89f89141, 0xb6e713cdfae0ca3a, 0x26694fbb4e82ebc3}, gfP{0xb5773b104563ab30, 0x347f91c8a9aa6454, 0x7a007127242e0991, 0x1956bcd8118214ec}} 41 | 42 | // xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+9. 43 | var xiToPMinus1Over2 = &gfP2{gfP{0xa1d77ce45ffe77c7, 0x07affd117826d1db, 0x6d16bd27bb7edc6b, 0x2c87200285defecc}, gfP{0xe4bbdd0c2936b629, 0xbb30f162e133bacb, 0x31a9d1b6f9645366, 0x253570bea500f8dd}} 44 | 45 | // xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+9. 46 | var xiToPSquaredMinus1Over3 = &gfP{0x3350c88e13e80b9c, 0x7dce557cdb5e56b9, 0x6001b4b8b615564a, 0x2682e617020217e0} 47 | 48 | // xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+9 (a cubic root of unity, mod p). 49 | var xiTo2PSquaredMinus2Over3 = &gfP{0x71930c11d782e155, 0xa6bb947cffbe3323, 0xaa303344d4741444, 0x2c3b3f0d26594943} 50 | 51 | // xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+9 (a cubic root of -1, mod p). 52 | var xiToPSquaredMinus1Over6 = &gfP{0xca8d800500fa1bf2, 0xf0c5d61468b39769, 0x0e201271ad0d4418, 0x04290f65bad856e6} 53 | 54 | // xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+9. 55 | var xiTo2PMinus2Over3 = &gfP2{gfP{0x5dddfd154bd8c949, 0x62cb29a5a4445b60, 0x37bc870a0c7dd2b9, 0x24830a9d3171f0fd}, gfP{0x7361d77f843abe92, 0xa5bb2bd3273411fb, 0x9c941f314b3e2399, 0x15df9cddbb9fd3ec}} 56 | -------------------------------------------------------------------------------- /group/bn256/curve.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | ) 7 | 8 | // curvePoint implements the elliptic curve y²=x³+3. Points are kept in Jacobian 9 | // form and t=z² when valid. G₁ is the set of points of this curve on GF(p). 10 | type curvePoint struct { 11 | x, y, z, t gfP 12 | } 13 | 14 | var curveB = newGFp(3) 15 | 16 | // curveGen is the generator of G₁. 17 | var curveGen = &curvePoint{ 18 | x: *newGFp(1), 19 | y: *newGFp(2), 20 | z: *newGFp(1), 21 | t: *newGFp(1), 22 | } 23 | 24 | func (c *curvePoint) String() string { 25 | c.MakeAffine() 26 | x, y := &gfP{}, &gfP{} 27 | montDecode(x, &c.x) 28 | montDecode(y, &c.y) 29 | return fmt.Sprintf("(%s, %s)", x.String(), y.String()) 30 | } 31 | 32 | func (c *curvePoint) Set(a *curvePoint) { 33 | c.x.Set(&a.x) 34 | c.y.Set(&a.y) 35 | c.z.Set(&a.z) 36 | c.t.Set(&a.t) 37 | } 38 | 39 | // IsOnCurve returns true iff c is on the curve. 40 | func (c *curvePoint) IsOnCurve() bool { 41 | c.MakeAffine() 42 | if c.IsInfinity() { 43 | return true 44 | } 45 | 46 | y2, x3 := &gfP{}, &gfP{} 47 | gfpMul(y2, &c.y, &c.y) 48 | gfpMul(x3, &c.x, &c.x) 49 | gfpMul(x3, x3, &c.x) 50 | gfpAdd(x3, x3, curveB) 51 | 52 | return *y2 == *x3 53 | } 54 | 55 | func (c *curvePoint) SetInfinity() { 56 | c.x = gfP{0} 57 | c.y = *newGFp(1) 58 | c.z = gfP{0} 59 | c.t = gfP{0} 60 | } 61 | 62 | func (c *curvePoint) IsInfinity() bool { 63 | return c.z == gfP{0} 64 | } 65 | 66 | func (c *curvePoint) Add(a, b *curvePoint) { 67 | if a.IsInfinity() { 68 | c.Set(b) 69 | return 70 | } 71 | if b.IsInfinity() { 72 | c.Set(a) 73 | return 74 | } 75 | 76 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 77 | 78 | // Normalize the points by replacing a = [x1:y1:z1] and b = [x2:y2:z2] 79 | // by [u1:s1:z1·z2] and [u2:s2:z1·z2] 80 | // where u1 = x1·z2², s1 = y1·z2³ and u1 = x2·z1², s2 = y2·z1³ 81 | z12, z22 := &gfP{}, &gfP{} 82 | gfpMul(z12, &a.z, &a.z) 83 | gfpMul(z22, &b.z, &b.z) 84 | 85 | u1, u2 := &gfP{}, &gfP{} 86 | gfpMul(u1, &a.x, z22) 87 | gfpMul(u2, &b.x, z12) 88 | 89 | t, s1 := &gfP{}, &gfP{} 90 | gfpMul(t, &b.z, z22) 91 | gfpMul(s1, &a.y, t) 92 | 93 | s2 := &gfP{} 94 | gfpMul(t, &a.z, z12) 95 | gfpMul(s2, &b.y, t) 96 | 97 | // Compute x = (2h)²(s²-u1-u2) 98 | // where s = (s2-s1)/(u2-u1) is the slope of the line through 99 | // (u1,s1) and (u2,s2). The extra factor 2h = 2(u2-u1) comes from the value of z below. 100 | // This is also: 101 | // 4(s2-s1)² - 4h²(u1+u2) = 4(s2-s1)² - 4h³ - 4h²(2u1) 102 | // = r² - j - 2v 103 | // with the notations below. 104 | h := &gfP{} 105 | gfpSub(h, u2, u1) 106 | xEqual := *h == gfP{0} 107 | 108 | gfpAdd(t, h, h) 109 | // i = 4h² 110 | i := &gfP{} 111 | gfpMul(i, t, t) 112 | // j = 4h³ 113 | j := &gfP{} 114 | gfpMul(j, h, i) 115 | 116 | gfpSub(t, s2, s1) 117 | yEqual := *t == gfP{0} 118 | if xEqual && yEqual { 119 | c.Double(a) 120 | return 121 | } 122 | r := &gfP{} 123 | gfpAdd(r, t, t) 124 | 125 | v := &gfP{} 126 | gfpMul(v, u1, i) 127 | 128 | // t4 = 4(s2-s1)² 129 | t4, t6 := &gfP{}, &gfP{} 130 | gfpMul(t4, r, r) 131 | gfpAdd(t, v, v) 132 | gfpSub(t6, t4, j) 133 | 134 | gfpSub(&c.x, t6, t) 135 | 136 | // Set y = -(2h)³(s1 + s*(x/4h²-u1)) 137 | // This is also 138 | // y = - 2·s1·j - (s2-s1)(2x - 2i·u1) = r(v-x) - 2·s1·j 139 | gfpSub(t, v, &c.x) // t7 140 | gfpMul(t4, s1, j) // t8 141 | gfpAdd(t6, t4, t4) // t9 142 | gfpMul(t4, r, t) // t10 143 | gfpSub(&c.y, t4, t6) 144 | 145 | // Set z = 2(u2-u1)·z1·z2 = 2h·z1·z2 146 | gfpAdd(t, &a.z, &b.z) // t11 147 | gfpMul(t4, t, t) // t12 148 | gfpSub(t, t4, z12) // t13 149 | gfpSub(t4, t, z22) // t14 150 | gfpMul(&c.z, t4, h) 151 | } 152 | 153 | func (c *curvePoint) Double(a *curvePoint) { 154 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 155 | A, B, C := &gfP{}, &gfP{}, &gfP{} 156 | gfpMul(A, &a.x, &a.x) 157 | gfpMul(B, &a.y, &a.y) 158 | gfpMul(C, B, B) 159 | 160 | t, t2 := &gfP{}, &gfP{} 161 | gfpAdd(t, &a.x, B) 162 | gfpMul(t2, t, t) 163 | gfpSub(t, t2, A) 164 | gfpSub(t2, t, C) 165 | 166 | d, e, f := &gfP{}, &gfP{}, &gfP{} 167 | gfpAdd(d, t2, t2) 168 | gfpAdd(t, A, A) 169 | gfpAdd(e, t, A) 170 | gfpMul(f, e, e) 171 | 172 | gfpAdd(t, d, d) 173 | gfpSub(&c.x, f, t) 174 | 175 | gfpAdd(t, C, C) 176 | gfpAdd(t2, t, t) 177 | gfpAdd(t, t2, t2) 178 | gfpSub(&c.y, d, &c.x) 179 | gfpMul(t2, e, &c.y) 180 | gfpSub(&c.y, t2, t) 181 | 182 | gfpMul(t, &a.y, &a.z) 183 | gfpAdd(&c.z, t, t) 184 | } 185 | 186 | func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) { 187 | sum, t := &curvePoint{}, &curvePoint{} 188 | sum.SetInfinity() 189 | 190 | for i := scalar.BitLen(); i >= 0; i-- { 191 | t.Double(sum) 192 | if scalar.Bit(i) != 0 { 193 | sum.Add(t, a) 194 | } else { 195 | sum.Set(t) 196 | } 197 | } 198 | 199 | c.Set(sum) 200 | } 201 | 202 | func (c *curvePoint) MakeAffine() { 203 | if c.z == *newGFp(1) { 204 | return 205 | } else if c.z == *newGFp(0) { 206 | c.x = gfP{0} 207 | c.y = *newGFp(1) 208 | c.t = gfP{0} 209 | return 210 | } 211 | 212 | zInv := &gfP{} 213 | zInv.Invert(&c.z) 214 | 215 | t, zInv2 := &gfP{}, &gfP{} 216 | gfpMul(t, &c.y, zInv) 217 | gfpMul(zInv2, zInv, zInv) 218 | 219 | gfpMul(&c.x, &c.x, zInv2) 220 | gfpMul(&c.y, t, zInv2) 221 | 222 | c.z = *newGFp(1) 223 | c.t = *newGFp(1) 224 | } 225 | 226 | func (c *curvePoint) Neg(a *curvePoint) { 227 | c.x.Set(&a.x) 228 | gfpNeg(&c.y, &a.y) 229 | c.z.Set(&a.z) 230 | c.t = gfP{0} 231 | } 232 | -------------------------------------------------------------------------------- /group/bn256/gfp.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | import ( 4 | "fmt" 5 | 6 | "golang.org/x/sys/cpu" 7 | ) 8 | 9 | var hasBMI2 = cpu.X86.HasBMI2 10 | 11 | type gfP [4]uint64 12 | 13 | func newGFp(x int64) (out *gfP) { 14 | if x >= 0 { 15 | out = &gfP{uint64(x)} 16 | } else { 17 | out = &gfP{uint64(-x)} 18 | gfpNeg(out, out) 19 | } 20 | 21 | montEncode(out, out) 22 | return out 23 | } 24 | 25 | func (e *gfP) String() string { 26 | return fmt.Sprintf("%16.16x%16.16x%16.16x%16.16x", e[3], e[2], e[1], e[0]) 27 | } 28 | 29 | func (e *gfP) Set(f *gfP) { 30 | e[0] = f[0] 31 | e[1] = f[1] 32 | e[2] = f[2] 33 | e[3] = f[3] 34 | } 35 | 36 | func (e *gfP) Invert(f *gfP) { 37 | bits := [4]uint64{0x3c208c16d87cfd45, 0x97816a916871ca8d, 0xb85045b68181585d, 0x30644e72e131a029} 38 | 39 | sum, power := &gfP{}, &gfP{} 40 | sum.Set(rN1) 41 | power.Set(f) 42 | 43 | for word := 0; word < 4; word++ { 44 | for bit := uint(0); bit < 64; bit++ { 45 | if (bits[word]>>bit)&1 == 1 { 46 | gfpMul(sum, sum, power) 47 | } 48 | gfpMul(power, power, power) 49 | } 50 | } 51 | 52 | gfpMul(sum, sum, r3) 53 | e.Set(sum) 54 | } 55 | 56 | func (e *gfP) Marshal(out []byte) { 57 | for w := uint(0); w < 4; w++ { 58 | for b := uint(0); b < 8; b++ { 59 | out[8*w+b] = byte(e[3-w] >> (56 - 8*b)) 60 | } 61 | } 62 | } 63 | 64 | func (e *gfP) Unmarshal(in []byte) { 65 | for w := uint(0); w < 4; w++ { 66 | for b := uint(0); b < 8; b++ { 67 | e[3-w] += uint64(in[8*w+b]) << (56 - 8*b) 68 | } 69 | } 70 | } 71 | 72 | func montEncode(c, a *gfP) { gfpMul(c, a, r2) } 73 | func montDecode(c, a *gfP) { gfpMul(c, a, &gfP{1}) } 74 | 75 | // go:noescape 76 | func gfpNeg(c, a *gfP) 77 | 78 | //go:noescape 79 | func gfpAdd(c, a, b *gfP) 80 | 81 | //go:noescape 82 | func gfpSub(c, a, b *gfP) 83 | 84 | //go:noescape 85 | func gfpMul(c, a, b *gfP) 86 | -------------------------------------------------------------------------------- /group/bn256/gfp.h: -------------------------------------------------------------------------------- 1 | #define storeBlock(a0,a1,a2,a3, r) \ 2 | MOVQ a0, 0+r \ 3 | MOVQ a1, 8+r \ 4 | MOVQ a2, 16+r \ 5 | MOVQ a3, 24+r 6 | 7 | #define loadBlock(r, a0,a1,a2,a3) \ 8 | MOVQ 0+r, a0 \ 9 | MOVQ 8+r, a1 \ 10 | MOVQ 16+r, a2 \ 11 | MOVQ 24+r, a3 12 | 13 | #define gfpCarry(a0,a1,a2,a3,a4, b0,b1,b2,b3,b4) \ 14 | \ // b = a-p 15 | MOVQ a0, b0 \ 16 | MOVQ a1, b1 \ 17 | MOVQ a2, b2 \ 18 | MOVQ a3, b3 \ 19 | MOVQ a4, b4 \ 20 | \ 21 | SUBQ ·p2+0(SB), b0 \ 22 | SBBQ ·p2+8(SB), b1 \ 23 | SBBQ ·p2+16(SB), b2 \ 24 | SBBQ ·p2+24(SB), b3 \ 25 | SBBQ $0, b4 \ 26 | \ 27 | \ // if b is negative then return a 28 | \ // else return b 29 | CMOVQCC b0, a0 \ 30 | CMOVQCC b1, a1 \ 31 | CMOVQCC b2, a2 \ 32 | CMOVQCC b3, a3 33 | -------------------------------------------------------------------------------- /group/bn256/gfp.s: -------------------------------------------------------------------------------- 1 | #include "gfp.h" 2 | #include "mul.h" 3 | #include "mul_bmi2.h" 4 | 5 | TEXT ·gfpNeg(SB),0,$0-16 6 | MOVQ ·p2+0(SB), R8 7 | MOVQ ·p2+8(SB), R9 8 | MOVQ ·p2+16(SB), R10 9 | MOVQ ·p2+24(SB), R11 10 | 11 | MOVQ a+8(FP), DI 12 | SUBQ 0(DI), R8 13 | SBBQ 8(DI), R9 14 | SBBQ 16(DI), R10 15 | SBBQ 24(DI), R11 16 | 17 | MOVQ $0, AX 18 | gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,R15,BX) 19 | 20 | MOVQ c+0(FP), DI 21 | storeBlock(R8,R9,R10,R11, 0(DI)) 22 | RET 23 | 24 | TEXT ·gfpAdd(SB),0,$0-24 25 | MOVQ a+8(FP), DI 26 | MOVQ b+16(FP), SI 27 | 28 | loadBlock(0(DI), R8,R9,R10,R11) 29 | MOVQ $0, R12 30 | 31 | ADDQ 0(SI), R8 32 | ADCQ 8(SI), R9 33 | ADCQ 16(SI), R10 34 | ADCQ 24(SI), R11 35 | ADCQ $0, R12 36 | 37 | gfpCarry(R8,R9,R10,R11,R12, R13,R14,R15,AX,BX) 38 | 39 | MOVQ c+0(FP), DI 40 | storeBlock(R8,R9,R10,R11, 0(DI)) 41 | RET 42 | 43 | TEXT ·gfpSub(SB),0,$0-24 44 | MOVQ a+8(FP), DI 45 | MOVQ b+16(FP), SI 46 | 47 | loadBlock(0(DI), R8,R9,R10,R11) 48 | 49 | MOVQ ·p2+0(SB), R12 50 | MOVQ ·p2+8(SB), R13 51 | MOVQ ·p2+16(SB), R14 52 | MOVQ ·p2+24(SB), R15 53 | MOVQ $0, AX 54 | 55 | SUBQ 0(SI), R8 56 | SBBQ 8(SI), R9 57 | SBBQ 16(SI), R10 58 | SBBQ 24(SI), R11 59 | 60 | CMOVQCC AX, R12 61 | CMOVQCC AX, R13 62 | CMOVQCC AX, R14 63 | CMOVQCC AX, R15 64 | 65 | ADDQ R12, R8 66 | ADCQ R13, R9 67 | ADCQ R14, R10 68 | ADCQ R15, R11 69 | 70 | MOVQ c+0(FP), DI 71 | storeBlock(R8,R9,R10,R11, 0(DI)) 72 | RET 73 | 74 | TEXT ·gfpMul(SB),0,$160-24 75 | MOVQ a+8(FP), DI 76 | MOVQ b+16(FP), SI 77 | 78 | // Jump to a slightly different implementation if MULX isn't supported. 79 | CMPB ·hasBMI2(SB), $0 80 | JE nobmi2Mul 81 | 82 | mulBMI2(0(DI),8(DI),16(DI),24(DI), 0(SI)) 83 | storeBlock( R8, R9,R10,R11, 0(SP)) 84 | storeBlock(R12,R13,R14,R15, 32(SP)) 85 | gfpReduceBMI2() 86 | JMP end 87 | 88 | nobmi2Mul: 89 | mul(0(DI),8(DI),16(DI),24(DI), 0(SI), 0(SP)) 90 | gfpReduce(0(SP)) 91 | 92 | end: 93 | MOVQ c+0(FP), DI 94 | storeBlock(R12,R13,R14,R15, 0(DI)) 95 | RET 96 | -------------------------------------------------------------------------------- /group/bn256/gfp2.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | // For details of the algorithms used, see "Multiplication and Squaring on 4 | // Pairing-Friendly Fields, Devegili et al. 5 | // http://eprint.iacr.org/2006/471.pdf. 6 | 7 | // gfP2 implements a field of size p² as a quadratic extension of the base field 8 | // where i²=-1. 9 | type gfP2 struct { 10 | x, y gfP // value is xi+y. 11 | } 12 | 13 | func gfP2Decode(in *gfP2) *gfP2 { 14 | out := &gfP2{} 15 | montDecode(&out.x, &in.x) 16 | montDecode(&out.y, &in.y) 17 | return out 18 | } 19 | 20 | func (e *gfP2) String() string { 21 | return "(" + e.x.String() + ", " + e.y.String() + ")" 22 | } 23 | 24 | func (e *gfP2) Set(a *gfP2) *gfP2 { 25 | e.x.Set(&a.x) 26 | e.y.Set(&a.y) 27 | return e 28 | } 29 | 30 | func (e *gfP2) SetZero() *gfP2 { 31 | e.x = gfP{0} 32 | e.y = gfP{0} 33 | return e 34 | } 35 | 36 | func (e *gfP2) SetOne() *gfP2 { 37 | e.x = gfP{0} 38 | e.y = *newGFp(1) 39 | return e 40 | } 41 | 42 | func (e *gfP2) IsZero() bool { 43 | zero := gfP{0} 44 | return e.x == zero && e.y == zero 45 | } 46 | 47 | func (e *gfP2) IsOne() bool { 48 | zero, one := gfP{0}, *newGFp(1) 49 | return e.x == zero && e.y == one 50 | } 51 | 52 | func (e *gfP2) Conjugate(a *gfP2) *gfP2 { 53 | e.y.Set(&a.y) 54 | gfpNeg(&e.x, &a.x) 55 | return e 56 | } 57 | 58 | func (e *gfP2) Neg(a *gfP2) *gfP2 { 59 | gfpNeg(&e.x, &a.x) 60 | gfpNeg(&e.y, &a.y) 61 | return e 62 | } 63 | 64 | func (e *gfP2) Add(a, b *gfP2) *gfP2 { 65 | gfpAdd(&e.x, &a.x, &b.x) 66 | gfpAdd(&e.y, &a.y, &b.y) 67 | return e 68 | } 69 | 70 | func (e *gfP2) Sub(a, b *gfP2) *gfP2 { 71 | gfpSub(&e.x, &a.x, &b.x) 72 | gfpSub(&e.y, &a.y, &b.y) 73 | return e 74 | } 75 | 76 | // See "Multiplication and Squaring in Pairing-Friendly Fields", 77 | // http://eprint.iacr.org/2006/471.pdf 78 | func (e *gfP2) Mul(a, b *gfP2) *gfP2 { 79 | tx, t := &gfP{}, &gfP{} 80 | gfpMul(tx, &a.x, &b.y) 81 | gfpMul(t, &b.x, &a.y) 82 | gfpAdd(tx, tx, t) 83 | 84 | ty := &gfP{} 85 | gfpMul(ty, &a.y, &b.y) 86 | gfpMul(t, &a.x, &b.x) 87 | gfpSub(ty, ty, t) 88 | 89 | e.x.Set(tx) 90 | e.y.Set(ty) 91 | return e 92 | } 93 | 94 | func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 { 95 | gfpMul(&e.x, &a.x, b) 96 | gfpMul(&e.y, &a.y, b) 97 | return e 98 | } 99 | 100 | // MulXi sets e=ξa where ξ=i+9 and then returns e. 101 | func (e *gfP2) MulXi(a *gfP2) *gfP2 { 102 | // (xi+y)(i+9) = (9x+y)i+(9y-x) 103 | tx := &gfP{} 104 | gfpAdd(tx, &a.x, &a.x) 105 | gfpAdd(tx, tx, tx) 106 | gfpAdd(tx, tx, tx) 107 | gfpAdd(tx, tx, &a.x) 108 | 109 | gfpAdd(tx, tx, &a.y) 110 | 111 | ty := &gfP{} 112 | gfpAdd(ty, &a.y, &a.y) 113 | gfpAdd(ty, ty, ty) 114 | gfpAdd(ty, ty, ty) 115 | gfpAdd(ty, ty, &a.y) 116 | 117 | gfpSub(ty, ty, &a.x) 118 | 119 | e.x.Set(tx) 120 | e.y.Set(ty) 121 | return e 122 | } 123 | 124 | func (e *gfP2) Square(a *gfP2) *gfP2 { 125 | // Complex squaring algorithm: 126 | // (xi+y)² = (x+y)(y-x) + 2*i*x*y 127 | tx, ty := &gfP{}, &gfP{} 128 | gfpSub(tx, &a.y, &a.x) 129 | gfpAdd(ty, &a.x, &a.y) 130 | gfpMul(ty, tx, ty) 131 | 132 | gfpMul(tx, &a.x, &a.y) 133 | gfpAdd(tx, tx, tx) 134 | 135 | e.x.Set(tx) 136 | e.y.Set(ty) 137 | return e 138 | } 139 | 140 | func (e *gfP2) Invert(a *gfP2) *gfP2 { 141 | // See "Implementing cryptographic pairings", M. Scott, section 3.2. 142 | // ftp://136.206.11.249/pub/crypto/pairings.pdf 143 | t1, t2 := &gfP{}, &gfP{} 144 | gfpMul(t1, &a.x, &a.x) 145 | gfpMul(t2, &a.y, &a.y) 146 | gfpAdd(t1, t1, t2) 147 | 148 | inv := &gfP{} 149 | inv.Invert(t1) 150 | 151 | gfpNeg(t1, &a.x) 152 | 153 | gfpMul(&e.x, t1, inv) 154 | gfpMul(&e.y, &a.y, inv) 155 | return e 156 | } 157 | -------------------------------------------------------------------------------- /group/bn256/gfp6.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | // For details of the algorithms used, see "Multiplication and Squaring on 4 | // Pairing-Friendly Fields, Devegili et al. 5 | // http://eprint.iacr.org/2006/471.pdf. 6 | 7 | // gfP6 implements the field of size p⁶ as a cubic extension of gfP2 where τ³=ξ 8 | // and ξ=i+3. 9 | type gfP6 struct { 10 | x, y, z gfP2 // value is xτ² + yτ + z 11 | } 12 | 13 | func (e *gfP6) String() string { 14 | return "(" + e.x.String() + ", " + e.y.String() + ", " + e.z.String() + ")" 15 | } 16 | 17 | func (e *gfP6) Set(a *gfP6) *gfP6 { 18 | e.x.Set(&a.x) 19 | e.y.Set(&a.y) 20 | e.z.Set(&a.z) 21 | return e 22 | } 23 | 24 | func (e *gfP6) SetZero() *gfP6 { 25 | e.x.SetZero() 26 | e.y.SetZero() 27 | e.z.SetZero() 28 | return e 29 | } 30 | 31 | func (e *gfP6) SetOne() *gfP6 { 32 | e.x.SetZero() 33 | e.y.SetZero() 34 | e.z.SetOne() 35 | return e 36 | } 37 | 38 | func (e *gfP6) IsZero() bool { 39 | return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() 40 | } 41 | 42 | func (e *gfP6) IsOne() bool { 43 | return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() 44 | } 45 | 46 | func (e *gfP6) Neg(a *gfP6) *gfP6 { 47 | e.x.Neg(&a.x) 48 | e.y.Neg(&a.y) 49 | e.z.Neg(&a.z) 50 | return e 51 | } 52 | 53 | func (e *gfP6) Frobenius(a *gfP6) *gfP6 { 54 | e.x.Conjugate(&a.x) 55 | e.y.Conjugate(&a.y) 56 | e.z.Conjugate(&a.z) 57 | 58 | e.x.Mul(&e.x, xiTo2PMinus2Over3) 59 | e.y.Mul(&e.y, xiToPMinus1Over3) 60 | return e 61 | } 62 | 63 | // FrobeniusP2 computes (xτ²+yτ+z)^(p²) = xτ^(2p²) + yτ^(p²) + z 64 | func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { 65 | // τ^(2p²) = τ²τ^(2p²-2) = τ²ξ^((2p²-2)/3) 66 | e.x.MulScalar(&a.x, xiTo2PSquaredMinus2Over3) 67 | // τ^(p²) = ττ^(p²-1) = τξ^((p²-1)/3) 68 | e.y.MulScalar(&a.y, xiToPSquaredMinus1Over3) 69 | e.z.Set(&a.z) 70 | return e 71 | } 72 | 73 | func (e *gfP6) FrobeniusP4(a *gfP6) *gfP6 { 74 | e.x.MulScalar(&a.x, xiToPSquaredMinus1Over3) 75 | e.y.MulScalar(&a.y, xiTo2PSquaredMinus2Over3) 76 | e.z.Set(&a.z) 77 | return e 78 | } 79 | 80 | func (e *gfP6) Add(a, b *gfP6) *gfP6 { 81 | e.x.Add(&a.x, &b.x) 82 | e.y.Add(&a.y, &b.y) 83 | e.z.Add(&a.z, &b.z) 84 | return e 85 | } 86 | 87 | func (e *gfP6) Sub(a, b *gfP6) *gfP6 { 88 | e.x.Sub(&a.x, &b.x) 89 | e.y.Sub(&a.y, &b.y) 90 | e.z.Sub(&a.z, &b.z) 91 | return e 92 | } 93 | 94 | func (e *gfP6) Mul(a, b *gfP6) *gfP6 { 95 | // "Multiplication and Squaring on Pairing-Friendly Fields" 96 | // Section 4, Karatsuba method. 97 | // http://eprint.iacr.org/2006/471.pdf 98 | v0 := (&gfP2{}).Mul(&a.z, &b.z) 99 | v1 := (&gfP2{}).Mul(&a.y, &b.y) 100 | v2 := (&gfP2{}).Mul(&a.x, &b.x) 101 | 102 | t0 := (&gfP2{}).Add(&a.x, &a.y) 103 | t1 := (&gfP2{}).Add(&b.x, &b.y) 104 | tz := (&gfP2{}).Mul(t0, t1) 105 | tz.Sub(tz, v1).Sub(tz, v2).MulXi(tz).Add(tz, v0) 106 | 107 | t0.Add(&a.y, &a.z) 108 | t1.Add(&b.y, &b.z) 109 | ty := (&gfP2{}).Mul(t0, t1) 110 | t0.MulXi(v2) 111 | ty.Sub(ty, v0).Sub(ty, v1).Add(ty, t0) 112 | 113 | t0.Add(&a.x, &a.z) 114 | t1.Add(&b.x, &b.z) 115 | tx := (&gfP2{}).Mul(t0, t1) 116 | tx.Sub(tx, v0).Add(tx, v1).Sub(tx, v2) 117 | 118 | e.x.Set(tx) 119 | e.y.Set(ty) 120 | e.z.Set(tz) 121 | return e 122 | } 123 | 124 | func (e *gfP6) MulScalar(a *gfP6, b *gfP2) *gfP6 { 125 | e.x.Mul(&a.x, b) 126 | e.y.Mul(&a.y, b) 127 | e.z.Mul(&a.z, b) 128 | return e 129 | } 130 | 131 | func (e *gfP6) MulGFP(a *gfP6, b *gfP) *gfP6 { 132 | e.x.MulScalar(&a.x, b) 133 | e.y.MulScalar(&a.y, b) 134 | e.z.MulScalar(&a.z, b) 135 | return e 136 | } 137 | 138 | // MulTau computes τ·(aτ²+bτ+c) = bτ²+cτ+aξ 139 | func (e *gfP6) MulTau(a *gfP6) *gfP6 { 140 | tz := (&gfP2{}).MulXi(&a.x) 141 | ty := (&gfP2{}).Set(&a.y) 142 | 143 | e.y.Set(&a.z) 144 | e.x.Set(ty) 145 | e.z.Set(tz) 146 | return e 147 | } 148 | 149 | func (e *gfP6) Square(a *gfP6) *gfP6 { 150 | v0 := (&gfP2{}).Square(&a.z) 151 | v1 := (&gfP2{}).Square(&a.y) 152 | v2 := (&gfP2{}).Square(&a.x) 153 | 154 | c0 := (&gfP2{}).Add(&a.x, &a.y) 155 | c0.Square(c0).Sub(c0, v1).Sub(c0, v2).MulXi(c0).Add(c0, v0) 156 | 157 | c1 := (&gfP2{}).Add(&a.y, &a.z) 158 | c1.Square(c1).Sub(c1, v0).Sub(c1, v1) 159 | xiV2 := (&gfP2{}).MulXi(v2) 160 | c1.Add(c1, xiV2) 161 | 162 | c2 := (&gfP2{}).Add(&a.x, &a.z) 163 | c2.Square(c2).Sub(c2, v0).Add(c2, v1).Sub(c2, v2) 164 | 165 | e.x.Set(c2) 166 | e.y.Set(c1) 167 | e.z.Set(c0) 168 | return e 169 | } 170 | 171 | func (e *gfP6) Invert(a *gfP6) *gfP6 { 172 | // See "Implementing cryptographic pairings", M. Scott, section 3.2. 173 | // ftp://136.206.11.249/pub/crypto/pairings.pdf 174 | 175 | // Here we can give a short explanation of how it works: let j be a cubic root of 176 | // unity in GF(p²) so that 1+j+j²=0. 177 | // Then (xτ² + yτ + z)(xj²τ² + yjτ + z)(xjτ² + yj²τ + z) 178 | // = (xτ² + yτ + z)(Cτ²+Bτ+A) 179 | // = (x³ξ²+y³ξ+z³-3ξxyz) = F is an element of the base field (the norm). 180 | // 181 | // On the other hand (xj²τ² + yjτ + z)(xjτ² + yj²τ + z) 182 | // = τ²(y²-ξxz) + τ(ξx²-yz) + (z²-ξxy) 183 | // 184 | // So that's why A = (z²-ξxy), B = (ξx²-yz), C = (y²-ξxz) 185 | t1 := (&gfP2{}).Mul(&a.x, &a.y) 186 | t1.MulXi(t1) 187 | 188 | A := (&gfP2{}).Square(&a.z) 189 | A.Sub(A, t1) 190 | 191 | B := (&gfP2{}).Square(&a.x) 192 | B.MulXi(B) 193 | t1.Mul(&a.y, &a.z) 194 | B.Sub(B, t1) 195 | 196 | C := (&gfP2{}).Square(&a.y) 197 | t1.Mul(&a.x, &a.z) 198 | C.Sub(C, t1) 199 | 200 | F := (&gfP2{}).Mul(C, &a.y) 201 | F.MulXi(F) 202 | t1.Mul(A, &a.z) 203 | F.Add(F, t1) 204 | t1.Mul(B, &a.x).MulXi(t1) 205 | F.Add(F, t1) 206 | 207 | F.Invert(F) 208 | 209 | e.x.Mul(C, F) 210 | e.y.Mul(B, F) 211 | e.z.Mul(A, F) 212 | return e 213 | } 214 | -------------------------------------------------------------------------------- /group/bn256/group.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | import ( 4 | "crypto/cipher" 5 | 6 | "github.com/dedis/kyber" 7 | "github.com/dedis/kyber/group/mod" 8 | ) 9 | 10 | type groupG1 struct { 11 | common 12 | *commonSuite 13 | } 14 | 15 | func (g *groupG1) String() string { 16 | return "bn256.G1" 17 | } 18 | 19 | func (g *groupG1) PointLen() int { 20 | return newPointG1().MarshalSize() 21 | } 22 | 23 | func (g *groupG1) Point() kyber.Point { 24 | return newPointG1() 25 | } 26 | 27 | type groupG2 struct { 28 | common 29 | *commonSuite 30 | } 31 | 32 | func (g *groupG2) String() string { 33 | return "bn256.G2" 34 | } 35 | 36 | func (g *groupG2) PointLen() int { 37 | return newPointG2().MarshalSize() 38 | } 39 | 40 | func (g *groupG2) Point() kyber.Point { 41 | return newPointG2() 42 | } 43 | 44 | type groupGT struct { 45 | common 46 | *commonSuite 47 | } 48 | 49 | func (g *groupGT) String() string { 50 | return "bn256.GT" 51 | } 52 | 53 | func (g *groupGT) PointLen() int { 54 | return newPointGT().MarshalSize() 55 | } 56 | 57 | func (g *groupGT) Point() kyber.Point { 58 | return newPointGT() 59 | } 60 | 61 | // common functionalities across G1, G2, and GT 62 | type common struct{} 63 | 64 | func (c *common) ScalarLen() int { 65 | return mod.NewInt64(0, Order).MarshalSize() 66 | } 67 | 68 | func (c *common) Scalar() kyber.Scalar { 69 | return mod.NewInt64(0, Order) 70 | } 71 | 72 | func (c *common) PrimeOrder() bool { 73 | return true 74 | } 75 | 76 | func (c *common) NewKey(rand cipher.Stream) kyber.Scalar { 77 | return mod.NewInt64(0, Order).Pick(rand) 78 | } 79 | -------------------------------------------------------------------------------- /group/bn256/mul.h: -------------------------------------------------------------------------------- 1 | #define mul(a0,a1,a2,a3, rb, stack) \ 2 | MOVQ a0, AX \ 3 | MULQ 0+rb \ 4 | MOVQ AX, R8 \ 5 | MOVQ DX, R9 \ 6 | MOVQ a0, AX \ 7 | MULQ 8+rb \ 8 | ADDQ AX, R9 \ 9 | ADCQ $0, DX \ 10 | MOVQ DX, R10 \ 11 | MOVQ a0, AX \ 12 | MULQ 16+rb \ 13 | ADDQ AX, R10 \ 14 | ADCQ $0, DX \ 15 | MOVQ DX, R11 \ 16 | MOVQ a0, AX \ 17 | MULQ 24+rb \ 18 | ADDQ AX, R11 \ 19 | ADCQ $0, DX \ 20 | MOVQ DX, R12 \ 21 | \ 22 | storeBlock(R8,R9,R10,R11, 0+stack) \ 23 | MOVQ R12, 32+stack \ 24 | \ 25 | MOVQ a1, AX \ 26 | MULQ 0+rb \ 27 | MOVQ AX, R8 \ 28 | MOVQ DX, R9 \ 29 | MOVQ a1, AX \ 30 | MULQ 8+rb \ 31 | ADDQ AX, R9 \ 32 | ADCQ $0, DX \ 33 | MOVQ DX, R10 \ 34 | MOVQ a1, AX \ 35 | MULQ 16+rb \ 36 | ADDQ AX, R10 \ 37 | ADCQ $0, DX \ 38 | MOVQ DX, R11 \ 39 | MOVQ a1, AX \ 40 | MULQ 24+rb \ 41 | ADDQ AX, R11 \ 42 | ADCQ $0, DX \ 43 | MOVQ DX, R12 \ 44 | \ 45 | ADDQ 8+stack, R8 \ 46 | ADCQ 16+stack, R9 \ 47 | ADCQ 24+stack, R10 \ 48 | ADCQ 32+stack, R11 \ 49 | ADCQ $0, R12 \ 50 | storeBlock(R8,R9,R10,R11, 8+stack) \ 51 | MOVQ R12, 40+stack \ 52 | \ 53 | MOVQ a2, AX \ 54 | MULQ 0+rb \ 55 | MOVQ AX, R8 \ 56 | MOVQ DX, R9 \ 57 | MOVQ a2, AX \ 58 | MULQ 8+rb \ 59 | ADDQ AX, R9 \ 60 | ADCQ $0, DX \ 61 | MOVQ DX, R10 \ 62 | MOVQ a2, AX \ 63 | MULQ 16+rb \ 64 | ADDQ AX, R10 \ 65 | ADCQ $0, DX \ 66 | MOVQ DX, R11 \ 67 | MOVQ a2, AX \ 68 | MULQ 24+rb \ 69 | ADDQ AX, R11 \ 70 | ADCQ $0, DX \ 71 | MOVQ DX, R12 \ 72 | \ 73 | ADDQ 16+stack, R8 \ 74 | ADCQ 24+stack, R9 \ 75 | ADCQ 32+stack, R10 \ 76 | ADCQ 40+stack, R11 \ 77 | ADCQ $0, R12 \ 78 | storeBlock(R8,R9,R10,R11, 16+stack) \ 79 | MOVQ R12, 48+stack \ 80 | \ 81 | MOVQ a3, AX \ 82 | MULQ 0+rb \ 83 | MOVQ AX, R8 \ 84 | MOVQ DX, R9 \ 85 | MOVQ a3, AX \ 86 | MULQ 8+rb \ 87 | ADDQ AX, R9 \ 88 | ADCQ $0, DX \ 89 | MOVQ DX, R10 \ 90 | MOVQ a3, AX \ 91 | MULQ 16+rb \ 92 | ADDQ AX, R10 \ 93 | ADCQ $0, DX \ 94 | MOVQ DX, R11 \ 95 | MOVQ a3, AX \ 96 | MULQ 24+rb \ 97 | ADDQ AX, R11 \ 98 | ADCQ $0, DX \ 99 | MOVQ DX, R12 \ 100 | \ 101 | ADDQ 24+stack, R8 \ 102 | ADCQ 32+stack, R9 \ 103 | ADCQ 40+stack, R10 \ 104 | ADCQ 48+stack, R11 \ 105 | ADCQ $0, R12 \ 106 | storeBlock(R8,R9,R10,R11, 24+stack) \ 107 | MOVQ R12, 56+stack 108 | 109 | #define gfpReduce(stack) \ 110 | \ // m = (T * N') mod R, store m in R8:R9:R10:R11 111 | MOVQ ·np+0(SB), AX \ 112 | MULQ 0+stack \ 113 | MOVQ AX, R8 \ 114 | MOVQ DX, R9 \ 115 | MOVQ ·np+0(SB), AX \ 116 | MULQ 8+stack \ 117 | ADDQ AX, R9 \ 118 | ADCQ $0, DX \ 119 | MOVQ DX, R10 \ 120 | MOVQ ·np+0(SB), AX \ 121 | MULQ 16+stack \ 122 | ADDQ AX, R10 \ 123 | ADCQ $0, DX \ 124 | MOVQ DX, R11 \ 125 | MOVQ ·np+0(SB), AX \ 126 | MULQ 24+stack \ 127 | ADDQ AX, R11 \ 128 | \ 129 | MOVQ ·np+8(SB), AX \ 130 | MULQ 0+stack \ 131 | MOVQ AX, R12 \ 132 | MOVQ DX, R13 \ 133 | MOVQ ·np+8(SB), AX \ 134 | MULQ 8+stack \ 135 | ADDQ AX, R13 \ 136 | ADCQ $0, DX \ 137 | MOVQ DX, R14 \ 138 | MOVQ ·np+8(SB), AX \ 139 | MULQ 16+stack \ 140 | ADDQ AX, R14 \ 141 | \ 142 | ADDQ R12, R9 \ 143 | ADCQ R13, R10 \ 144 | ADCQ R14, R11 \ 145 | \ 146 | MOVQ ·np+16(SB), AX \ 147 | MULQ 0+stack \ 148 | MOVQ AX, R12 \ 149 | MOVQ DX, R13 \ 150 | MOVQ ·np+16(SB), AX \ 151 | MULQ 8+stack \ 152 | ADDQ AX, R13 \ 153 | \ 154 | ADDQ R12, R10 \ 155 | ADCQ R13, R11 \ 156 | \ 157 | MOVQ ·np+24(SB), AX \ 158 | MULQ 0+stack \ 159 | ADDQ AX, R11 \ 160 | \ 161 | storeBlock(R8,R9,R10,R11, 64+stack) \ 162 | \ 163 | \ // m * N 164 | mul(·p2+0(SB),·p2+8(SB),·p2+16(SB),·p2+24(SB), 64+stack, 96+stack) \ 165 | \ 166 | \ // Add the 512-bit intermediate to m*N 167 | loadBlock(96+stack, R8,R9,R10,R11) \ 168 | loadBlock(128+stack, R12,R13,R14,R15) \ 169 | \ 170 | MOVQ $0, AX \ 171 | ADDQ 0+stack, R8 \ 172 | ADCQ 8+stack, R9 \ 173 | ADCQ 16+stack, R10 \ 174 | ADCQ 24+stack, R11 \ 175 | ADCQ 32+stack, R12 \ 176 | ADCQ 40+stack, R13 \ 177 | ADCQ 48+stack, R14 \ 178 | ADCQ 56+stack, R15 \ 179 | ADCQ $0, AX \ 180 | \ 181 | gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) 182 | -------------------------------------------------------------------------------- /group/bn256/mul_bmi2.h: -------------------------------------------------------------------------------- 1 | #define mulBMI2(a0,a1,a2,a3, rb) \ 2 | MOVQ a0, DX \ 3 | MOVQ $0, R13 \ 4 | MULXQ 0+rb, R8, R9 \ 5 | MULXQ 8+rb, AX, R10 \ 6 | ADDQ AX, R9 \ 7 | MULXQ 16+rb, AX, R11 \ 8 | ADCQ AX, R10 \ 9 | MULXQ 24+rb, AX, R12 \ 10 | ADCQ AX, R11 \ 11 | ADCQ $0, R12 \ 12 | ADCQ $0, R13 \ 13 | \ 14 | MOVQ a1, DX \ 15 | MOVQ $0, R14 \ 16 | MULXQ 0+rb, AX, BX \ 17 | ADDQ AX, R9 \ 18 | ADCQ BX, R10 \ 19 | MULXQ 16+rb, AX, BX \ 20 | ADCQ AX, R11 \ 21 | ADCQ BX, R12 \ 22 | ADCQ $0, R13 \ 23 | MULXQ 8+rb, AX, BX \ 24 | ADDQ AX, R10 \ 25 | ADCQ BX, R11 \ 26 | MULXQ 24+rb, AX, BX \ 27 | ADCQ AX, R12 \ 28 | ADCQ BX, R13 \ 29 | ADCQ $0, R14 \ 30 | \ 31 | MOVQ a2, DX \ 32 | MOVQ $0, R15 \ 33 | MULXQ 0+rb, AX, BX \ 34 | ADDQ AX, R10 \ 35 | ADCQ BX, R11 \ 36 | MULXQ 16+rb, AX, BX \ 37 | ADCQ AX, R12 \ 38 | ADCQ BX, R13 \ 39 | ADCQ $0, R14 \ 40 | MULXQ 8+rb, AX, BX \ 41 | ADDQ AX, R11 \ 42 | ADCQ BX, R12 \ 43 | MULXQ 24+rb, AX, BX \ 44 | ADCQ AX, R13 \ 45 | ADCQ BX, R14 \ 46 | ADCQ $0, R15 \ 47 | \ 48 | MOVQ a3, DX \ 49 | MULXQ 0+rb, AX, BX \ 50 | ADDQ AX, R11 \ 51 | ADCQ BX, R12 \ 52 | MULXQ 16+rb, AX, BX \ 53 | ADCQ AX, R13 \ 54 | ADCQ BX, R14 \ 55 | ADCQ $0, R15 \ 56 | MULXQ 8+rb, AX, BX \ 57 | ADDQ AX, R12 \ 58 | ADCQ BX, R13 \ 59 | MULXQ 24+rb, AX, BX \ 60 | ADCQ AX, R14 \ 61 | ADCQ BX, R15 62 | 63 | #define gfpReduceBMI2() \ 64 | \ // m = (T * N') mod R, store m in R8:R9:R10:R11 65 | MOVQ ·np+0(SB), DX \ 66 | MULXQ 0(SP), R8, R9 \ 67 | MULXQ 8(SP), AX, R10 \ 68 | ADDQ AX, R9 \ 69 | MULXQ 16(SP), AX, R11 \ 70 | ADCQ AX, R10 \ 71 | MULXQ 24(SP), AX, BX \ 72 | ADCQ AX, R11 \ 73 | \ 74 | MOVQ ·np+8(SB), DX \ 75 | MULXQ 0(SP), AX, BX \ 76 | ADDQ AX, R9 \ 77 | ADCQ BX, R10 \ 78 | MULXQ 16(SP), AX, BX \ 79 | ADCQ AX, R11 \ 80 | MULXQ 8(SP), AX, BX \ 81 | ADDQ AX, R10 \ 82 | ADCQ BX, R11 \ 83 | \ 84 | MOVQ ·np+16(SB), DX \ 85 | MULXQ 0(SP), AX, BX \ 86 | ADDQ AX, R10 \ 87 | ADCQ BX, R11 \ 88 | MULXQ 8(SP), AX, BX \ 89 | ADDQ AX, R11 \ 90 | \ 91 | MOVQ ·np+24(SB), DX \ 92 | MULXQ 0(SP), AX, BX \ 93 | ADDQ AX, R11 \ 94 | \ 95 | storeBlock(R8,R9,R10,R11, 64(SP)) \ 96 | \ 97 | \ // m * N 98 | mulBMI2(·p2+0(SB),·p2+8(SB),·p2+16(SB),·p2+24(SB), 64(SP)) \ 99 | \ 100 | \ // Add the 512-bit intermediate to m*N 101 | MOVQ $0, AX \ 102 | ADDQ 0(SP), R8 \ 103 | ADCQ 8(SP), R9 \ 104 | ADCQ 16(SP), R10 \ 105 | ADCQ 24(SP), R11 \ 106 | ADCQ 32(SP), R12 \ 107 | ADCQ 40(SP), R13 \ 108 | ADCQ 48(SP), R14 \ 109 | ADCQ 56(SP), R15 \ 110 | ADCQ $0, AX \ 111 | \ 112 | gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX) 113 | -------------------------------------------------------------------------------- /group/bn256/suite.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | import ( 4 | "crypto/cipher" 5 | "crypto/sha256" 6 | "hash" 7 | "io" 8 | "reflect" 9 | 10 | "github.com/dedis/fixbuf" 11 | "github.com/dedis/kyber" 12 | "github.com/dedis/kyber/util/random" 13 | "github.com/dedis/kyber/xof/blake2xb" 14 | ) 15 | 16 | // Suite implements the pairing.Suite interface for the BN256 bilinear pairing. 17 | type Suite struct { 18 | *commonSuite 19 | g1 *groupG1 20 | g2 *groupG2 21 | gt *groupGT 22 | } 23 | 24 | // NewSuite generates and returns a new BN256 pairing suite. 25 | func NewSuite() *Suite { 26 | s := &Suite{commonSuite: &commonSuite{}} 27 | s.g1 = &groupG1{commonSuite: s.commonSuite} 28 | s.g2 = &groupG2{commonSuite: s.commonSuite} 29 | s.gt = &groupGT{commonSuite: s.commonSuite} 30 | return s 31 | } 32 | 33 | // NewSuiteG1 returns a G1 suite. 34 | func NewSuiteG1() *Suite { 35 | s := NewSuite() 36 | s.commonSuite.Group = &groupG1{commonSuite: &commonSuite{}} 37 | return s 38 | } 39 | 40 | // NewSuiteG2 returns a G2 suite. 41 | func NewSuiteG2() *Suite { 42 | s := NewSuite() 43 | s.commonSuite.Group = &groupG2{commonSuite: &commonSuite{}} 44 | return s 45 | } 46 | 47 | // NewSuiteGT returns a GT suite. 48 | func NewSuiteGT() *Suite { 49 | s := NewSuite() 50 | s.commonSuite.Group = &groupGT{commonSuite: &commonSuite{}} 51 | return s 52 | } 53 | 54 | // NewSuiteRand generates and returns a new BN256 suite seeded by the 55 | // given cipher stream. 56 | func NewSuiteRand(rand cipher.Stream) *Suite { 57 | s := &Suite{commonSuite: &commonSuite{s: rand}} 58 | s.g1 = &groupG1{commonSuite: s.commonSuite} 59 | s.g2 = &groupG2{commonSuite: s.commonSuite} 60 | s.gt = &groupGT{commonSuite: s.commonSuite} 61 | return s 62 | } 63 | 64 | // Point returns a point in groups G2 65 | func (s *Suite) Point() kyber.Point { 66 | return s.g2.Point() 67 | } 68 | 69 | // Scalar returns a scalar in groups G1 70 | func (s *Suite) Scalar() kyber.Scalar { 71 | return s.g1.Scalar() 72 | } 73 | 74 | // String returns a recognizable string that this is a combined suite. 75 | func (s Suite) String() string { 76 | return "bn256" 77 | } 78 | 79 | // G1 returns the group G1 of the BN256 pairing. 80 | func (s *Suite) G1() kyber.Group { 81 | return s.g1 82 | } 83 | 84 | // G2 returns the group G2 of the BN256 pairing. 85 | func (s *Suite) G2() kyber.Group { 86 | return s.g2 87 | } 88 | 89 | // GT returns the group GT of the BN256 pairing. 90 | func (s *Suite) GT() kyber.Group { 91 | return s.gt 92 | } 93 | 94 | // Pair takes the points p1 and p2 in groups G1 and G2, respectively, as input 95 | // and computes their pairing in GT. 96 | func (s *Suite) Pair(p1 kyber.Point, p2 kyber.Point) kyber.Point { 97 | return s.GT().Point().(*pointGT).Pair(p1, p2) 98 | } 99 | 100 | // PairingCheck calculates the Optimal Ate pairing for a set of points 101 | func (s *Suite) PairingCheck(a []kyber.Point, b []kyber.Point) bool { 102 | return s.GT().Point().(*pointGT).PairingCheck(a, b) 103 | } 104 | 105 | // Not used other than for reflect.TypeOf() 106 | var aScalar kyber.Scalar 107 | var aPoint kyber.Point 108 | var aPointG1 pointG1 109 | var aPointG2 pointG2 110 | var aPointGT pointGT 111 | 112 | var tScalar = reflect.TypeOf(&aScalar).Elem() 113 | var tPoint = reflect.TypeOf(&aPoint).Elem() 114 | var tPointG1 = reflect.TypeOf(&aPointG1).Elem() 115 | var tPointG2 = reflect.TypeOf(&aPointG2).Elem() 116 | var tPointGT = reflect.TypeOf(&aPointGT).Elem() 117 | 118 | type commonSuite struct { 119 | s cipher.Stream 120 | // kyber.Group is only set if we have a combined Suite 121 | kyber.Group 122 | } 123 | 124 | // New implements the kyber.Encoding interface. 125 | func (c *commonSuite) New(t reflect.Type) interface{} { 126 | switch t { 127 | case tScalar: 128 | return c.Scalar() 129 | case tPoint: 130 | return c.Point() 131 | case tPointG1: 132 | g1 := groupG1{} 133 | return g1.Point() 134 | case tPointG2: 135 | g2 := groupG2{} 136 | return g2.Point() 137 | case tPointGT: 138 | gt := groupGT{} 139 | return gt.Point() 140 | } 141 | return nil 142 | } 143 | 144 | // Read is the default implementation of kyber.Encoding interface Read. 145 | func (c *commonSuite) Read(r io.Reader, objs ...interface{}) error { 146 | return fixbuf.Read(r, c, objs...) 147 | } 148 | 149 | // Write is the default implementation of kyber.Encoding interface Write. 150 | func (c *commonSuite) Write(w io.Writer, objs ...interface{}) error { 151 | return fixbuf.Write(w, objs) 152 | } 153 | 154 | // Hash returns a newly instantiated sha256 hash function. 155 | func (c *commonSuite) Hash() hash.Hash { 156 | return sha256.New() 157 | } 158 | 159 | // XOF returns a newlly instantiated blake2xb XOF function. 160 | func (c *commonSuite) XOF(seed []byte) kyber.XOF { 161 | return blake2xb.New(seed) 162 | } 163 | 164 | // RandomStream returns a cipher.Stream which corresponds to a key stream from 165 | // crypto/rand. 166 | func (c *commonSuite) RandomStream() cipher.Stream { 167 | if c.s != nil { 168 | return c.s 169 | } 170 | return random.New() 171 | } 172 | 173 | // String returns a recognizable string that this is a combined suite. 174 | func (c commonSuite) String() string { 175 | if c.Group != nil { 176 | return c.Group.String() 177 | } 178 | return "bn256" 179 | } 180 | -------------------------------------------------------------------------------- /group/bn256/twist.go: -------------------------------------------------------------------------------- 1 | package bn256 2 | 3 | import ( 4 | "math/big" 5 | ) 6 | 7 | // twistPoint implements the elliptic curve y²=x³+3/ξ over GF(p²). Points are 8 | // kept in Jacobian form and t=z² when valid. The group G₂ is the set of 9 | // n-torsion points of this curve over GF(p²) (where n = Order) 10 | type twistPoint struct { 11 | x, y, z, t gfP2 12 | } 13 | 14 | var twistB = &gfP2{ 15 | gfP{0x38e7ecccd1dcff67, 0x65f0b37d93ce0d3e, 0xd749d0dd22ac00aa, 0x0141b9ce4a688d4d}, 16 | gfP{0x3bf938e377b802a8, 0x020b1b273633535d, 0x26b7edf049755260, 0x2514c6324384a86d}, 17 | } 18 | 19 | // twistGen is the generator of group G₂. 20 | var twistGen = &twistPoint{ 21 | gfP2{ 22 | gfP{0xafb4737da84c6140, 0x6043dd5a5802d8c4, 0x09e950fc52a02f86, 0x14fef0833aea7b6b}, 23 | gfP{0x8e83b5d102bc2026, 0xdceb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b}, 24 | }, 25 | gfP2{ 26 | gfP{0x64095b56c71856ee, 0xdc57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482}, 27 | gfP{0x619dfa9d886be9f6, 0xfe7fd297f59e9b78, 0xff9e1a62231b7dfe, 0x28fd7eebae9e4206}, 28 | }, 29 | gfP2{*newGFp(0), *newGFp(1)}, 30 | gfP2{*newGFp(0), *newGFp(1)}, 31 | } 32 | 33 | func (c *twistPoint) String() string { 34 | c.MakeAffine() 35 | x, y := gfP2Decode(&c.x), gfP2Decode(&c.y) 36 | return "(" + x.String() + ", " + y.String() + ")" 37 | } 38 | 39 | func (c *twistPoint) Set(a *twistPoint) { 40 | c.x.Set(&a.x) 41 | c.y.Set(&a.y) 42 | c.z.Set(&a.z) 43 | c.t.Set(&a.t) 44 | } 45 | 46 | // IsOnCurve returns true iff c is on the curve. 47 | func (c *twistPoint) IsOnCurve() bool { 48 | c.MakeAffine() 49 | if c.IsInfinity() { 50 | return true 51 | } 52 | 53 | y2, x3 := &gfP2{}, &gfP2{} 54 | y2.Square(&c.y) 55 | x3.Square(&c.x).Mul(x3, &c.x).Add(x3, twistB) 56 | 57 | if *y2 != *x3 { 58 | return false 59 | } 60 | cneg := &twistPoint{} 61 | cneg.Mul(c, Order) 62 | return cneg.z.IsZero() 63 | } 64 | 65 | func (c *twistPoint) SetInfinity() { 66 | c.x.SetZero() 67 | c.y.SetOne() 68 | c.z.SetZero() 69 | c.t.SetZero() 70 | } 71 | 72 | func (c *twistPoint) IsInfinity() bool { 73 | return c.z.IsZero() 74 | } 75 | 76 | func (c *twistPoint) Add(a, b *twistPoint) { 77 | // For additional comments, see the same function in curve.go. 78 | 79 | if a.IsInfinity() { 80 | c.Set(b) 81 | return 82 | } 83 | if b.IsInfinity() { 84 | c.Set(a) 85 | return 86 | } 87 | 88 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 89 | z12 := (&gfP2{}).Square(&a.z) 90 | z22 := (&gfP2{}).Square(&b.z) 91 | u1 := (&gfP2{}).Mul(&a.x, z22) 92 | u2 := (&gfP2{}).Mul(&b.x, z12) 93 | 94 | t := (&gfP2{}).Mul(&b.z, z22) 95 | s1 := (&gfP2{}).Mul(&a.y, t) 96 | 97 | t.Mul(&a.z, z12) 98 | s2 := (&gfP2{}).Mul(&b.y, t) 99 | 100 | h := (&gfP2{}).Sub(u2, u1) 101 | xEqual := h.IsZero() 102 | 103 | t.Add(h, h) 104 | i := (&gfP2{}).Square(t) 105 | j := (&gfP2{}).Mul(h, i) 106 | 107 | t.Sub(s2, s1) 108 | yEqual := t.IsZero() 109 | if xEqual && yEqual { 110 | c.Double(a) 111 | return 112 | } 113 | r := (&gfP2{}).Add(t, t) 114 | 115 | v := (&gfP2{}).Mul(u1, i) 116 | 117 | t4 := (&gfP2{}).Square(r) 118 | t.Add(v, v) 119 | t6 := (&gfP2{}).Sub(t4, j) 120 | c.x.Sub(t6, t) 121 | 122 | t.Sub(v, &c.x) // t7 123 | t4.Mul(s1, j) // t8 124 | t6.Add(t4, t4) // t9 125 | t4.Mul(r, t) // t10 126 | c.y.Sub(t4, t6) 127 | 128 | t.Add(&a.z, &b.z) // t11 129 | t4.Square(t) // t12 130 | t.Sub(t4, z12) // t13 131 | t4.Sub(t, z22) // t14 132 | c.z.Mul(t4, h) 133 | } 134 | 135 | func (c *twistPoint) Double(a *twistPoint) { 136 | // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3 137 | A := (&gfP2{}).Square(&a.x) 138 | B := (&gfP2{}).Square(&a.y) 139 | C := (&gfP2{}).Square(B) 140 | 141 | t := (&gfP2{}).Add(&a.x, B) 142 | t2 := (&gfP2{}).Square(t) 143 | t.Sub(t2, A) 144 | t2.Sub(t, C) 145 | d := (&gfP2{}).Add(t2, t2) 146 | t.Add(A, A) 147 | e := (&gfP2{}).Add(t, A) 148 | f := (&gfP2{}).Square(e) 149 | 150 | t.Add(d, d) 151 | c.x.Sub(f, t) 152 | 153 | t.Add(C, C) 154 | t2.Add(t, t) 155 | t.Add(t2, t2) 156 | c.y.Sub(d, &c.x) 157 | t2.Mul(e, &c.y) 158 | c.y.Sub(t2, t) 159 | 160 | t.Mul(&a.y, &a.z) 161 | c.z.Add(t, t) 162 | } 163 | 164 | func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int) { 165 | sum, t := &twistPoint{}, &twistPoint{} 166 | 167 | for i := scalar.BitLen(); i >= 0; i-- { 168 | t.Double(sum) 169 | if scalar.Bit(i) != 0 { 170 | sum.Add(t, a) 171 | } else { 172 | sum.Set(t) 173 | } 174 | } 175 | 176 | c.Set(sum) 177 | } 178 | 179 | func (c *twistPoint) MakeAffine() { 180 | if c.z.IsOne() { 181 | return 182 | } else if c.z.IsZero() { 183 | c.x.SetZero() 184 | c.y.SetOne() 185 | c.t.SetZero() 186 | return 187 | } 188 | 189 | zInv := (&gfP2{}).Invert(&c.z) 190 | t := (&gfP2{}).Mul(&c.y, zInv) 191 | zInv2 := (&gfP2{}).Square(zInv) 192 | c.y.Mul(t, zInv2) 193 | t.Mul(&c.x, zInv2) 194 | c.x.Set(t) 195 | c.z.SetOne() 196 | c.t.SetOne() 197 | } 198 | 199 | func (c *twistPoint) Neg(a *twistPoint) { 200 | c.x.Set(&a.x) 201 | c.y.Neg(&a.y) 202 | c.z.Set(&a.z) 203 | c.t.SetZero() 204 | } 205 | -------------------------------------------------------------------------------- /group/edwards25519/LICENSE: -------------------------------------------------------------------------------- 1 | This directory is under the go-license: 2 | 3 | Copyright (c) 2009 The Go Authors. All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are 7 | met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following disclaimer 13 | in the documentation and/or other materials provided with the 14 | distribution. 15 | * Neither the name of Google Inc. nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /group/edwards25519/allow_test.go: -------------------------------------------------------------------------------- 1 | // +build !vartime 2 | 3 | package edwards25519 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/dedis/kyber" 9 | ) 10 | 11 | func TestNotVartime(t *testing.T) { 12 | p := tSuite.Point() 13 | if _, ok := p.(kyber.AllowsVarTime); ok { 14 | t.Fatal("expected Point to NOT allow var time") 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /group/edwards25519/allowvt_test.go: -------------------------------------------------------------------------------- 1 | // +build vartime 2 | 3 | package edwards25519 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/dedis/kyber" 9 | ) 10 | 11 | func TestVartime(t *testing.T) { 12 | p := tSuite.Point() 13 | if pvt, ok := p.(kyber.AllowsVarTime); ok { 14 | // Try both settings 15 | pvt.AllowVarTime(false) 16 | p.Mul(one, p) 17 | pvt.AllowVarTime(true) 18 | p.Mul(one, p) 19 | } else { 20 | t.Fatal("expected Point to allow var time") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /group/edwards25519/curve.go: -------------------------------------------------------------------------------- 1 | package edwards25519 2 | 3 | import ( 4 | "crypto/cipher" 5 | "crypto/sha512" 6 | 7 | "github.com/dedis/kyber" 8 | "github.com/dedis/kyber/util/random" 9 | ) 10 | 11 | // Curve represents the Ed25519 group. 12 | // There are no parameters and no initialization is required 13 | // because it supports only this one specific curve. 14 | type Curve struct { 15 | } 16 | 17 | // Return the name of the curve, "Ed25519". 18 | func (c *Curve) String() string { 19 | return "Ed25519" 20 | } 21 | 22 | // ScalarLen returns 32, the size in bytes of an encoded Scalar 23 | // for the Ed25519 curve. 24 | func (c *Curve) ScalarLen() int { 25 | return 32 26 | } 27 | 28 | // Scalar creates a new Scalar for the prime-order subgroup of the Ed25519 curve. 29 | // The scalars in this package implement kyber.Scalar's SetBytes 30 | // method, interpreting the bytes as a little-endian integer, in order to remain 31 | // compatible with other Ed25519 implementations, and with the standard implementation 32 | // of the EdDSA signature. 33 | func (c *Curve) Scalar() kyber.Scalar { 34 | return &scalar{} 35 | } 36 | 37 | // PointLen returns 32, the size in bytes of an encoded Point on the Ed25519 curve. 38 | func (c *Curve) PointLen() int { 39 | return 32 40 | } 41 | 42 | // Point creates a new Point on the Ed25519 curve. 43 | func (c *Curve) Point() kyber.Point { 44 | P := new(point) 45 | return P 46 | } 47 | 48 | // NewKey returns a formatted Ed25519 key (avoiding subgroup attack by requiring 49 | // it to be a multiple of 8). NewKey implements the kyber/util/key.Generator interface. 50 | func (c *Curve) NewKey(stream cipher.Stream) kyber.Scalar { 51 | var buffer [32]byte 52 | random.Bytes(buffer[:], stream) 53 | scalar := sha512.Sum512(buffer[:]) 54 | scalar[0] &= 0xf8 55 | scalar[31] &= 0x3f 56 | scalar[31] |= 0x40 57 | 58 | secret := c.Scalar().SetBytes(scalar[:32]) 59 | return secret 60 | } 61 | -------------------------------------------------------------------------------- /group/edwards25519/curve_test.go: -------------------------------------------------------------------------------- 1 | package edwards25519 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/dedis/kyber/util/test" 7 | ) 8 | 9 | var tSuite = NewBlakeSHA256Ed25519() 10 | var groupBench = test.NewGroupBench(tSuite) 11 | 12 | func TestSuite(t *testing.T) { test.SuiteTest(t, tSuite) } 13 | 14 | func BenchmarkScalarAdd(b *testing.B) { groupBench.ScalarAdd(b.N) } 15 | func BenchmarkScalarSub(b *testing.B) { groupBench.ScalarSub(b.N) } 16 | func BenchmarkScalarNeg(b *testing.B) { groupBench.ScalarNeg(b.N) } 17 | func BenchmarkScalarMul(b *testing.B) { groupBench.ScalarMul(b.N) } 18 | func BenchmarkScalarDiv(b *testing.B) { groupBench.ScalarDiv(b.N) } 19 | func BenchmarkScalarInv(b *testing.B) { groupBench.ScalarInv(b.N) } 20 | func BenchmarkScalarPick(b *testing.B) { groupBench.ScalarPick(b.N) } 21 | func BenchmarkScalarEncode(b *testing.B) { groupBench.ScalarEncode(b.N) } 22 | func BenchmarkScalarDecode(b *testing.B) { groupBench.ScalarDecode(b.N) } 23 | 24 | func BenchmarkPointAdd(b *testing.B) { groupBench.PointAdd(b.N) } 25 | func BenchmarkPointSub(b *testing.B) { groupBench.PointSub(b.N) } 26 | func BenchmarkPointNeg(b *testing.B) { groupBench.PointNeg(b.N) } 27 | func BenchmarkPointMul(b *testing.B) { groupBench.PointMul(b.N) } 28 | func BenchmarkPointBaseMul(b *testing.B) { groupBench.PointBaseMul(b.N) } 29 | func BenchmarkPointPick(b *testing.B) { groupBench.PointPick(b.N) } 30 | func BenchmarkPointEncode(b *testing.B) { groupBench.PointEncode(b.N) } 31 | func BenchmarkPointDecode(b *testing.B) { groupBench.PointDecode(b.N) } 32 | -------------------------------------------------------------------------------- /group/edwards25519/elligator_test_go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package edwards25519 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "testing" 11 | 12 | "code.google.com/p/go.crypto/curve25519" 13 | "github.com/agl/ed25519" 14 | ) 15 | 16 | func TestCurve25519Conversion(t *testing.T) { 17 | public, private, _ := ed25519.GenerateKey(rand.Reader) 18 | 19 | var curve25519Public, curve25519Public2, curve25519Private [32]byte 20 | PrivateKeyToCurve25519(&curve25519Private, private) 21 | curve25519.ScalarBaseMult(&curve25519Public, &curve25519Private) 22 | 23 | if !PublicKeyToCurve25519(&curve25519Public2, public) { 24 | t.Fatalf("PublicKeyToCurve25519 failed") 25 | } 26 | 27 | if !bytes.Equal(curve25519Public[:], curve25519Public2[:]) { 28 | t.Errorf("Values didn't match: curve25519 produced %x, conversion produced %x", curve25519Public[:], curve25519Public2[:]) 29 | } 30 | } 31 | 32 | func TestElligator(t *testing.T) { 33 | var publicKey, publicKey2, publicKey3, representative, privateKey [32]byte 34 | 35 | for i := 0; i < 1000; i++ { 36 | rand.Reader.Read(privateKey[:]) 37 | 38 | if !ScalarBaseMult(&publicKey, &representative, &privateKey) { 39 | continue 40 | } 41 | RepresentativeToPublicKey(&publicKey2, &representative) 42 | if !bytes.Equal(publicKey[:], publicKey2[:]) { 43 | t.Fatal("The resulting public key doesn't match the initial one.") 44 | } 45 | 46 | curve25519.ScalarBaseMult(&publicKey3, &privateKey) 47 | if !bytes.Equal(publicKey[:], publicKey3[:]) { 48 | t.Fatal("The public key doesn't match the value that curve25519 produced.") 49 | } 50 | } 51 | } 52 | 53 | func BenchmarkKeyGeneration(b *testing.B) { 54 | var publicKey, representative, privateKey [32]byte 55 | 56 | // Find the private key that results in a point that's in the image of the map. 57 | for { 58 | rand.Reader.Read(privateKey[:]) 59 | if ScalarBaseMult(&publicKey, &representative, &privateKey) { 60 | break 61 | } 62 | } 63 | 64 | b.ResetTimer() 65 | for i := 0; i < b.N; i++ { 66 | ScalarBaseMult(&publicKey, &representative, &privateKey) 67 | } 68 | } 69 | 70 | func BenchmarkMap(b *testing.B) { 71 | var publicKey, representative [32]byte 72 | rand.Reader.Read(representative[:]) 73 | 74 | b.ResetTimer() 75 | for i := 0; i < b.N; i++ { 76 | RepresentativeToPublicKey(&publicKey, &representative) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /group/edwards25519/ge_mult.go: -------------------------------------------------------------------------------- 1 | // +build !vartime 2 | 3 | package edwards25519 4 | 5 | // In "func (P *point) Mul", this function is referenced, even when !vartime. 6 | // So we need that something is defined, in order to make the linker happy, even if 7 | // it will never be called. 8 | func geScalarMultVartime(h *extendedGroupElement, a *[32]byte, 9 | A *extendedGroupElement) { 10 | panic("geScalarMultVartime should never be called with build tags !vartime") 11 | } 12 | -------------------------------------------------------------------------------- /group/edwards25519/ge_mult_vartime.go: -------------------------------------------------------------------------------- 1 | // +build vartime 2 | 3 | package edwards25519 4 | 5 | // geScalarMultVartime computes h = a*B, where 6 | // a = a[0]+256*a[1]+...+256^31 a[31] 7 | // B is the Ed25519 base point (x,4/5) with x positive. 8 | // 9 | // Preconditions: 10 | // a[31] <= 127 11 | func geScalarMultVartime(h *extendedGroupElement, a *[32]byte, 12 | A *extendedGroupElement) { 13 | 14 | var aSlide [256]int8 15 | var Ai [8]cachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A 16 | var t completedGroupElement 17 | var u, A2 extendedGroupElement 18 | var r projectiveGroupElement 19 | var i int 20 | 21 | // Slide through the scalar exponent clumping sequences of bits, 22 | // resulting in only zero or odd multipliers between -15 and 15. 23 | slide(&aSlide, a) 24 | 25 | // Form an array of odd multiples of A from 1A through 15A, 26 | // in addition-ready cached group element form. 27 | // We only need odd multiples of A because slide() 28 | // produces only odd-multiple clumps of bits. 29 | A.ToCached(&Ai[0]) 30 | A.Double(&t) 31 | t.ToExtended(&A2) 32 | for i := 0; i < 7; i++ { 33 | t.Add(&A2, &Ai[i]) 34 | t.ToExtended(&u) 35 | u.ToCached(&Ai[i+1]) 36 | } 37 | 38 | // Process the multiplications from most-significant bit downward 39 | for i = 255; ; i-- { 40 | if i < 0 { // no bits set 41 | h.Zero() 42 | return 43 | } 44 | if aSlide[i] != 0 { 45 | break 46 | } 47 | } 48 | 49 | // first (most-significant) nonzero clump of bits 50 | u.Zero() 51 | if aSlide[i] > 0 { 52 | t.Add(&u, &Ai[aSlide[i]/2]) 53 | } else if aSlide[i] < 0 { 54 | t.Sub(&u, &Ai[(-aSlide[i])/2]) 55 | } 56 | i-- 57 | 58 | // remaining bits 59 | for ; i >= 0; i-- { 60 | t.ToProjective(&r) 61 | r.Double(&t) 62 | 63 | if aSlide[i] > 0 { 64 | t.ToExtended(&u) 65 | t.Add(&u, &Ai[aSlide[i]/2]) 66 | } else if aSlide[i] < 0 { 67 | t.ToExtended(&u) 68 | t.Sub(&u, &Ai[(-aSlide[i])/2]) 69 | } 70 | } 71 | 72 | t.ToExtended(h) 73 | } 74 | -------------------------------------------------------------------------------- /group/edwards25519/point_vartime.go: -------------------------------------------------------------------------------- 1 | // +build vartime 2 | 3 | package edwards25519 4 | 5 | // AllowVarTime sets a flag in this object which determines if a faster 6 | // but variable time implementation can be used. Set this only on Points 7 | // which represent public information. Using variable time algorithms to 8 | // operate on private information can result in timing side-channels. 9 | func (P *point) AllowVarTime(varTime bool) { 10 | P.varTime = varTime 11 | } 12 | -------------------------------------------------------------------------------- /group/edwards25519/suite.go: -------------------------------------------------------------------------------- 1 | package edwards25519 2 | 3 | import ( 4 | "crypto/cipher" 5 | "crypto/sha256" 6 | "hash" 7 | "io" 8 | "reflect" 9 | 10 | "github.com/DOSNetwork/core/group/internal/marshalling" 11 | "github.com/dedis/fixbuf" 12 | "github.com/dedis/kyber" 13 | "github.com/dedis/kyber/util/random" 14 | "github.com/dedis/kyber/xof/blake2xb" 15 | ) 16 | 17 | // SuiteEd25519 implements some basic functionalities such as Group, HashFactory, 18 | // and XOFFactory. 19 | type SuiteEd25519 struct { 20 | Curve 21 | r cipher.Stream 22 | } 23 | 24 | // G1 returns the group G1 of the BN256 pairing. 25 | func (s *SuiteEd25519) G1() kyber.Group { 26 | return s 27 | } 28 | 29 | // G2 returns the group G2 of the BN256 pairing. 30 | func (s *SuiteEd25519) G2() kyber.Group { 31 | return s 32 | } 33 | 34 | // GT returns the group GT of the BN256 pairing. 35 | func (s *SuiteEd25519) GT() kyber.Group { 36 | return s 37 | } 38 | 39 | // Pair takes the points p1 and p2 in groups G1 and G2, respectively, as input 40 | // and computes their pairing in GT. 41 | func (s *SuiteEd25519) Pair(p1 kyber.Point, p2 kyber.Point) kyber.Point { 42 | return s.Point() 43 | } 44 | 45 | // PairingCheck always return false for SuiteEd25519. 46 | func (s *SuiteEd25519) PairingCheck(a []kyber.Point, b []kyber.Point) bool { 47 | return false 48 | } 49 | 50 | // Hash returns a newly instanciated sha256 hash function. 51 | func (s *SuiteEd25519) Hash() hash.Hash { 52 | return sha256.New() 53 | } 54 | 55 | // XOF returns an XOF which is implemented via the Blake2b hash. 56 | func (s *SuiteEd25519) XOF(key []byte) kyber.XOF { 57 | return blake2xb.New(key) 58 | } 59 | 60 | func (s *SuiteEd25519) Read(r io.Reader, objs ...interface{}) error { 61 | return fixbuf.Read(r, s, objs...) 62 | } 63 | 64 | func (s *SuiteEd25519) Write(w io.Writer, objs ...interface{}) error { 65 | return fixbuf.Write(w, objs) 66 | } 67 | 68 | // New implements the kyber.Encoding interface 69 | func (s *SuiteEd25519) New(t reflect.Type) interface{} { 70 | return marshalling.GroupNew(s, t) 71 | } 72 | 73 | // RandomStream returns a cipher.Stream that returns a key stream 74 | // from crypto/rand. 75 | func (s *SuiteEd25519) RandomStream() cipher.Stream { 76 | if s.r != nil { 77 | return s.r 78 | } 79 | return random.New() 80 | } 81 | 82 | // NewBlakeSHA256Ed25519 returns a cipher suite based on package 83 | // github.com/dedis/kyber/xof/blake2xb, SHA-256, and the Ed25519 curve. 84 | // It produces cryptographically random numbers via package crypto/rand. 85 | func NewBlakeSHA256Ed25519() *SuiteEd25519 { 86 | suite := new(SuiteEd25519) 87 | return suite 88 | } 89 | 90 | // NewBlakeSHA256Ed25519WithRand returns a cipher suite based on package 91 | // github.com/dedis/kyber/xof/blake2xb, SHA-256, and the Ed25519 curve. 92 | // It produces cryptographically random numbers via the provided stream r. 93 | func NewBlakeSHA256Ed25519WithRand(r cipher.Stream) *SuiteEd25519 { 94 | suite := new(SuiteEd25519) 95 | suite.r = r 96 | return suite 97 | } 98 | -------------------------------------------------------------------------------- /group/internal/marshalling/marshal.go: -------------------------------------------------------------------------------- 1 | // Package marshalling provides a common implementation of (un)marshalling method using Writer and Reader. 2 | // 3 | package marshalling 4 | 5 | import ( 6 | "crypto/cipher" 7 | "io" 8 | "reflect" 9 | 10 | "github.com/dedis/kyber" 11 | ) 12 | 13 | // PointMarshalTo provides a generic implementation of Point.EncodeTo 14 | // based on Point.Encode. 15 | func PointMarshalTo(p kyber.Point, w io.Writer) (int, error) { 16 | buf, err := p.MarshalBinary() 17 | if err != nil { 18 | return 0, err 19 | } 20 | return w.Write(buf) 21 | } 22 | 23 | // PointUnmarshalFrom provides a generic implementation of Point.DecodeFrom, 24 | // based on Point.Decode, or Point.Pick if r is a Cipher or cipher.Stream. 25 | // The returned byte-count is valid only when decoding from a normal Reader, 26 | // not when picking from a pseudorandom source. 27 | func PointUnmarshalFrom(p kyber.Point, r io.Reader) (int, error) { 28 | if strm, ok := r.(cipher.Stream); ok { 29 | p.Pick(strm) 30 | return -1, nil // no byte-count when picking randomly 31 | } 32 | buf := make([]byte, p.MarshalSize()) 33 | n, err := io.ReadFull(r, buf) 34 | if err != nil { 35 | return n, err 36 | } 37 | return n, p.UnmarshalBinary(buf) 38 | } 39 | 40 | // ScalarMarshalTo provides a generic implementation of Scalar.EncodeTo 41 | // based on Scalar.Encode. 42 | func ScalarMarshalTo(s kyber.Scalar, w io.Writer) (int, error) { 43 | buf, err := s.MarshalBinary() 44 | if err != nil { 45 | return 0, err 46 | } 47 | return w.Write(buf) 48 | } 49 | 50 | // ScalarUnmarshalFrom provides a generic implementation of Scalar.DecodeFrom, 51 | // based on Scalar.Decode, or Scalar.Pick if r is a Cipher or cipher.Stream. 52 | // The returned byte-count is valid only when decoding from a normal Reader, 53 | // not when picking from a pseudorandom source. 54 | func ScalarUnmarshalFrom(s kyber.Scalar, r io.Reader) (int, error) { 55 | if strm, ok := r.(cipher.Stream); ok { 56 | s.Pick(strm) 57 | return -1, nil // no byte-count when picking randomly 58 | } 59 | buf := make([]byte, s.MarshalSize()) 60 | n, err := io.ReadFull(r, buf) 61 | if err != nil { 62 | return n, err 63 | } 64 | return n, s.UnmarshalBinary(buf) 65 | } 66 | 67 | // Not used other than for reflect.TypeOf() 68 | var aScalar kyber.Scalar 69 | var aPoint kyber.Point 70 | 71 | var tScalar = reflect.TypeOf(&aScalar).Elem() 72 | var tPoint = reflect.TypeOf(&aPoint).Elem() 73 | 74 | // GroupNew is the Default implementation of reflective constructor for Group 75 | func GroupNew(g kyber.Group, t reflect.Type) interface{} { 76 | switch t { 77 | case tScalar: 78 | return g.Scalar() 79 | case tPoint: 80 | return g.Point() 81 | } 82 | return nil 83 | } 84 | -------------------------------------------------------------------------------- /group/mod/int_test.go: -------------------------------------------------------------------------------- 1 | package mod 2 | 3 | import ( 4 | "bytes" 5 | "encoding/hex" 6 | "math/big" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestIntEndianness(t *testing.T) { 13 | modulo := big.NewInt(65535) 14 | var v int64 = 65500 15 | // Let's assume it is bigendian and test that 16 | i := new(Int).Init64(v, modulo) 17 | assert.Equal(t, i.BO, BigEndian) 18 | 19 | buff1, err := i.MarshalBinary() 20 | assert.Nil(t, err) 21 | i.BO = BigEndian 22 | buff2, err := i.MarshalBinary() 23 | assert.Nil(t, err) 24 | assert.Equal(t, buff1, buff2) 25 | 26 | // Let's change endianness and check the result 27 | i.BO = LittleEndian 28 | buff3, err := i.MarshalBinary() 29 | assert.Nil(t, err) 30 | assert.NotEqual(t, buff2, buff3) 31 | 32 | // let's try LittleEndian function 33 | buff4 := i.LittleEndian(0, 32) 34 | assert.Equal(t, buff3, buff4) 35 | // set endianess but using littleendian should not change anything 36 | i.BO = BigEndian 37 | assert.Equal(t, buff4, i.LittleEndian(0, 32)) 38 | 39 | // Try to reconstruct the int from the buffer 40 | i = new(Int).Init64(v, modulo) 41 | i2 := NewInt64(0, modulo) 42 | buff, _ := i.MarshalBinary() 43 | assert.Nil(t, i2.UnmarshalBinary(buff)) 44 | assert.True(t, i.Equal(i2)) 45 | 46 | i.BO = LittleEndian 47 | buff, _ = i.MarshalBinary() 48 | i2.BO = LittleEndian 49 | assert.Nil(t, i2.UnmarshalBinary(buff)) 50 | assert.True(t, i.Equal(i2)) 51 | 52 | i2.BO = BigEndian 53 | assert.Nil(t, i2.UnmarshalBinary(buff)) 54 | assert.False(t, i.Equal(i2)) 55 | } 56 | func TestIntEndianBytes(t *testing.T) { 57 | modulo, err := hex.DecodeString("1000") 58 | moduloI := new(big.Int).SetBytes(modulo) 59 | assert.Nil(t, err) 60 | v, err := hex.DecodeString("10") 61 | assert.Nil(t, err) 62 | 63 | i := new(Int).InitBytes(v, moduloI, BigEndian) 64 | 65 | assert.Equal(t, 2, i.MarshalSize()) 66 | assert.NotPanics(t, func() { i.LittleEndian(2, 2) }) 67 | } 68 | 69 | func TestInits(t *testing.T) { 70 | i1 := NewInt64(int64(65500), big.NewInt(65535)) 71 | i2 := NewInt(&i1.V, i1.M) 72 | assert.True(t, i1.Equal(i2)) 73 | b, _ := i1.MarshalBinary() 74 | i3 := NewIntBytes(b, i1.M, BigEndian) 75 | assert.True(t, i1.Equal(i3)) 76 | i4 := NewIntString(i1.String(), "", 16, i1.M) 77 | assert.True(t, i1.Equal(i4)) 78 | } 79 | 80 | func TestIntClone(t *testing.T) { 81 | moduloI := new(big.Int).SetBytes([]byte{0x10, 0}) 82 | base := new(Int).InitBytes([]byte{0x10}, moduloI, BigEndian) 83 | 84 | clone := base.Clone() 85 | clone.Add(clone, clone) 86 | b1, _ := clone.MarshalBinary() 87 | b2, _ := base.MarshalBinary() 88 | if bytes.Equal(b1, b2) { 89 | t.Error("Should not be equal") 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /group/nist/doc.go: -------------------------------------------------------------------------------- 1 | // Package nist implements cryptographic groups and ciphersuites 2 | // based on the NIST standards, using Go's built-in crypto library. 3 | // Since that package does not implement constant time arithmetic operations 4 | // yet, it must be compiled with the "vartime" compilation flag. 5 | package nist 6 | -------------------------------------------------------------------------------- /group/nist/group_test.go: -------------------------------------------------------------------------------- 1 | // +build vartime 2 | 3 | package nist 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/dedis/kyber/util/test" 9 | ) 10 | 11 | var testQR512 = NewBlakeSHA256QR512() 12 | 13 | func TestQR512(t *testing.T) { test.SuiteTest(t, testQR512) } 14 | 15 | var testP256 = NewBlakeSHA256P256() 16 | 17 | func TestP256(t *testing.T) { test.SuiteTest(t, testP256) } 18 | 19 | func TestSetBytesBE(t *testing.T) { 20 | s := testP256.Scalar() 21 | s.SetBytes([]byte{0, 1, 2, 3}) 22 | // 010203 because initial 0 is trimmed in String(), and 03 (last byte of BE) ends up 23 | // in the LSB of the bigint. 24 | if s.String() != "010203" { 25 | t.Fatal("unexpected result from String():", s.String()) 26 | } 27 | } 28 | 29 | var benchP256 = test.NewGroupBench(testP256) 30 | 31 | func BenchmarkScalarAdd(b *testing.B) { benchP256.ScalarAdd(b.N) } 32 | func BenchmarkScalarSub(b *testing.B) { benchP256.ScalarSub(b.N) } 33 | func BenchmarkScalarNeg(b *testing.B) { benchP256.ScalarNeg(b.N) } 34 | func BenchmarkScalarMul(b *testing.B) { benchP256.ScalarMul(b.N) } 35 | func BenchmarkScalarDiv(b *testing.B) { benchP256.ScalarDiv(b.N) } 36 | func BenchmarkScalarInv(b *testing.B) { benchP256.ScalarInv(b.N) } 37 | func BenchmarkScalarPick(b *testing.B) { benchP256.ScalarPick(b.N) } 38 | func BenchmarkScalarEncode(b *testing.B) { benchP256.ScalarEncode(b.N) } 39 | func BenchmarkScalarDecode(b *testing.B) { benchP256.ScalarDecode(b.N) } 40 | 41 | func BenchmarkPointAdd(b *testing.B) { benchP256.PointAdd(b.N) } 42 | func BenchmarkPointSub(b *testing.B) { benchP256.PointSub(b.N) } 43 | func BenchmarkPointNeg(b *testing.B) { benchP256.PointNeg(b.N) } 44 | func BenchmarkPointMul(b *testing.B) { benchP256.PointMul(b.N) } 45 | func BenchmarkPointBaseMul(b *testing.B) { benchP256.PointBaseMul(b.N) } 46 | func BenchmarkPointPick(b *testing.B) { benchP256.PointPick(b.N) } 47 | func BenchmarkPointEncode(b *testing.B) { benchP256.PointEncode(b.N) } 48 | func BenchmarkPointDecode(b *testing.B) { benchP256.PointDecode(b.N) } 49 | -------------------------------------------------------------------------------- /group/nist/p256.go: -------------------------------------------------------------------------------- 1 | // +build vartime 2 | 3 | package nist 4 | 5 | import ( 6 | "crypto/elliptic" 7 | "math/big" 8 | ) 9 | 10 | // P256 implements the kyber.Group interface 11 | // for the NIST P-256 elliptic curve, 12 | // based on Go's native elliptic curve library. 13 | type p256 struct { 14 | curve 15 | } 16 | 17 | func (curve *p256) String() string { 18 | return "P256" 19 | } 20 | 21 | // Optimized modular square root for P-256 curve, from 22 | // "Mathematical routines for the NIST prime elliptic curves" (April 2010) 23 | func (curve *p256) sqrt(c *big.Int) *big.Int { 24 | m := curve.p.P 25 | 26 | t1 := new(big.Int) 27 | t1.Mul(c, c) 28 | t1.Mul(t1, c) // t1 = c^(2^2-1) 29 | 30 | p2 := new(big.Int) 31 | p2.SetBit(p2, 2, 1) 32 | t2 := new(big.Int) 33 | t2.Exp(t1, p2, m) 34 | t2.Mul(t2, t1) // t2 = c^(2^4-1) 35 | 36 | p3 := new(big.Int) 37 | p3.SetBit(p3, 4, 1) 38 | t3 := new(big.Int) 39 | t3.Exp(t2, p3, m) 40 | t3.Mul(t3, t2) // t3 = c^(2^8-1) 41 | 42 | p4 := new(big.Int) 43 | p4.SetBit(p4, 8, 1) 44 | t4 := new(big.Int) 45 | t4.Exp(t3, p4, m) 46 | t4.Mul(t4, t3) // t4 = c^(2^16-1) 47 | 48 | p5 := new(big.Int) 49 | p5.SetBit(p5, 16, 1) 50 | r := new(big.Int) 51 | r.Exp(t4, p5, m) 52 | r.Mul(r, t4) // r = c^(2^32-1) 53 | 54 | p6 := new(big.Int) 55 | p6.SetBit(p6, 32, 1) 56 | r.Exp(r, p6, m) 57 | r.Mul(r, c) // r = c^(2^64-2^32+1) 58 | 59 | p7 := new(big.Int) 60 | p7.SetBit(p7, 96, 1) 61 | r.Exp(r, p7, m) 62 | r.Mul(r, c) // r = c^(2^160-2^128+2^96+1) 63 | 64 | p8 := new(big.Int) 65 | p8.SetBit(p8, 94, 1) 66 | r.Exp(r, p8, m) 67 | 68 | // r = c^(2^254-2^222+2^190+2^94) = sqrt(c) mod p256 69 | return r 70 | } 71 | 72 | // Initialize standard Curve instances 73 | func (c *p256) Init() curve { 74 | c.curve.Curve = elliptic.P256() 75 | c.p = c.Params() 76 | c.curveOps = c 77 | return c.curve 78 | } 79 | -------------------------------------------------------------------------------- /group/nist/qrsuite.go: -------------------------------------------------------------------------------- 1 | // +build vartime 2 | 3 | package nist 4 | 5 | import ( 6 | "crypto/cipher" 7 | "crypto/sha256" 8 | "hash" 9 | "io" 10 | "math/big" 11 | "reflect" 12 | 13 | "github.com/dedis/fixbuf" 14 | 15 | "github.com/dedis/kyber" 16 | "github.com/dedis/kyber/group/internal/marshalling" 17 | "github.com/dedis/kyber/util/random" 18 | "github.com/dedis/kyber/xof/blake2xb" 19 | ) 20 | 21 | type QrSuite struct { 22 | ResidueGroup 23 | } 24 | 25 | // SHA256 hash function 26 | func (s QrSuite) Hash() hash.Hash { 27 | return sha256.New() 28 | } 29 | 30 | func (s QrSuite) XOF(key []byte) kyber.XOF { 31 | return blake2xb.New(key) 32 | } 33 | 34 | func (s QrSuite) RandomStream() cipher.Stream { 35 | return random.New() 36 | } 37 | 38 | func (s *QrSuite) Read(r io.Reader, objs ...interface{}) error { 39 | return fixbuf.Read(r, s, objs) 40 | } 41 | 42 | func (s *QrSuite) Write(w io.Writer, objs ...interface{}) error { 43 | return fixbuf.Write(w, objs) 44 | } 45 | 46 | func (s *QrSuite) New(t reflect.Type) interface{} { 47 | return marshalling.GroupNew(s, t) 48 | } 49 | 50 | // NewBlakeSHA256QR512 returns a cipher suite based on package 51 | // github.com/dedis/kyber/xof/blake2xb, SHA-256, and a residue group of 52 | // quadratic residues modulo a 512-bit prime. 53 | // 54 | // This group size should be used only for testing and experimentation. 55 | // 512-bit DSA-style groups are no longer considered secure. 56 | func NewBlakeSHA256QR512() *QrSuite { 57 | p, _ := new(big.Int).SetString("10198267722357351868598076141027380280417188309231803909918464305012113541414604537422741096561285049775792035177041672305646773132014126091142862443826263", 10) 58 | q, _ := new(big.Int).SetString("5099133861178675934299038070513690140208594154615901954959232152506056770707302268711370548280642524887896017588520836152823386566007063045571431221913131", 10) 59 | r := new(big.Int).SetInt64(2) 60 | g := new(big.Int).SetInt64(4) 61 | 62 | suite := new(QrSuite) 63 | suite.SetParams(p, q, r, g) 64 | return suite 65 | } 66 | -------------------------------------------------------------------------------- /group/nist/suite.go: -------------------------------------------------------------------------------- 1 | // +build vartime 2 | 3 | package nist 4 | 5 | import ( 6 | "crypto/cipher" 7 | "crypto/sha256" 8 | "hash" 9 | "io" 10 | "reflect" 11 | 12 | "github.com/dedis/fixbuf" 13 | 14 | "github.com/dedis/kyber" 15 | "github.com/dedis/kyber/group/internal/marshalling" 16 | "github.com/dedis/kyber/util/random" 17 | "github.com/dedis/kyber/xof/blake2xb" 18 | ) 19 | 20 | type Suite128 struct { 21 | p256 22 | } 23 | 24 | // SHA256 hash function 25 | func (s *Suite128) Hash() hash.Hash { 26 | return sha256.New() 27 | } 28 | 29 | func (s *Suite128) XOF(key []byte) kyber.XOF { 30 | return blake2xb.New(key) 31 | } 32 | 33 | func (s *Suite128) RandomStream() cipher.Stream { 34 | return random.New() 35 | } 36 | 37 | func (s *Suite128) Read(r io.Reader, objs ...interface{}) error { 38 | return fixbuf.Read(r, s, objs) 39 | } 40 | 41 | func (s *Suite128) Write(w io.Writer, objs ...interface{}) error { 42 | return fixbuf.Write(w, objs) 43 | } 44 | 45 | func (s *Suite128) New(t reflect.Type) interface{} { 46 | return marshalling.GroupNew(s, t) 47 | } 48 | 49 | // NewBlakeSHA256P256 returns a cipher suite based on package 50 | // github.com/dedis/kyber/xof/blake2xb, SHA-256, and the NIST P-256 51 | // elliptic curve. It returns random streams from Go's crypto/rand. 52 | // 53 | // The scalars created by this group implement kyber.Scalar's SetBytes 54 | // method, interpreting the bytes as a big-endian integer, so as to be 55 | // compatible with the Go standard library's big.Int type. 56 | func NewBlakeSHA256P256() *Suite128 { 57 | suite := new(Suite128) 58 | suite.p256.Init() 59 | return suite 60 | } 61 | -------------------------------------------------------------------------------- /log/logger.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "reflect" 7 | "strings" 8 | "time" 9 | 10 | "github.com/sirupsen/logrus" 11 | //errors "golang.org/x/xerrors" 12 | ) 13 | 14 | /* 15 | Example: 16 | 17 | import ( 18 | "errors" 19 | "time" 20 | log "github.com/DOSNetwork/core/log" 21 | ) 22 | 23 | func myfunc() error { 24 | return errors.New("error message") 25 | } 26 | func main() { 27 | startTime := time.Now() 28 | log.Info("test") 29 | 30 | time.Sleep(500 * time.Millisecond) 31 | log.Metrics("time-cost", time.Since(startTime).Seconds()) 32 | 33 | srvlog := log.New("module", "service") 34 | srvlog.Error(myfunc()) 35 | } 36 | */ 37 | 38 | // A Logger writes key/value pairs to a Handler 39 | type Logger interface { 40 | // New returns a new Logger that has this logger's context plus the given context 41 | New(key string, value interface{}) Logger 42 | AddField(key string, value interface{}) 43 | Debug(msg string) 44 | Info(msg string) 45 | Warn(msg string) 46 | Error(err error) 47 | Fatal(err error) 48 | TimeTrack(time.Time, string, map[string]interface{}) 49 | Event(e string, f map[string]interface{}) 50 | } 51 | 52 | type logger struct { 53 | entry *logrus.Entry 54 | } 55 | 56 | func (l *logger) New(key string, value interface{}) Logger { 57 | if l.entry != nil { 58 | return &logger{l.entry.WithFields(logrus.Fields{key: value})} 59 | } 60 | return nil 61 | } 62 | 63 | func (l *logger) AddField(key string, value interface{}) { 64 | if l.entry == nil { 65 | return 66 | } 67 | l.entry = l.entry.WithFields(logrus.Fields{key: value}) 68 | } 69 | 70 | func (l *logger) Debug(msg string) { 71 | if l.entry == nil { 72 | return 73 | } 74 | l.entry.Debug(msg) 75 | } 76 | 77 | func (l *logger) Info(msg string) { 78 | if l.entry == nil { 79 | return 80 | } 81 | l.entry.Info(msg) 82 | } 83 | 84 | func (l *logger) Warn(msg string) { 85 | if l.entry == nil { 86 | return 87 | } 88 | l.entry.Warn(msg) 89 | } 90 | 91 | func (l *logger) Error(err error) { 92 | if l.entry == nil { 93 | return 94 | } 95 | ss := strings.FieldsFunc(fmt.Sprintf("%+v", err), func(r rune) bool { 96 | if r == '-' { 97 | return true 98 | } 99 | return false 100 | }) 101 | errCause := "" 102 | if len(ss) >= 1 { 103 | c := strings.Split(ss[len(ss)-1], ":") 104 | errCause = c[0] 105 | } 106 | l.entry.WithFields(logrus.Fields{"errCause": errCause, "errDetail": fmt.Sprintf("%+v", err), "errType": reflect.TypeOf(err).String()}).Error() 107 | 108 | } 109 | 110 | func (l *logger) Fatal(err error) { 111 | if l.entry == nil { 112 | os.Exit(1) 113 | return 114 | } 115 | l.entry.Fatal(err) 116 | os.Exit(1) 117 | } 118 | 119 | func (l *logger) Event(e string, info map[string]interface{}) { 120 | if l.entry == nil { 121 | return 122 | } 123 | if info != nil { 124 | l.entry.WithFields(logrus.Fields{"EVENT": e}).WithFields(info).Debug("") 125 | } else { 126 | l.entry.WithFields(logrus.Fields{"EVENT": e}).Debug("") 127 | } 128 | } 129 | 130 | func (l *logger) TimeTrack(start time.Time, e string, info map[string]interface{}) { 131 | elapsed := time.Since(start).Nanoseconds() / 1000 132 | 133 | if l.entry == nil { 134 | return 135 | } 136 | if info != nil { 137 | l.entry.WithFields(logrus.Fields{"EVENT": e, e: elapsed}).WithFields(info).Debug("") 138 | } else { 139 | l.entry.WithFields(logrus.Fields{"EVENT": e, e: elapsed}).Debug("") 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /log/root.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "strings" 9 | "time" 10 | 11 | "github.com/bshuster-repo/logrus-logstash-hook" 12 | rotatelogs "github.com/lestrrat-go/file-rotatelogs" 13 | "github.com/rifflock/lfshook" 14 | "github.com/sirupsen/logrus" 15 | "golang.org/x/crypto/sha3" 16 | ) 17 | 18 | var ( 19 | root = &logger{} 20 | ) 21 | 22 | type dosFormatter struct { 23 | logrus.TextFormatter 24 | } 25 | 26 | func (f *dosFormatter) Format(entry *logrus.Entry) ([]byte, error) { 27 | // this whole mess of dealing with ansi color codes is required if you want the colored output otherwise you will lose colors in the log levels 28 | var levelColor int 29 | switch entry.Level { 30 | case logrus.DebugLevel, logrus.TraceLevel: 31 | levelColor = 32 // green 32 | case logrus.WarnLevel: 33 | levelColor = 33 // yellow 34 | case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel: 35 | levelColor = 31 // red 36 | default: 37 | levelColor = 36 // blue 38 | } 39 | var msg string 40 | if len(entry.Message) > 0 { 41 | msg = entry.Message 42 | } else { 43 | msg, _ = entry.String() 44 | } 45 | return []byte(fmt.Sprintf("[%s] - \x1b[%dm%s\x1b[0m - %s\n", entry.Time.Format(f.TimestampFormat), levelColor, strings.ToUpper(entry.Level.String()), msg)), nil 46 | } 47 | 48 | // New returns a new logger with the given key/value . 49 | // New is a convenient alias for Root().New 50 | func New(key string, value interface{}) Logger { 51 | if root == nil { 52 | fmt.Println("no root") 53 | } 54 | return root.New(key, value) 55 | } 56 | 57 | // Init setups default field and add hook 58 | func Init(id []byte) { 59 | appSession := os.Getenv("APPSESSION") 60 | logIp := os.Getenv("LOGIP") 61 | nodeId := byteTohex(id) 62 | os.Setenv("NODEID", nodeId) 63 | logrus.SetOutput(ioutil.Discard) 64 | // Use INFO log level by default 65 | lvl, ok := os.LookupEnv("LOG_LEVEL") 66 | if !ok { 67 | lvl = "info" 68 | } 69 | ll, err := logrus.ParseLevel(lvl) 70 | if err != nil { 71 | ll = logrus.InfoLevel 72 | } 73 | logrus.SetLevel(ll) 74 | 75 | if logIp != "" { 76 | logrus.SetLevel(logrus.DebugLevel) 77 | hook, err := logrustash.NewHook("tcp", logIp, appSession) 78 | if err != nil { 79 | fmt.Println(err) 80 | logrus.Error(err) 81 | } 82 | logrus.AddHook(hook) 83 | } 84 | 85 | path := "./vault/doslog.txt" 86 | writer, err := rotatelogs.New( 87 | path+".%Y-%m-%d-%H-%M-%S", 88 | rotatelogs.WithLinkName(path), 89 | rotatelogs.WithMaxAge(time.Duration(86400)*time.Second), 90 | rotatelogs.WithRotationTime(time.Duration(604800)*time.Second), 91 | ) 92 | if err != nil { 93 | fmt.Println("rotatelogs.New err", err) 94 | } 95 | 96 | logrus.AddHook(lfshook.NewHook( 97 | lfshook.WriterMap{ 98 | logrus.InfoLevel: writer, 99 | logrus.DebugLevel: writer, 100 | logrus.ErrorLevel: writer, 101 | }, 102 | &dosFormatter{ 103 | logrus.TextFormatter{ 104 | ForceColors: true, 105 | TimestampFormat: "2006-01-02 15:04:05", 106 | FullTimestamp: true, 107 | }, 108 | }, 109 | )) 110 | root.entry = logrus.WithFields(logrus.Fields{}) 111 | } 112 | 113 | func byteTohex(a []byte) string { 114 | unchecksummed := hex.EncodeToString(a[:]) 115 | sha := sha3.NewLegacyKeccak256() 116 | sha.Write([]byte(unchecksummed)) 117 | hash := sha.Sum(nil) 118 | 119 | result := []byte(unchecksummed) 120 | for i := 0; i < len(result); i++ { 121 | hashByte := hash[i/2] 122 | if i%2 == 0 { 123 | hashByte = hashByte >> 4 124 | } else { 125 | hashByte &= 0xf 126 | } 127 | if result[i] > '9' && hashByte > 7 { 128 | result[i] -= 32 129 | } 130 | } 131 | return "" + string(result) 132 | } 133 | 134 | // AddField is a convenient alias for Root().AddField 135 | func AddField(key string, value interface{}) { 136 | root.AddField(key, value) 137 | } 138 | 139 | // Debug is a convenient alias for Root().Debug 140 | func Debug(msg string) { 141 | root.Debug(msg) 142 | } 143 | 144 | // Info is a convenient alias for Root().Info 145 | func Info(msg string) { 146 | root.Info(msg) 147 | } 148 | 149 | // Warn is a convenient alias for Root().Warn 150 | func Warn(msg string) { 151 | root.Warn(msg) 152 | } 153 | 154 | // Error is a convenient alias for Root().Error 155 | func Error(err error) { 156 | if root != nil { 157 | root.Error(err) 158 | } 159 | } 160 | 161 | // Fatal is a convenient alias for Root().Fatal 162 | func Fatal(err error) { 163 | root.Fatal(err) 164 | } 165 | 166 | // Event is a convenient alias for Root().Event 167 | func Event(e string, f map[string]interface{}) { 168 | root.Event(e, f) 169 | } 170 | 171 | // TimeTrack is a convenient alias for Root().TimeTrack 172 | func TimeTrack(start time.Time, e string, info map[string]interface{}) { 173 | root.TimeTrack(start, e, info) 174 | } 175 | -------------------------------------------------------------------------------- /media/logo-white.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/media/logo-white.jpg -------------------------------------------------------------------------------- /onchain/chain_adaptor.go: -------------------------------------------------------------------------------- 1 | package onchain 2 | 3 | import ( 4 | /// "context" 5 | "fmt" 6 | "math/big" 7 | "time" 8 | 9 | "github.com/DOSNetwork/core/configuration" 10 | "github.com/DOSNetwork/core/log" 11 | "github.com/DOSNetwork/core/share/vss/pedersen" 12 | "github.com/ethereum/go-ethereum/accounts/keystore" 13 | "github.com/ethereum/go-ethereum/common" 14 | errors "golang.org/x/xerrors" 15 | ) 16 | 17 | const ( 18 | //ETH represents the type of blockchain 19 | ETH = "ETH" 20 | HECO = "Heco" 21 | BSC = "BSC" 22 | OKCHAIN = "Okchain" 23 | ) 24 | 25 | //ProxyAdapter represents an unified adapter interface for different blockchain 26 | type ProxyAdapter interface { 27 | Connect(urls []string, deadline time.Time) (err error) 28 | DisconnectAll() 29 | DisconnectWs(idx int) 30 | SubscribeEvent(subscribeTypes []int) (chan interface{}, chan error) 31 | //Set functions 32 | SetGroupSize(g uint64) (err error) 33 | UpdateRandomness(signatures *vss.Signature) (err error) 34 | DataReturn(signatures *vss.Signature) (err error) 35 | RegisterGroupPubKey(IdWithPubKeys [5]*big.Int) (err error) 36 | RegisterNewNode() (err error) 37 | UnRegisterNode() (err error) 38 | SignalRandom() (err error) 39 | SignalGroupFormation() (err error) 40 | SignalGroupDissolve() (err error) 41 | SignalBootstrap(cid *big.Int) (err error) 42 | SignalUnregister(addr common.Address) (err error) 43 | StartCommitReveal(startBlock int64, commitDuration int64, revealDuration int64, revealThreshold int64) (err error) 44 | Commit(cid *big.Int, commitment [32]byte) (err error) 45 | Reveal(cid *big.Int, secret *big.Int) (err error) 46 | SetGasPrice(gasPrice *big.Int) 47 | SetGasLimit(gasLimit *big.Int) 48 | //Get functions 49 | GetBlockTime() (result uint64) 50 | GetGasPrice() (result uint64) 51 | GetGasLimit() (result uint64) 52 | GroupToPick() (result uint64, err error) 53 | PendingNonce() (result uint64, err error) 54 | GetExpiredWorkingGroupSize() (r uint64, err error) 55 | GroupSize() (r uint64, err error) 56 | GetWorkingGroupSize() (r uint64, err error) 57 | LastGroupFormationRequestId() (r uint64, err error) 58 | LastUpdatedBlock() (r uint64, err error) 59 | PendingGroupStartBlock(gId *big.Int) (r uint64, err error) 60 | PendingGroupMaxLife() (r uint64, err error) 61 | FirstPendingGroupId() (gId *big.Int, err error) 62 | NumPendingGroups() (r uint64, err error) 63 | NumPendingNodes() (r uint64, err error) 64 | BootstrapEndBlk() (result uint64, err error) 65 | BootstrapRound() (result uint64, err error) 66 | Balance() (balance *big.Float, err error) 67 | Address() (addr common.Address) 68 | CurrentBlock() (r uint64, err error) 69 | RefreshSystemRandomHardLimit() (limit uint64, err error) 70 | CachedUpdatedBlock() (blkNum uint64, err error) 71 | RelayRespondLimit() (limit uint64, err error) 72 | BootstrapStartThreshold() (result uint64, err error) 73 | IsPendingNode(id []byte) (bool, error) 74 | BootStrapUrl() string 75 | } 76 | 77 | //NewProxyAdapter constructs a new ProxyAdapter with the given type of blockchain and contract addresses 78 | func NewProxyAdapter(key *keystore.Key, config *configuration.Config) (ProxyAdapter, error) { 79 | switch config.ChainType { 80 | case ETH, HECO, BSC, OKCHAIN: 81 | l := log.New("module", "EthProxy") 82 | adaptor, err := NewEthAdaptor(key, config, l) 83 | if err != nil { 84 | l.Error(errors.Errorf("NewProxyAdapter : %w", err)) 85 | } 86 | return adaptor, err 87 | default: 88 | err := fmt.Errorf("Chain %s not supported error\n", config.ChainType) 89 | return nil, err 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /onchain/commitreveal/CommitReveal.abi: -------------------------------------------------------------------------------- 1 | [{"inputs":[{"internalType":"address","name":"_bridgeAddr","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cid","type":"uint256"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"bytes32","name":"commitment","type":"bytes32"}],"name":"LogCommit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"random","type":"uint256"}],"name":"LogRandom","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"commitNum","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"revealNum","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"revealThreshold","type":"uint256"}],"name":"LogRandomFailure","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cid","type":"uint256"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"secret","type":"uint256"}],"name":"LogReveal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"commitDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"revealDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"revealThreshold","type":"uint256"}],"name":"LogStartCommitReveal","type":"event"},{"constant":true,"inputs":[],"name":"addressBridge","outputs":[{"internalType":"contract DOSAddressBridgeI","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"campaigns","outputs":[{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"commitDuration","type":"uint256"},{"internalType":"uint256","name":"revealDuration","type":"uint256"},{"internalType":"uint256","name":"revealThreshold","type":"uint256"},{"internalType":"uint256","name":"commitNum","type":"uint256"},{"internalType":"uint256","name":"revealNum","type":"uint256"},{"internalType":"uint256","name":"generatedRandom","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_cid","type":"uint256"},{"internalType":"bytes32","name":"_secretHash","type":"bytes32"}],"name":"commit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_cid","type":"uint256"}],"name":"getRandom","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_cid","type":"uint256"},{"internalType":"uint256","name":"_secret","type":"uint256"}],"name":"reveal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_commitDuration","type":"uint256"},{"internalType":"uint256","name":"_revealDuration","type":"uint256"},{"internalType":"uint256","name":"_revealThreshold","type":"uint256"}],"name":"startCommitReveal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/commitreveal/CommitReveal.bin: -------------------------------------------------------------------------------- 1 | 608060405234801561001057600080fd5b50604051610ab0380380610ab08339818101604052602081101561003357600080fd5b50516000805490610047906001830161006d565b50600180546001600160a01b0319166001600160a01b03929092169190911790556100e8565b81548183558181111561009957600902816009028360005260206000209182019101610099919061009e565b505050565b6100e591905b808211156100e1576000808255600182018190556002820181905560038201819055600482018190556005820181905560068201556009016100a4565b5090565b90565b6109b9806100f76000396000f3fe608060405234801561001057600080fd5b50600436106100625760003560e01c8063141961bc1461006757806376cffa53146100bc5780639348cef7146100e0578063b917b5a514610105578063cd4b691414610146578063f2f0387714610163575b600080fd5b6100846004803603602081101561007d57600080fd5b5035610186565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b6100c46101d5565b604080516001600160a01b039092168252519081900360200190f35b610103600480360360408110156100f657600080fd5b50803590602001356101e4565b005b6101346004803603608081101561011b57600080fd5b5080359060208101359060408101359060600135610388565b60408051918252519081900360200190f35b6101346004803603602081101561015c57600080fd5b50356105f9565b6101036004803603604081101561017957600080fd5b5080359060200135610763565b6000818154811061019357fe5b90600052602060002090600902016000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154905087565b6001546001600160a01b031681565b8160008082815481106101f357fe5b906000526020600020906009020190508160001415801561021b575060018101548154014310155b80156102335750600281015460018201548254010143105b610274576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd0b5a5b8b5c995d99585b609a1b604482015290519081900360640190fd5b600080858154811061028257fe5b6000918252602080832033845260076009909302019182019052604090912060028101549192509060ff161580156102dc575060018101546040805160208082018990528251808303820181529183019092528051910120145b6103175760405162461bcd60e51b81526004018080602001828103825260248152602001806109616024913960400191505060405180910390fd5b84815560028101805460ff191660019081179091556005830180549091019055600682018054861890556040805187815233602082015280820187905290517f9141bfaedbc77aa7b8d9c989cd81909d95bb1677e556e34cfd45e50e0bea29679181900360600190a1505050505050565b600154604080516321d39ecd60e11b815290516000926001600160a01b0316916343a73d9a916004808301926020929190829003018186803b1580156103cd57600080fd5b505afa1580156103e1573d6000803e3d6000fd5b505050506040513d60208110156103f757600080fd5b50516001600160a01b0316331461044a576040805162461bcd60e51b81526020600482015260126024820152716e6f742d66726f6d2d646f732d70726f787960701b604482015290519081900360640190fd5b600080546040805160e081018252888152602080820189815282840189815260608085018a815260808087018a815260a08089018c815260c08a018d815260018d018e559c8052985160098c027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56381019190915596517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56488015594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56587015591517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56686015590517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56785015594517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56884015596517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5699092019190915583518581529182018b90528184018a9052948101889052908101869052905191927fbbfccb30e8cf1b5d88802741ceb4d63cf854fa8931eeeaec6b700f31f429dc0992918290030190a195945050505050565b600081600080828154811061060a57fe5b9060005260206000209060090201905081600014158015610638575060028101546001820154825401014310155b610689576040805162461bcd60e51b815260206004820152601a60248201527f636f6d6d69742d72657665616c2d6e6f742d66696e6973686564000000000000604482015290519081900360640190fd5b600080858154811061069757fe5b90600052602060002090600902019050806003015481600501541061070157600681015460408051878152602081019290925280517fa34f42a90fadfe357ee14419d618438a057569fbb63bab0c5fbcca0fc2b11e8d9281900390910190a160060154925061075c565b600481015460058201546003830154604080518981526020810194909452838101929092526060830152517fe888e7582d0505bce81eef694dfa216179eaaa3c1bd96b7894de8b4370d8543e9181900360800190a160009350505b5050919050565b8181600080838154811061077357fe5b9060005260206000209060090201905082600014158015610795575080544310155b80156107a75750600181015481540143105b6107e8576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd0b5a5b8b58dbdb5b5a5d609a1b604482015290519081900360640190fd5b8161082d576040805162461bcd60e51b815260206004820152601060248201526f195b5c1d1e4b58dbdb5b5a5d1b595b9d60821b604482015290519081900360640190fd5b600082815260088201602052604090205460ff161561088a576040805162461bcd60e51b8152602060048201526014602482015273191d5c1b1a58d85d194b58dbdb5b5a5d1b595b9d60621b604482015290519081900360640190fd5b600080868154811061089857fe5b60009182526020808320888452600860099093020191820181526040808420805460ff1990811660019081179092558251606080820185528782528186018d815282860189815233808b5260078a01895299879020935184559051838601555160029092018054921515929093169190911790915560048501805490920190915581518b815292830194909452818101899052519193507f918c00c65dd2a8dee4c6985d1d67f04aa8cd2c93e8d427d398a90444c7f7c75e92908290030190a150505050505056fe72657665616c65642d7365637265742d6e6f742d6d617463682d636f6d6d69746d656e74a265627a7a723158202709e9c899007f7199c6aa507a46acd19eb2cbe61fcf3472c06fee399a697a3464736f6c63430005110032 -------------------------------------------------------------------------------- /onchain/commitreveal/DOSAddressBridgeI.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[],"name":"getProxyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}] -------------------------------------------------------------------------------- /onchain/commitreveal/DOSAddressBridgeI.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/commitreveal/DOSAddressBridgeI.bin -------------------------------------------------------------------------------- /onchain/dosbridge/DOSAddressBridge.abi: -------------------------------------------------------------------------------- 1 | [{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"previousURL","type":"string"},{"indexed":false,"internalType":"string","name":"newURL","type":"string"}],"name":"BootStrapUrlUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAddr","type":"address"},{"indexed":false,"internalType":"address","name":"newAddr","type":"address"}],"name":"CommitRevealAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousPayment","type":"address"},{"indexed":false,"internalType":"address","name":"newPayment","type":"address"}],"name":"PaymentAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousProxy","type":"address"},{"indexed":false,"internalType":"address","name":"newProxy","type":"address"}],"name":"ProxyAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousStaking","type":"address"},{"indexed":false,"internalType":"address","name":"newStaking","type":"address"}],"name":"StakingAddressUpdated","type":"event"},{"constant":true,"inputs":[],"name":"getBootStrapUrl","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCommitRevealAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPaymentAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getProxyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStakingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"url","type":"string"}],"name":"setBootStrapUrl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAddr","type":"address"}],"name":"setCommitRevealAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAddr","type":"address"}],"name":"setPaymentAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAddr","type":"address"}],"name":"setProxyAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newAddr","type":"address"}],"name":"setStakingAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosbridge/DOSAddressBridge.bin: -------------------------------------------------------------------------------- 1 | 6080604052600080546001600160a01b03191633179055610907806100256000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637b08cd031161008c5780639d265e58116100665780639d265e5814610269578063b7e982be14610271578063f2fde38b146102ee578063f4e0d9ac14610314576100ea565b80637b08cd031461021f5780638da5cb5b146102455780638f32d59b1461024d576100ea565b80634400bc07116100c85780634400bc071461012357806346a7dadc146101cb5780635e1e1004146101f1578063715018a614610217576100ea565b80630e9ed68b146100ef5780631ae0433c1461011357806343a73d9a1461011b575b600080fd5b6100f761033a565b604080516001600160a01b039092168252519081900360200190f35b6100f761034a565b6100f7610359565b6101c96004803603602081101561013957600080fd5b81019060208101813564010000000081111561015457600080fd5b82018360208201111561016657600080fd5b8035906020019184600183028401116401000000008311171561018857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610368945050505050565b005b6101c9600480360360208110156101e157600080fd5b50356001600160a01b03166104a5565b6101c96004803603602081101561020757600080fd5b50356001600160a01b0316610520565b6101c961059b565b6101c96004803603602081101561023557600080fd5b50356001600160a01b03166105f4565b6100f761066f565b61025561067e565b604080519115158252519081900360200190f35b6100f761068f565b61027961069e565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102b357818101518382015260200161029b565b50505050905090810190601f1680156102e05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101c96004803603602081101561030457600080fd5b50356001600160a01b0316610734565b6101c96004803603602081101561032a57600080fd5b50356001600160a01b0316610751565b6004546001600160a01b03165b90565b6002546001600160a01b031690565b6001546001600160a01b031690565b61037061067e565b61037957600080fd5b6040805181815260058054600260001961010060018416150201909116049282018390527fc2194dd450e596fc07061b41e1cb9e4d38bd372ed38c6f909979d464f71cde7c92909184918190602082019060608301908690801561041e5780601f106103f35761010080835404028352916020019161041e565b820191906000526020600020905b81548152906001019060200180831161040157829003601f168201915b5050838103825284518152845160209182019186019080838360005b8381101561045257818101518382015260200161043a565b50505050905090810190601f16801561047f5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a180516104a190600590602084019061083a565b5050565b6104ad61067e565b6104b657600080fd5b600154604080516001600160a01b039283168152918316602083015280517fafa5c16901af5d392255707d27b3e2687e79a18df187b9f1525e7f0fc2144f6f9281900390910190a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b61052861067e565b61053157600080fd5b600354604080516001600160a01b039283168152918316602083015280517fb3d3f832f05d764f8934189cba7879e2dd829dd3f92749ec959339fd5cd8b0be9281900390910190a1600380546001600160a01b0319166001600160a01b0392909216919091179055565b6105a361067e565b6105ac57600080fd5b600080546040516001600160a01b03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a2600080546001600160a01b0319169055565b6105fc61067e565b61060557600080fd5b600254604080516001600160a01b039283168152918316602083015280517f23b082fc42fcc9c7d42de567b56abef6a737aa2600b8036ee5c304086a2545c39281900390910190a1600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b6003546001600160a01b031690565b60058054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561072a5780601f106106ff5761010080835404028352916020019161072a565b820191906000526020600020905b81548152906001019060200180831161070d57829003601f168201915b5050505050905090565b61073c61067e565b61074557600080fd5b61074e816107cc565b50565b61075961067e565b61076257600080fd5b600454604080516001600160a01b039283168152918316602083015280517f03fbfa1263b46c684780f3c24be11a2e189a59bedf0e316a7eae861cc769eb4f9281900390910190a1600480546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0381166107df57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061087b57805160ff19168380011785556108a8565b828001600101855582156108a8579182015b828111156108a857825182559160200191906001019061088d565b506108b49291506108b8565b5090565b61034791905b808211156108b457600081556001016108be56fea265627a7a72315820df4dfc812716bbcc980d3e18688b9bb09820906604fccac5a60ef6891323ecbe64736f6c63430005110032 -------------------------------------------------------------------------------- /onchain/dosbridge/Ownable.abi: -------------------------------------------------------------------------------- 1 | [{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosbridge/Ownable.bin: -------------------------------------------------------------------------------- 1 | 608060405234801561001057600080fd5b50600080546001600160a01b031916331790556101fa806100326000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063715018a6146100515780638da5cb5b1461005b5780638f32d59b1461007f578063f2fde38b1461009b575b600080fd5b6100596100c1565b005b61006361011a565b604080516001600160a01b039092168252519081900360200190f35b610087610129565b604080519115158252519081900360200190f35b610059600480360360208110156100b157600080fd5b50356001600160a01b031661013a565b6100c9610129565b6100d257600080fd5b600080546040516001600160a01b03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a2600080546001600160a01b0319169055565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b610142610129565b61014b57600080fd5b61015481610157565b50565b6001600160a01b03811661016a57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b039290921691909117905556fea265627a7a723158201ea9fe97f808c3826aa019a608f35caa203e0e9583f1058c21211290cb38996f64736f6c63430005110032 -------------------------------------------------------------------------------- /onchain/dospayment/DOSAddressBridgeInterface.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[],"name":"getProxyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}] -------------------------------------------------------------------------------- /onchain/dospayment/DOSAddressBridgeInterface.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dospayment/DOSAddressBridgeInterface.bin -------------------------------------------------------------------------------- /onchain/dospayment/ERC20.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/dospayment/ERC20.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dospayment/ERC20.bin -------------------------------------------------------------------------------- /onchain/dosproxy/BN256.abi: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /onchain/dosproxy/BN256.bin: -------------------------------------------------------------------------------- 1 | 60556023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a7231582054286ddae4e272bdfec4863e4757840a7a939f15bc5dea314216a27783eeb65264736f6c63430005110032 -------------------------------------------------------------------------------- /onchain/dosproxy/ICommitReveal.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getRandom","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"startCommitReveal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosproxy/ICommitReveal.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dosproxy/ICommitReveal.bin -------------------------------------------------------------------------------- /onchain/dosproxy/IDOSAddressBridge.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[],"name":"getCommitRevealAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPaymentAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getStakingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosproxy/IDOSAddressBridge.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dosproxy/IDOSAddressBridge.bin -------------------------------------------------------------------------------- /onchain/dosproxy/IDOSPayment.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"chargeServiceFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimGuardianReward","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"hasServiceFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"address[]","name":"","type":"address[]"}],"name":"recordServiceFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"setPaymentMethod","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosproxy/IDOSPayment.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dosproxy/IDOSPayment.bin -------------------------------------------------------------------------------- /onchain/dosproxy/IDOSStaking.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[{"internalType":"address","name":"_nodeAddr","type":"address"}],"name":"isValidStakingNode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_nodeAddr","type":"address"}],"name":"nodeStart","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_nodeAddr","type":"address"}],"name":"nodeStop","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosproxy/IDOSStaking.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dosproxy/IDOSStaking.bin -------------------------------------------------------------------------------- /onchain/dosproxy/IUserContract.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"__callback__","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"__callback__","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosproxy/IUserContract.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dosproxy/IUserContract.bin -------------------------------------------------------------------------------- /onchain/dosstaking/AddressBridgeI.abi: -------------------------------------------------------------------------------- 1 | [{"constant":true,"inputs":[],"name":"getProxyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosstaking/AddressBridgeI.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dosstaking/AddressBridgeI.bin -------------------------------------------------------------------------------- /onchain/dosstaking/DSMath.abi: -------------------------------------------------------------------------------- 1 | [] -------------------------------------------------------------------------------- /onchain/dosstaking/DSMath.bin: -------------------------------------------------------------------------------- 1 | 60556023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea265627a7a72315820d8cff3f2453f4bdd3790999093f956a93a380d1afb19932c9f16c8bba2f5f07f64736f6c63430005110032 -------------------------------------------------------------------------------- /onchain/dosstaking/ERC20I.abi: -------------------------------------------------------------------------------- 1 | [{"constant":false,"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}] -------------------------------------------------------------------------------- /onchain/dosstaking/ERC20I.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DOSNetwork/core/f81f8e7222376ce27e2a9f47bc91649ab08c4d6c/onchain/dosstaking/ERC20I.bin -------------------------------------------------------------------------------- /onchain/errors.go: -------------------------------------------------------------------------------- 1 | package onchain 2 | 3 | import ( 4 | "fmt" 5 | 6 | errors "golang.org/x/xerrors" 7 | ) 8 | 9 | type OnchainError struct { 10 | frame errors.Frame 11 | Idx int 12 | err error // the wrapped error 13 | } 14 | 15 | func (e *OnchainError) Format(f fmt.State, c rune) { 16 | errors.FormatError(e, f, c) 17 | } 18 | 19 | func (e *OnchainError) FormatError(p errors.Printer) error { 20 | p.Printf("Ocurred at: %d", e.Idx) 21 | e.frame.Format(p) 22 | return e.err 23 | } 24 | 25 | func (e *OnchainError) Error() string { 26 | return fmt.Sprint(e) 27 | } 28 | 29 | func (e *OnchainError) Unwrap() error { 30 | return e.err 31 | } 32 | -------------------------------------------------------------------------------- /onchain/eth_helpers_test.go: -------------------------------------------------------------------------------- 1 | package onchain 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | "time" 8 | 9 | "github.com/ethereum/go-ethereum/ethclient" 10 | ) 11 | 12 | const ( 13 | ID = 4 14 | ) 15 | 16 | func TestReadEthKey(t *testing.T) { 17 | _, err := ReadEthKey(credentialPath, passphrase) 18 | if err != nil { 19 | t.Errorf("ReadEthKey Error: %s.", err.Error()) 20 | } 21 | } 22 | 23 | func TestDialToEth(t *testing.T) { 24 | urls = []string{"http://123.123.123.123", "http://18.236.117.126:8545"} 25 | var clients []*ethclient.Client 26 | ctx := context.Background() 27 | outc := DialToEth(ctx, urls) 28 | for client := range outc { 29 | clients = append(clients, client) 30 | } 31 | if len(clients) != len(urls) { 32 | t.Errorf("Dial success count, got: %d, want: %d.", len(clients), len(urls)-1) 33 | } 34 | 35 | //Check to see if client is really working by getting networkID 36 | count := 0 37 | for _, client := range clients { 38 | id, err := client.NetworkID(ctx) 39 | //i/o timeout 40 | if err != nil { 41 | fmt.Println("NetworkID err ", err) 42 | client.Close() 43 | } else { 44 | if ID != id.Uint64() { 45 | t.Errorf("ID incorrect, got: %d, want: %d.", id.Uint64(), ID) 46 | } 47 | count++ 48 | } 49 | } 50 | if count != len(urls)-1 { 51 | t.Errorf("Dial count, got: %d, want: %d.", count, len(urls)-1) 52 | } 53 | fmt.Println("TestDialToEth pass") 54 | } 55 | 56 | func TestDialWS(t *testing.T) { 57 | urls = []string{"ws://18.236.117.126:8546", "ws:18.236.115.126:8546"} 58 | var clients []*ethclient.Client 59 | ctx := context.Background() 60 | outc := DialToEth(ctx, urls) 61 | for client := range outc { 62 | clients = append(clients, client) 63 | } 64 | if len(clients) != len(urls)-1 { 65 | t.Errorf("Dial success count, got: %d, want: %d.", len(clients), len(urls)-1) 66 | } 67 | 68 | fmt.Println("TestDialToEth pass") 69 | } 70 | 71 | func TestDialToEthDeadline(t *testing.T) { 72 | urls = []string{"ws://18.236.117.126:8546", "ws:18.236.115.126:8546"} 73 | d := time.Now().Add(1 * time.Second) 74 | ctx, cancelFunc := context.WithDeadline(context.Background(), d) 75 | defer cancelFunc() 76 | clients := DialToEth(ctx, urls) 77 | time.Sleep(2 * time.Second) 78 | 79 | for range clients { 80 | t.Errorf("Should not receive any client") 81 | } 82 | } 83 | 84 | func TestDialToEthErrHandling(t *testing.T) { 85 | var tUrls []string 86 | //It doesn't cause any error when dialing 87 | tUrls = append(tUrls, "http://123.123.123.123") 88 | //It cause an error (dial unix: missing address) 89 | tUrls = append(tUrls, "") 90 | tUrls = append(tUrls, "ws://123.123.123.123:8546") 91 | //tUrls = append(tUrls, "ws://51.15.0.157:8546") 92 | 93 | ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) 94 | defer cancel() 95 | //ctx := context.Background() 96 | 97 | clients := DialToEth(ctx, tUrls) 98 | 99 | count := 0 100 | for range clients { 101 | count++ 102 | } 103 | if count != 0 { 104 | t.Errorf("Dial success count, got: %d, want: %d.", count, 1) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /onchain/eventMsg.go: -------------------------------------------------------------------------------- 1 | package onchain 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/core/types" 8 | ) 9 | 10 | type LogCommon struct { 11 | Tx string 12 | BlockN uint64 13 | Removed bool 14 | Raw types.Log 15 | log interface{} 16 | } 17 | 18 | //LogUrl is an onchain event that DOSProxy requests a query result from the specified URL 19 | type LogUrl struct { 20 | QueryId *big.Int 21 | Timeout *big.Int 22 | DataSource string 23 | Selector string 24 | Randomness *big.Int 25 | DispatchedGroupId *big.Int 26 | } 27 | 28 | //LogRequestUserRandom is an onchain event that DOSProxy requests a random number with RequestID 29 | type LogRequestUserRandom struct { 30 | RequestId *big.Int 31 | LastSystemRandomness *big.Int 32 | UserSeed *big.Int 33 | DispatchedGroupId *big.Int 34 | } 35 | 36 | //LogUpdateRandom is an onchain event that DOSProxy requests a system random number 37 | type LogUpdateRandom struct { 38 | LastRandomness *big.Int 39 | DispatchedGroupId *big.Int 40 | } 41 | 42 | //LogValidationResult is an onchain event that shows a quesry result 43 | type LogValidationResult struct { 44 | TrafficType uint8 45 | TrafficId *big.Int 46 | Message []byte 47 | Signature [2]*big.Int 48 | PubKey [4]*big.Int 49 | Pass bool 50 | Version uint8 51 | } 52 | 53 | //LogGroupingInitiated is an onchain event that DOSProxy has requested a random number to form a new group 54 | type LogGroupingInitiated struct { 55 | NumPendingNodes *big.Int 56 | GroupSize *big.Int 57 | } 58 | 59 | //LogInsufficientWorkingGroup is an onchain event that means there are no enough working groups to mix with pending nodes to form a new group 60 | type LogInsufficientWorkingGroup struct { 61 | NumWorkingGroups *big.Int 62 | } 63 | 64 | //LogInsufficientPendingNode is an onchain event that means there are no enough pending nodes to form a new group 65 | type LogInsufficientPendingNode struct { 66 | NumPendingNodes *big.Int 67 | } 68 | 69 | //LogGrouping is an onchain event that DOSProxy requests the specified nodes to start DKG to generate a new pubkey 70 | type LogGrouping struct { 71 | GroupId *big.Int 72 | NodeId [][]byte 73 | } 74 | 75 | //LogPublicKeyAccepted is an onchain event that DOSProxy receives enough suggested pubkey so accepts it as a new pubkey 76 | type LogPublicKeyAccepted struct { 77 | GroupId *big.Int 78 | WorkingGroupSize *big.Int 79 | } 80 | 81 | //LogPublicKeySuggested is an onchain event that DOSProxy accepts a suggested pubkey 82 | type LogPublicKeySuggested struct { 83 | GroupId *big.Int 84 | Count *big.Int 85 | GroupSize *big.Int 86 | } 87 | 88 | //LogGroupDissolve is an onchain event that DOSProxy requests to dissolve a specified group 89 | type LogGroupDissolve struct { 90 | GroupId *big.Int 91 | } 92 | 93 | //LogUpdateGroupToPick is an onchain event that means GroupToPick is updated 94 | type LogUpdateGroupToPick struct { 95 | OldNum *big.Int 96 | NewNum *big.Int 97 | } 98 | 99 | //LogUpdateGroupSize is an onchain event that means GroupSize is updated 100 | type LogUpdateGroupSize struct { 101 | OldSize *big.Int 102 | NewSize *big.Int 103 | } 104 | 105 | //LogStartCommitReveal is an onchain event that means DOSProxy starts a new commit-revel process 106 | type LogStartCommitReveal struct { 107 | Cid *big.Int 108 | StartBlock *big.Int 109 | CommitDuration *big.Int 110 | RevealDuration *big.Int 111 | RevealThreshold *big.Int 112 | } 113 | 114 | //LogCommit is an onchain event that means a secret is committed 115 | type LogCommit struct { 116 | Cid *big.Int 117 | From common.Address 118 | Commitment [32]byte 119 | } 120 | 121 | //LogReveal is an onchain event that means a secret is revealed 122 | type LogReveal struct { 123 | Cid *big.Int 124 | From common.Address 125 | Secret *big.Int 126 | } 127 | 128 | //LogRandom is an onchain event that means a new random is generated by a commit-reveal process with Cid 129 | type LogRandom struct { 130 | Cid *big.Int 131 | Random *big.Int 132 | } 133 | -------------------------------------------------------------------------------- /onchain/request.go: -------------------------------------------------------------------------------- 1 | package onchain 2 | 3 | import ( 4 | "context" 5 | 6 | // "github.com/DOSNetwork/core/onchain/commitreveal" 7 | // "github.com/DOSNetwork/core/onchain/dosproxy" 8 | 9 | "github.com/ethereum/go-ethereum/core/types" 10 | ) 11 | 12 | type request struct { 13 | opCtx context.Context 14 | f func(ctx context.Context) (tx *types.Transaction, err error) 15 | reply chan *response 16 | } 17 | 18 | type response struct { 19 | idx int 20 | tx *types.Transaction 21 | err error 22 | } 23 | -------------------------------------------------------------------------------- /p2p/client_test.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "net" 7 | "sync" 8 | "testing" 9 | "time" 10 | 11 | "github.com/DOSNetwork/core/log" 12 | "github.com/DOSNetwork/core/suites" 13 | "github.com/golang/protobuf/proto" 14 | ) 15 | 16 | func Init() { 17 | logger = log.New("module", "p2p") 18 | } 19 | func listen(t *testing.T, listener net.Listener, sID string) { 20 | for { 21 | conn, err := listener.Accept() 22 | if err != nil { 23 | continue 24 | } 25 | go func(conn net.Conn, sID string) { 26 | suite := suites.MustFind("bn256") 27 | secret := suite.Scalar().Pick(suite.RandomStream()) 28 | public := suite.Point().Mul(secret, nil) 29 | client, err := newClient(suite, secret, public, []byte(sID), conn, true) 30 | if err != nil { 31 | fmt.Println("err", err) 32 | 33 | return 34 | } 35 | 36 | for msg := range client.receiver { 37 | pmsg, ok := msg.(P2PMessage) 38 | if !ok { 39 | t.Errorf("casting failed") 40 | } 41 | p, ok := pmsg.Msg.Message.(*Ping) 42 | if !ok { 43 | t.Errorf("casting failed") 44 | } 45 | 46 | reply := request{} 47 | 48 | reply.ctx, reply.cancel = context.WithTimeout(context.Background(), 5*time.Second) 49 | reply.id = client.remoteID 50 | reply.rType = 2 51 | reply.nonce = pmsg.RequestNonce 52 | errc := make(chan error) 53 | reply.errc = errc 54 | reply.msg = proto.Message(&Pong{Count: p.Count + 10}) 55 | client.send(reply) 56 | } 57 | }(conn, sID) 58 | } 59 | } 60 | 61 | func TestExchangeID(t *testing.T) { 62 | var listenerA net.Listener 63 | var err error 64 | if listenerA, err = net.Listen("tcp", ":9901"); err != nil { 65 | return 66 | } 67 | go listen(t, listenerA, "server") 68 | 69 | add := "localhost:9901" 70 | var conn net.Conn 71 | var client *client 72 | if conn, err = net.Dial("tcp", add); err != nil { 73 | t.Errorf("Can't Dial to %s ,Error %s", add, err.Error()) 74 | } 75 | suite := suites.MustFind("bn256") 76 | secret := suite.Scalar().Pick(suite.RandomStream()) 77 | public := suite.Point().Mul(secret, nil) 78 | client, err = newClient(suite, secret, public, []byte("local"), conn, false) 79 | if err != nil { 80 | t.Errorf("newClient,Error %s", err.Error()) 81 | } 82 | if string(client.localID) != "local" || string(client.remoteID) != "server" { 83 | t.Errorf("ExchangeID ,Error %s %s", string(client.localID), string(client.remoteID)) 84 | } 85 | } 86 | 87 | func TestRequest(t *testing.T) { 88 | var listenerA net.Listener 89 | var err error 90 | if listenerA, err = net.Listen("tcp", ":9902"); err != nil { 91 | return 92 | } 93 | go listen(t, listenerA, "server") 94 | 95 | add := "localhost:9902" 96 | var conn net.Conn 97 | var client *client 98 | if conn, err = net.Dial("tcp", add); err != nil { 99 | t.Errorf("Can't Dial to %s ,Error %s", add, err.Error()) 100 | } 101 | suite := suites.MustFind("bn256") 102 | secret := suite.Scalar().Pick(suite.RandomStream()) 103 | public := suite.Point().Mul(secret, nil) 104 | 105 | client, err = newClient(suite, secret, public, []byte("local"), conn, false) 106 | if err != nil { 107 | t.Errorf("newClient,Error %s", err.Error()) 108 | } 109 | var count uint64 110 | checkRoll := make(map[uint64]uint64) 111 | var wg sync.WaitGroup 112 | wg.Add(1) 113 | for count = 0; count < 1; count++ { 114 | go func(count uint64) { 115 | defer wg.Done() 116 | 117 | callReq := request{} 118 | callReq.ctx, callReq.cancel = context.WithTimeout(context.Background(), 35*time.Second) 119 | callReq.rType = 1 120 | callReq.id = client.remoteID 121 | callReq.reply = make(chan interface{}) 122 | callReq.errc = make(chan error) 123 | defer close(callReq.reply) 124 | defer close(callReq.errc) 125 | callReq.msg = proto.Message(&Ping{Count: count}) 126 | client.send(callReq) 127 | 128 | select { 129 | case r, ok := <-callReq.reply: 130 | if !ok { 131 | return 132 | } 133 | msg, ok := r.(P2PMessage) 134 | if ok { 135 | 136 | } 137 | p, ok := msg.Msg.Message.(*Pong) 138 | if !ok { 139 | t.Errorf("casting failed") 140 | } 141 | checkRoll[count] = p.Count 142 | return 143 | case e, ok := <-callReq.errc: 144 | if ok { 145 | err = e 146 | fmt.Println("reply err ", err) 147 | return 148 | } 149 | case <-callReq.ctx.Done(): 150 | err = callReq.ctx.Err() 151 | t.Errorf("TestRequest, ctx Error %s", callReq.ctx.Err()) 152 | 153 | return 154 | } 155 | }(count) 156 | } 157 | wg.Wait() 158 | for count = 0; count < 5; count++ { 159 | if checkRoll[count]-count != 10 { 160 | //t.Errorf("TestRequest ,Expected %d Actual %d", count+10, checkRoll[count]) 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /p2p/discover/membership.go: -------------------------------------------------------------------------------- 1 | package discover 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io/ioutil" 7 | "net" 8 | "time" 9 | 10 | "github.com/hashicorp/serf/serf" 11 | ) 12 | 13 | // Membership represents the p2p network 14 | type Membership interface { 15 | Join(Ip []string) (num int, err error) 16 | Leave() 17 | Listen(ctx context.Context, outch chan P2PEvent) 18 | Lookup(id []byte) (addr string) 19 | NumOfPeers() int 20 | IsAlive() bool 21 | MembersIP() (addr []net.IP) 22 | MembersID() (list [][]byte) 23 | } 24 | 25 | type P2PEvent struct { 26 | EventType string 27 | NodeID string 28 | Addr net.IP 29 | } 30 | 31 | //NewSerfNet creates a Serf implementation 32 | func NewSerfNet(Addr net.IP, id, port string) (Membership, error) { 33 | var err error 34 | serfNet := &serfNet{} 35 | conf := serf.DefaultConfig() 36 | conf.Init() 37 | conf.LogOutput = ioutil.Discard 38 | conf.MemberlistConfig.LogOutput = ioutil.Discard 39 | conf.MemberlistConfig.AdvertiseAddr = Addr.String() 40 | conf.NodeName = id + port 41 | conf.MemberlistConfig.IndirectChecks = 21 // Use 3 nodes for the indirect ping 42 | conf.MemberlistConfig.ProbeTimeout = 1 * time.Second // Reasonable RTT time for LAN 43 | conf.MemberlistConfig.ProbeInterval = 5 * time.Second // Failure check every second 44 | conf.MemberlistConfig.DisableTcpPings = false // TCP pings are safe, even with mixed versions 45 | conf.MemberlistConfig.AwarenessMaxMultiplier = 16 // Probe interval backs off to 8 seconds 46 | 47 | eventCh := make(chan serf.Event, 4) 48 | conf.EventCh = eventCh 49 | serfNet.eventch = eventCh 50 | serfNet._serf, err = serf.Create(conf) 51 | return serfNet, err 52 | } 53 | 54 | type serfNet struct { 55 | _serf *serf.Serf 56 | eventch chan serf.Event 57 | } 58 | 59 | //NumOfPeers return the length of members 60 | func (s *serfNet) Listen(ctx context.Context, outch chan P2PEvent) { 61 | defer fmt.Println("[P2P] End MemberList Listen") 62 | 63 | for event := range s.eventch { 64 | if e, ok := event.(serf.MemberEvent); ok { 65 | 66 | for _, member := range e.Members { 67 | nodeId := member.Name[:20] 68 | select { 69 | case <-ctx.Done(): 70 | case outch <- P2PEvent{EventType: event.String(), NodeID: nodeId, Addr: member.Addr}: 71 | } 72 | } 73 | } 74 | //if event.EventType() == serf.EventQuery { 75 | // query := event.(*serf.Query) 76 | //fmt.Println("[Gossip ] query", query) 77 | //} 78 | } 79 | } 80 | 81 | func (s *serfNet) IsAlive() bool { 82 | state := s._serf.State() 83 | if state != serf.SerfAlive { 84 | fmt.Println("[Gossip ] status ", state) 85 | return false 86 | } 87 | return true 88 | } 89 | 90 | //NumOfPeers return the length of members 91 | func (s *serfNet) NumOfPeers() int { 92 | members := s._serf.Members() 93 | n := 0 94 | for i := 0; i < len(members); i++ { 95 | if members[i].Status == serf.StatusAlive && members[i].Name != s._serf.LocalMember().Name { 96 | n++ 97 | } 98 | 99 | } 100 | return n 101 | } 102 | 103 | // Join joins an existing Serf cluster. Returns the number of nodes 104 | // successfully contacted. 105 | func (s *serfNet) Join(bootstrapIp []string) (num int, err error) { 106 | num, err = s._serf.Join(bootstrapIp, true) 107 | return 108 | } 109 | 110 | // Join leaves an Serf cluster. 111 | func (s *serfNet) Leave() { 112 | s._serf.Leave() 113 | close(s.eventch) 114 | return 115 | } 116 | 117 | // Lookup return the IP address of the given ID 118 | func (s *serfNet) Lookup(id []byte) (addr string) { 119 | members := s._serf.Members() 120 | var nodeId, port string 121 | for i := 0; i < len(members); i++ { 122 | if len(members[i].Name) < 20 { 123 | continue 124 | } 125 | nodeId = members[i].Name[:20] 126 | if len(members[i].Name) == 20 { 127 | port = "9501" 128 | continue 129 | } else { 130 | port = members[i].Name[20:] 131 | } 132 | if nodeId == string(id) && members[i].Status == serf.StatusAlive { 133 | fmt.Println("ID ", []byte(nodeId), " ", members[i].Addr.String()+":"+port) 134 | return members[i].Addr.String() + ":" + port 135 | } 136 | } 137 | return 138 | } 139 | 140 | // MembersIP return the all IP address of an existing cluster 141 | func (s *serfNet) MembersIP() (addr []net.IP) { 142 | 143 | members := s._serf.Members() 144 | for i := 0; i < len(members); i++ { 145 | //fmt.Println("localMember ", []byte(s.serf.LocalMember().Name), "members[i].Name ", []byte(members[i].Name), " status ", members[i].Status, " addr ", members[i].Addr) 146 | if members[i].Name != s._serf.LocalMember().Name { 147 | addr = append(addr, members[i].Addr) 148 | } 149 | } 150 | return 151 | } 152 | 153 | // MembersID return the all ID of an existing cluster 154 | func (s *serfNet) MembersID() (list [][]byte) { 155 | members := s._serf.Members() 156 | for i := 0; i < len(members); i++ { 157 | var port string 158 | if len(members[i].Name) < 20 { 159 | continue 160 | } 161 | if len(members[i].Name) == 20 { 162 | port = "9501" 163 | continue 164 | } else { 165 | port = members[i].Name[20:] 166 | } 167 | fmt.Println(members[i].Addr.String() + ":" + port) 168 | fmt.Println("len ", len(members[i].Name)) 169 | if members[i].Status == serf.StatusAlive { 170 | list = append(list, []byte(members[i].Name)) 171 | } 172 | 173 | } 174 | return 175 | } 176 | -------------------------------------------------------------------------------- /p2p/discover/simulator.go: -------------------------------------------------------------------------------- 1 | package discover 2 | 3 | import ( 4 | "context" 5 | "net" 6 | ) 7 | 8 | //NewSerfNet creates a Serf implementation 9 | func NewSimulator() (Membership, error) { 10 | return &simulator{}, nil 11 | } 12 | 13 | type simulator struct { 14 | } 15 | 16 | func (s *simulator) IsAlive() bool { 17 | return true 18 | } 19 | 20 | //NumOfPeers return the length of members 21 | func (s *simulator) NumOfPeers() int { 22 | return 1 23 | } 24 | 25 | // Join joins an existing Serf cluster. Returns the number of nodes 26 | // successfully contacted. 27 | func (s *simulator) Join(bootstrapIp []string) (num int, err error) { 28 | return 29 | } 30 | 31 | // Join leaves an Serf cluster. 32 | func (s *simulator) Leave() { 33 | return 34 | } 35 | func (s *simulator) Listen(ctx context.Context, outch chan P2PEvent) { 36 | } 37 | 38 | // Lookup return the IP address of the given ID 39 | func (s *simulator) Lookup(id []byte) (addr string) { 40 | if string(id) == "b" { 41 | return "127.0.0.1:9502" 42 | } else if string(id) == "a" { 43 | return "127.0.0.1:9501" 44 | } 45 | 46 | return 47 | } 48 | 49 | // MembersIP return the all IP address of an existing cluster 50 | func (s *simulator) MembersIP() (addr []net.IP) { 51 | 52 | return 53 | } 54 | 55 | // MembersID return the all ID of an existing cluster 56 | func (s *simulator) MembersID() (list [][]byte) { 57 | 58 | return 59 | } 60 | -------------------------------------------------------------------------------- /p2p/error.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | errors "golang.org/x/xerrors" 8 | ) 9 | 10 | var ( 11 | ErrNoRemoteID = errors.New("remoteID is nil") 12 | ErrMsgOverSize = errors.New("header size check failed") 13 | ErrCasting = errors.New("casting failed") 14 | ErrDuplicateID = errors.New("remote ID is the same with local ID") 15 | ErrCanNotFindClient = errors.New("can't find client") 16 | ErrIdleTimeout = errors.New("idle timeout") 17 | ) 18 | 19 | type P2PError struct { 20 | frame errors.Frame 21 | dest string 22 | t time.Time // the time when the error happened 23 | err error // the wrapped error 24 | } 25 | 26 | func (e *P2PError) Format(f fmt.State, c rune) { 27 | errors.FormatError(e, f, c) 28 | } 29 | 30 | func (e *P2PError) FormatError(p errors.Printer) error { 31 | p.Printf("IP : %s", e.dest) 32 | e.frame.Format(p) 33 | return e.err 34 | } 35 | 36 | func (e *P2PError) Error() string { 37 | return fmt.Sprint(e) 38 | } 39 | 40 | func (e *P2PError) Unwrap() error { 41 | return e.err 42 | } 43 | -------------------------------------------------------------------------------- /p2p/internal/package.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package internal; 3 | 4 | import "protobuf/ptypes/any/any.proto"; 5 | 6 | message Package { 7 | google.protobuf.Any anything = 1; 8 | bytes pubkey = 2; 9 | bytes signature = 3; 10 | 11 | // Sender's address and public key. 12 | ID sender = 4; 13 | 14 | // request_nonce is the request/response ID. Null if ID associated to a message is not a request/response. 15 | uint64 request_nonce = 5; 16 | 17 | // message_nonce is the sequence ID. 18 | uint64 message_nonce = 6; 19 | 20 | // reply_flag indicates this is a reply to a request 21 | bool reply_flag = 7; 22 | } 23 | 24 | message Hi { 25 | // public_key of the peer (we no longer use the public key as the peer ID, but use it to verify messages) 26 | bytes public_key = 1; 27 | // address is the network address of the peer 28 | string address = 2; 29 | // id is the computed hash of the public key 30 | bytes id = 3; 31 | } 32 | 33 | message ID { 34 | // public_key of the peer (we no longer use the public key as the peer ID, but use it to verify messages) 35 | bytes public_key = 1; 36 | // address is the network address of the peer 37 | string address = 2; 38 | // id is the computed hash of the public key 39 | bytes id = 3; 40 | } 41 | 42 | message Ping { 43 | } 44 | 45 | message Pong { 46 | } 47 | 48 | message LookupNodeRequest { 49 | ID target = 1; 50 | } 51 | 52 | message LookupNodeResponse { 53 | repeated ID peers = 1; 54 | } 55 | 56 | message Bytes { 57 | bytes data = 1; 58 | } -------------------------------------------------------------------------------- /p2p/nat/nat.go: -------------------------------------------------------------------------------- 1 | // Package nat implements NAT handling facilities 2 | package nat 3 | 4 | import ( 5 | "context" 6 | "errors" 7 | "log" 8 | "net" 9 | "time" 10 | ) 11 | 12 | const ( 13 | mapTimeout = 20 * time.Minute 14 | mapUpdateInterval = 15 * time.Minute 15 | ) 16 | 17 | var errNoExternalAddress = errors.New("no external address") 18 | var errNoInternalAddress = errors.New("no internalMsg address") 19 | var errNoNATFound = errors.New("no NAT found") 20 | 21 | // NAT represents an interface for upnp and natpmp 22 | type NAT interface { 23 | // Type returns the kind of NAT port mapping service that is used 24 | getType() string 25 | 26 | // GetDeviceAddress returns the internalMsg address of the gateway device. 27 | getDeviceAddress() (addr net.IP, err error) 28 | 29 | // GetExternalAddress returns the external address of the gateway device. 30 | GetExternalAddress() (addr net.IP, err error) 31 | 32 | // GetInternalAddress returns the address of the local host. 33 | getInternalAddress() (addr net.IP, err error) 34 | 35 | // AddPortMapping maps a port on the local host to an external port. 36 | addPortMapping(protocol string, externalPort, internalPort int, description string, timeout time.Duration) error 37 | 38 | // DeletePortMapping removes a port mapping. 39 | deletePortMapping(protocol string, internalPort int) (err error) 40 | } 41 | 42 | // SetMapping adds a port mapping on m and keeps it alive until c is closed. 43 | func SetMapping(ctx context.Context, nat NAT, protocol string, extport, intport int, name string) error { 44 | if err := nat.addPortMapping(protocol, extport, intport, name, mapTimeout); err != nil { 45 | return err 46 | } 47 | 48 | go func() { 49 | 50 | refresh := time.NewTimer(mapUpdateInterval) 51 | defer func() { 52 | refresh.Stop() 53 | nat.deletePortMapping(protocol, intport) 54 | }() 55 | 56 | for { 57 | select { 58 | case <-ctx.Done(): 59 | return 60 | case <-refresh.C: 61 | if err := nat.addPortMapping(protocol, extport, intport, name, mapTimeout); err != nil { 62 | log.Fatal(err) 63 | } 64 | refresh.Reset(mapUpdateInterval) 65 | } 66 | } 67 | 68 | }() 69 | 70 | return nil 71 | } 72 | 73 | // DiscoverGateway attempts to find a gateway device. 74 | func DiscoverGateway() (NAT, error) { 75 | select { 76 | case nat := <-discoverUPNPIG1(): 77 | return nat, nil 78 | case nat := <-discoverUPNPIG2(): 79 | return nat, nil 80 | case nat := <-discoverNATPMP(): 81 | return nat, nil 82 | case <-time.After(10 * time.Second): 83 | return nil, errNoNATFound 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /p2p/nat/natpmp.go: -------------------------------------------------------------------------------- 1 | package nat 2 | 3 | import ( 4 | "net" 5 | "time" 6 | 7 | "github.com/jackpal/gateway" 8 | "github.com/jackpal/go-nat-pmp" 9 | ) 10 | 11 | var ( 12 | _ NAT = (*natpmpNAT)(nil) 13 | ) 14 | 15 | func discoverNATPMP() <-chan NAT { 16 | res := make(chan NAT, 1) 17 | 18 | ip, err := gateway.DiscoverGateway() 19 | if err == nil { 20 | go discoverNATPMPWithAddr(res, ip) 21 | } 22 | 23 | return res 24 | } 25 | 26 | func discoverNATPMPWithAddr(c chan NAT, ip net.IP) { 27 | client := natpmp.NewClient(ip) 28 | _, err := client.GetExternalAddress() 29 | if err != nil { 30 | return 31 | } 32 | 33 | c <- &natpmpNAT{client, ip, make(map[int]int)} 34 | } 35 | 36 | type natpmpNAT struct { 37 | c *natpmp.Client 38 | gateway net.IP 39 | ports map[int]int 40 | } 41 | 42 | func (n *natpmpNAT) getDeviceAddress() (addr net.IP, err error) { 43 | return n.gateway, nil 44 | } 45 | 46 | func (n *natpmpNAT) getInternalAddress() (addr net.IP, err error) { 47 | ifaces, err := net.Interfaces() 48 | if err != nil { 49 | return nil, err 50 | } 51 | 52 | for _, iface := range ifaces { 53 | addrs, err := iface.Addrs() 54 | if err != nil { 55 | return nil, err 56 | } 57 | 58 | for _, addr := range addrs { 59 | switch x := addr.(type) { 60 | case *net.IPNet: 61 | if x.Contains(n.gateway) { 62 | return x.IP, nil 63 | } 64 | } 65 | } 66 | } 67 | 68 | return nil, errNoInternalAddress 69 | } 70 | 71 | func (n *natpmpNAT) GetExternalAddress() (addr net.IP, err error) { 72 | res, err := n.c.GetExternalAddress() 73 | if err != nil { 74 | return nil, err 75 | } 76 | 77 | d := res.ExternalIPAddress 78 | return net.IPv4(d[0], d[1], d[2], d[3]), nil 79 | } 80 | 81 | func (n *natpmpNAT) addPortMapping(protocol string, externalPort, internalPort int, description string, timeout time.Duration) error { 82 | n.deletePortMapping(protocol, internalPort) 83 | 84 | var ( 85 | err error 86 | ) 87 | 88 | timeoutInSeconds := int(timeout / time.Second) 89 | 90 | if externalPort := n.ports[internalPort]; externalPort > 0 { 91 | _, err = n.c.AddPortMapping(protocol, internalPort, externalPort, timeoutInSeconds) 92 | if err == nil { 93 | n.ports[internalPort] = externalPort 94 | return nil 95 | } 96 | } 97 | 98 | for i := 0; i < 3; i++ { 99 | _, err = n.c.AddPortMapping(protocol, internalPort, externalPort, timeoutInSeconds) 100 | if err == nil { 101 | n.ports[internalPort] = externalPort 102 | return nil 103 | } 104 | } 105 | 106 | return err 107 | } 108 | 109 | func (n *natpmpNAT) deletePortMapping(protocol string, internalPort int) (err error) { 110 | delete(n.ports, internalPort) 111 | return nil 112 | } 113 | 114 | func (n *natpmpNAT) getType() string { 115 | return "NAT-PMP" 116 | } 117 | -------------------------------------------------------------------------------- /p2p/p2p_interface.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "net" 8 | "strconv" 9 | 10 | "github.com/DOSNetwork/core/log" 11 | "github.com/DOSNetwork/core/p2p/discover" 12 | "github.com/DOSNetwork/core/p2p/nat" 13 | "github.com/DOSNetwork/core/suites" 14 | 15 | "github.com/ethereum/go-ethereum/p2p/netutil" 16 | "github.com/golang/protobuf/proto" 17 | "github.com/golang/protobuf/ptypes" 18 | ) 19 | 20 | const ( 21 | //NoDiscover means that p2p don't use any discover protocol 22 | NoDiscover = iota // 0 23 | //GossipDiscover means that p2p use gossip as a discover protocol 24 | GossipDiscover 25 | swimPort = 7946 26 | ) 27 | 28 | // P2PMessage is a struct that includes message,sender and nonce 29 | type P2PMessage struct { 30 | Msg ptypes.DynamicAny 31 | Sender []byte 32 | RequestNonce uint64 33 | } 34 | 35 | // P2PInterface represents a p2p network 36 | type P2PInterface interface { 37 | GetIP() net.IP 38 | GetID() []byte 39 | SetPort(port string) 40 | GetPort() string 41 | Listen() error 42 | Join(bootstrapIp []string) (num int, err error) 43 | DisConnectTo(id []byte) error 44 | Leave() 45 | Request(ctx context.Context, id []byte, m proto.Message) (msg P2PMessage, err error) 46 | Reply(ctx context.Context, id []byte, nonce uint64, m proto.Message) (err error) 47 | SubscribeEvent() (subID int, outch chan discover.P2PEvent, err error) 48 | UnSubscribeEvent(int) 49 | SubscribeMsg(chanBuffer int, messages ...interface{}) (outch chan P2PMessage, err error) 50 | UnSubscribeMsg(messages ...interface{}) 51 | NumOfMembers() int 52 | MembersID() [][]byte 53 | RandomPeerIP() []string 54 | //ConnectToAll(ctx context.Context, groupIds [][]byte, sessionID string) (out chan bool, errc chan error) 55 | numOfClient() (int, int) 56 | } 57 | 58 | // CreateP2PNetwork creates a P2PInterface implementation , gets a public IP and generates a secret key 59 | func CreateP2PNetwork(id []byte, ip, port string, netType int) (P2PInterface, error) { 60 | suite := suites.MustFind("bn256") 61 | 62 | p := &server{ 63 | suite: suite, 64 | addIncomingC: make(chan *client), 65 | removeIncomingC: make(chan []byte), 66 | replying: make(chan p2pRequest), 67 | calling: make(chan p2pRequest), 68 | removeCallingC: make(chan []byte), 69 | peersFeed: make(chan P2PMessage, 5), 70 | peersEvent: make(chan discover.P2PEvent, 5), 71 | subscribeMsg: make(chan *subscription), 72 | unscribeMsg: make(chan string), 73 | subscribeEvent: make(chan *subscription), 74 | unscribeEvent: make(chan int), 75 | port: port, 76 | logger: log.New("module", "p2p"), 77 | } 78 | p.ctx, p.cancel = context.WithCancel(context.Background()) 79 | p.secKey = suite.Scalar().Pick(suite.RandomStream()) 80 | p.pubKey = suite.Point().Mul(p.secKey, nil) 81 | p.id = id 82 | 83 | // If user specify a public ip from the env variable,use it as external IP. 84 | if addr := net.ParseIP(ip); addr != nil { 85 | p.addr = addr 86 | } else { 87 | ip, err := getIP() 88 | if err != nil { 89 | return nil, err 90 | } 91 | if netutil.IsLAN(ip) { 92 | natdev, err := nat.DiscoverGateway() 93 | if err != nil { 94 | return nil, err 95 | } 96 | 97 | externalIp, err := natdev.GetExternalAddress() 98 | if err != nil { 99 | fmt.Println(err) 100 | return nil, err 101 | } 102 | if netutil.IsLAN(externalIp) { 103 | return nil, errors.New("NAT IP is a local IP Address") 104 | } 105 | 106 | portInt, err := strconv.Atoi(port) 107 | if err != nil { 108 | return nil, err 109 | } 110 | 111 | if err := nat.SetMapping(p.ctx, natdev, "tcp", portInt, portInt, "DosClient"); err != nil { 112 | fmt.Println(err) 113 | return nil, err 114 | } 115 | 116 | if netType == GossipDiscover { 117 | if err := nat.SetMapping(p.ctx, natdev, "tcp", swimPort, swimPort, "DosGossip"); err != nil { 118 | fmt.Println(err) 119 | return nil, err 120 | } 121 | } 122 | // If NAT port mapping success, then return NAT external IP. 123 | p.addr = externalIp 124 | } else { 125 | // If the local IP is a public IP, then return it as a external IP. 126 | p.addr = ip 127 | } 128 | } 129 | 130 | switch netType { 131 | case GossipDiscover: 132 | network, err := discover.NewSerfNet(p.addr, string(p.id), p.port) 133 | if err != nil { 134 | p.cancel() 135 | return nil, err 136 | } 137 | p.members = network 138 | default: 139 | network, _ := discover.NewSimulator() 140 | p.members = network 141 | } 142 | return p, nil 143 | } 144 | -------------------------------------------------------------------------------- /p2p/package.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package p2p; 3 | 4 | import "protobuf/ptypes/any/any.proto"; 5 | 6 | message Package { 7 | google.protobuf.Any anything = 1; 8 | bytes signature = 2; 9 | // Sender's address and public key. 10 | bytes sender = 3; 11 | // request_nonce is the request/response ID. Null if ID associated to a message is not a request/response. 12 | uint64 request_nonce = 4; 13 | // reply_flag indicates this is a reply to a request 14 | bool reply_flag = 5; 15 | } 16 | 17 | message ID { 18 | // public_key of the peer (we no longer use the public key as the peer ID, but use it to verify messages) 19 | bytes public_key = 1; 20 | // id is the computed hash of the public key 21 | bytes id = 2; 22 | } 23 | message Ping { 24 | uint64 count = 1; 25 | } 26 | message Pong { 27 | uint64 count = 1; 28 | } 29 | -------------------------------------------------------------------------------- /p2p/request.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "sync" 7 | 8 | "github.com/golang/protobuf/proto" 9 | ) 10 | 11 | type p2pRequest struct { 12 | rType int 13 | ctx context.Context 14 | cancel context.CancelFunc 15 | addr string 16 | id []byte 17 | //client signs and packs msg into Package 18 | msg proto.Message 19 | p *Package 20 | // 21 | nonce uint64 22 | reply chan p2pResult 23 | once sync.Once 24 | } 25 | type p2pResult struct { 26 | res interface{} 27 | err error 28 | } 29 | 30 | func NewP2pRequest(ctx context.Context, rType int, id []byte, addr string, msg proto.Message, nonce uint64) (req *p2pRequest) { 31 | rctx, cancel := context.WithCancel(ctx) 32 | req = &p2pRequest{ctx: rctx, cancel: cancel, id: id, msg: msg, rType: rType, nonce: nonce, reply: make(chan p2pResult)} 33 | return 34 | } 35 | func (r *p2pRequest) sendReq(ch chan p2pRequest) (err error) { 36 | select { 37 | case ch <- *r: 38 | case <-r.ctx.Done(): 39 | err = r.ctx.Err() 40 | fmt.Println("p2pRequest sendReq err", err) 41 | } 42 | return 43 | } 44 | 45 | func (r *p2pRequest) waitForResult() (res interface{}, err error) { 46 | select { 47 | case <-r.ctx.Done(): 48 | err = r.ctx.Err() 49 | case result := <-r.reply: 50 | res = result.res 51 | err = result.err 52 | } 53 | r.cancel() 54 | return 55 | } 56 | 57 | func (r *p2pRequest) replyResult(res interface{}, err error) { 58 | r.once.Do(func() { 59 | defer close(r.reply) 60 | select { 61 | case <-r.ctx.Done(): 62 | case r.reply <- p2pResult{res: res, err: err}: 63 | } 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /p2p/server_test.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "os" 5 | "strconv" 6 | "sync" 7 | "testing" 8 | "time" 9 | 10 | "github.com/DOSNetwork/core/log" 11 | "github.com/golang/protobuf/proto" 12 | ) 13 | 14 | func receiveEvent(pListener P2PInterface, t *testing.T) { 15 | events, _ := pListener.SubscribeEvent(1, Ping{}) 16 | for msg := range events { 17 | r, ok := msg.Msg.Message.(*Ping) 18 | if !ok { 19 | t.Errorf("Not ok") 20 | } 21 | pListener.Reply(msg.Sender, msg.RequestNonce, proto.Message(&Pong{Count: r.Count + 10})) 22 | } 23 | } 24 | 25 | func TestServer(t *testing.T) { 26 | listener := []byte("9") 27 | os.Setenv("PUBLICIP", "127.0.0.1") 28 | log.Init(listener[:]) 29 | 30 | pListener, _ := CreateP2PNetwork(listener, "9905", NoDiscover) 31 | pListener.Listen() 32 | 33 | go receiveEvent(pListener, t) 34 | 35 | var wgForPeer sync.WaitGroup 36 | wgForPeer.Add(1) 37 | for c := 9904; c < 9905; c++ { 38 | go func(c int) { 39 | defer wgForPeer.Done() 40 | id := []byte(strconv.Itoa(c)) 41 | p, _ := CreateP2PNetwork(id, strconv.Itoa(c), NoDiscover) 42 | p.Listen() 43 | 44 | var count uint64 45 | var wgForMsg sync.WaitGroup 46 | var connected []byte 47 | var err error 48 | wgForMsg.Add(10) 49 | for count = 0; count < 10; count++ { 50 | go func(count uint64) { 51 | defer wgForMsg.Done() 52 | p.SetPort("9905") 53 | connected, err = p.ConnectTo("127.0.0.1", nil) 54 | if err != nil { 55 | t.Errorf("ConnectTo ,Error %s", err) 56 | } 57 | cmd := &Ping{Count: count} 58 | pb := proto.Message(cmd) 59 | reply, _ := p.Request(connected, pb) 60 | pong, _ := reply.Msg.Message.(*Pong) 61 | if pong.Count-count != 10 { 62 | t.Errorf("TestRequest ,Expected %d Actual %d", count+10, pong.Count) 63 | } 64 | p.DisConnectTo(connected) 65 | }(count) 66 | } 67 | wgForMsg.Wait() 68 | }(c) 69 | } 70 | wgForPeer.Wait() 71 | retryLimit := 5 72 | for { 73 | prNum, pcNum := pListener.numOfClient() 74 | if prNum == 0 && pcNum == 0 { 75 | break 76 | } 77 | retryLimit-- 78 | if retryLimit == 0 { 79 | t.Errorf("TestServer ,Expected %d Actual %d", 0, prNum) 80 | } 81 | time.Sleep(1 * time.Second) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /p2p/util.go: -------------------------------------------------------------------------------- 1 | package p2p 2 | 3 | import ( 4 | "errors" 5 | "net" 6 | ) 7 | 8 | func getIP() (net.IP, error) { 9 | ifaces, err := net.Interfaces() 10 | if err != nil { 11 | return nil, err 12 | } 13 | for _, iface := range ifaces { 14 | if iface.Flags&net.FlagUp == 0 { 15 | continue // interface down 16 | } 17 | if iface.Flags&net.FlagLoopback != 0 { 18 | continue // loopback interface 19 | } 20 | addrs, err := iface.Addrs() 21 | if err != nil { 22 | return nil, err 23 | } 24 | for _, addr := range addrs { 25 | var ip net.IP 26 | switch v := addr.(type) { 27 | case *net.IPNet: 28 | ip = v.IP 29 | case *net.IPAddr: 30 | ip = v.IP 31 | } 32 | if ip == nil || ip.IsLoopback() { 33 | continue 34 | } 35 | ip = ip.To4() 36 | if ip == nil { 37 | continue // not an ipv4 address 38 | } 39 | return ip, nil 40 | } 41 | } 42 | return nil, errors.New("Can't find IP address") 43 | } 44 | -------------------------------------------------------------------------------- /share/dkg/pedersen/dkg.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package dkg; 3 | import "github.com/DOSNetwork/core/share/vss/pedersen/vss.proto"; 4 | 5 | message PublicKey { 6 | string sessionId = 1; 7 | uint32 index = 2; 8 | vss.PublicKey publickey =3; 9 | } 10 | 11 | message Deal { 12 | string sessionId = 1; 13 | uint32 index = 2; 14 | vss.EncryptedDeal deal = 3; 15 | } 16 | 17 | message Response { 18 | string sessionId = 1; 19 | uint32 index = 2; 20 | vss.Response response = 3; 21 | } 22 | 23 | message Responses{ 24 | string sessionId = 1; 25 | repeated Response response = 2; 26 | } 27 | -------------------------------------------------------------------------------- /share/dkg/pedersen/errorrs.go: -------------------------------------------------------------------------------- 1 | package dkg 2 | 3 | import ( 4 | "fmt" 5 | 6 | errors "golang.org/x/xerrors" 7 | ) 8 | 9 | var ( 10 | ErrDupPubKey = errors.New("duplicated share public key") 11 | ErrDupPubKeyIndex = errors.New("duplicated public key index") 12 | ErrCanNotFindID = errors.New("can't find id in group IDs") 13 | ErrCasting = errors.New("casting failed") 14 | ErrRespNotApproval = errors.New("response not approval") 15 | ErrNotCertified = errors.New("not certified") 16 | ErrCanNotLoadSec = errors.New("can't load sec") 17 | ErrCanNotLoadGroup = errors.New("can't load group") 18 | ErrResponseNoApproval = errors.New("response no approval") 19 | ErrDKGNotCertified = errors.New("dkg is not certified") 20 | ) 21 | 22 | type DKGError struct { 23 | frame errors.Frame 24 | err error // the wrapped error 25 | } 26 | 27 | func (e *DKGError) Format(f fmt.State, c rune) { 28 | errors.FormatError(e, f, c) 29 | } 30 | 31 | func (e *DKGError) FormatError(p errors.Printer) error { 32 | e.frame.Format(p) 33 | return e.err 34 | } 35 | 36 | func (e *DKGError) Error() string { 37 | return fmt.Sprint(e) 38 | } 39 | 40 | func (e *DKGError) Unwrap() error { 41 | return e.err 42 | } 43 | -------------------------------------------------------------------------------- /share/dkg/pedersen/pdkg_test.go: -------------------------------------------------------------------------------- 1 | package dkg 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "fmt" 7 | "os" 8 | "strconv" 9 | "sync" 10 | "testing" 11 | 12 | "github.com/DOSNetwork/core/log" 13 | 14 | //"github.com/DOSNetwork/core/log" 15 | "github.com/DOSNetwork/core/p2p" 16 | bls "github.com/DOSNetwork/core/sign/bls" 17 | tbls "github.com/DOSNetwork/core/sign/tbls" 18 | "github.com/DOSNetwork/core/suites" 19 | ) 20 | 21 | func buildConn(s, d p2p.P2PInterface, port string, t *testing.T) { 22 | //Println(string(s.GetID()), " connect ", string(d.GetID()), " port ", port) 23 | oldPort := s.GetPort() 24 | s.SetPort(port) 25 | connected, err := s.ConnectTo("0.0.0.0", nil) 26 | if err != nil { 27 | t.Errorf("TestRequest ,err %s", err) 28 | } 29 | if !bytes.Equal(connected, d.GetID()) { 30 | t.Errorf("TestRequest ,Expected [% x] Actual [% x]", d.GetID(), connected) 31 | } 32 | s.SetPort(oldPort) 33 | } 34 | func setUpP2P(id []byte, port string, t *testing.T) (p p2p.P2PInterface) { 35 | var err error 36 | p, err = p2p.CreateP2PNetwork(id, port, 0) 37 | if err != nil { 38 | t.Errorf("CreateP2PNetwork err %s", err) 39 | } 40 | p.Listen() 41 | return 42 | } 43 | 44 | func buildPdkg(size int, t *testing.T) ([]PDKGInterface, [][]byte) { 45 | var p []p2p.P2PInterface 46 | var d []PDKGInterface 47 | var groupIds [][]byte 48 | portStart := 9905 49 | id := "Participant" 50 | suite := suites.MustFind("bn256") 51 | for i := 0; i < size; i++ { 52 | nodePort := strconv.Itoa(portStart + i) 53 | nodeId := []byte(id + strconv.Itoa(i)) 54 | groupIds = append(groupIds, nodeId) 55 | pi := setUpP2P(nodeId, nodePort, t) 56 | p = append(p, pi) 57 | d = append(d, NewPDKG(pi, suite)) 58 | } 59 | for i := 0; i < size; i++ { 60 | for j := 0; j < size; j++ { 61 | if i != j { 62 | buildConn(p[i], p[j], p[j].GetPort(), t) 63 | } 64 | } 65 | } 66 | return d, groupIds 67 | } 68 | 69 | func TestPDKG(t *testing.T) { 70 | 71 | os.Setenv("APPSESSION", "test") 72 | os.Setenv("LOGIP", "163.172.36.173:9500") 73 | os.Setenv("PUBLICIP", "0.0.0.0") 74 | id := []byte("Participant0") 75 | log.Init(id[:]) 76 | 77 | pdkgs, groupIds := buildPdkg(11, t) 78 | 79 | var wg sync.WaitGroup 80 | wg.Add(11) 81 | for i := 0; i < 11; i++ { 82 | go func(groupID string, pdkgs []PDKGInterface, groupIds [][]byte) { 83 | defer wg.Done() 84 | ctx := context.Background() 85 | var wgPdkg sync.WaitGroup 86 | wgPdkg.Add(len(pdkgs)) 87 | for _, pdkg := range pdkgs { 88 | go func(pdkg PDKGInterface) { 89 | defer wgPdkg.Done() 90 | out, errc, err := pdkg.Grouping(ctx, groupID, groupIds) 91 | if err != nil { 92 | t.Errorf("Grouping err %s", err) 93 | } 94 | select { 95 | case <-out: 96 | case err := <-errc: 97 | t.Errorf("Grouping err %s", err) 98 | } 99 | }(pdkg) 100 | } 101 | wgPdkg.Wait() 102 | 103 | content := []byte{'a', 'b'} 104 | var sigShares [][]byte 105 | var sig []byte 106 | var err error 107 | for _, pdkg := range pdkgs { 108 | sig, err = tbls.Sign(suite, pdkg.GetShareSecurity(groupID), content) 109 | if err != nil { 110 | t.Errorf("Sign err %s", err) 111 | } 112 | sigShares = append(sigShares, sig) 113 | } 114 | 115 | sig, err = tbls.Recover(suite, pdkgs[0].GetGroupPublicPoly(groupID), content, sigShares, len(pdkgs)/2+1, len(pdkgs)) 116 | if err != nil { 117 | t.Errorf("Recover err %s", err) 118 | } 119 | if err = bls.Verify(suite, pdkgs[1].GetGroupPublicPoly(groupID).Commit(), content, sig); err != nil { 120 | t.Errorf("Verify err %s", err) 121 | } 122 | 123 | fmt.Println("test done") 124 | }(strconv.Itoa(i), pdkgs, groupIds) 125 | } 126 | wg.Wait() 127 | } 128 | -------------------------------------------------------------------------------- /share/dkg/pedersen/request.go: -------------------------------------------------------------------------------- 1 | package dkg 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | type request struct { 8 | ctx context.Context 9 | reqType int 10 | sessionID string 11 | numOfResps int 12 | reply chan []interface{} 13 | } 14 | -------------------------------------------------------------------------------- /share/vss/pedersen/dh.go: -------------------------------------------------------------------------------- 1 | package vss 2 | 3 | import ( 4 | "crypto/aes" 5 | "crypto/cipher" 6 | "hash" 7 | 8 | "github.com/DOSNetwork/core/suites" 9 | 10 | "github.com/dedis/kyber" 11 | "golang.org/x/crypto/hkdf" 12 | ) 13 | 14 | // dhExchange computes the shared key from a private key and a public key 15 | func dhExchange(suite suites.Suite, ownPrivate kyber.Scalar, remotePublic kyber.Point) kyber.Point { 16 | sk := suite.Point() 17 | sk.Mul(ownPrivate, remotePublic) 18 | return sk 19 | } 20 | 21 | var sharedKeyLength = 32 22 | 23 | // newAEAD returns the AEAD cipher to be use to encrypt a share 24 | func newAEAD(fn func() hash.Hash, preSharedKey kyber.Point, context []byte) (cipher.AEAD, error) { 25 | preBuff, _ := preSharedKey.MarshalBinary() 26 | reader := hkdf.New(fn, preBuff, nil, context) 27 | 28 | sharedKey := make([]byte, sharedKeyLength) 29 | if _, err := reader.Read(sharedKey); err != nil { 30 | return nil, err 31 | } 32 | block, err := aes.NewCipher(sharedKey) 33 | if err != nil { 34 | return nil, err 35 | } 36 | gcm, err := cipher.NewGCM(block) 37 | if err != nil { 38 | return nil, err 39 | } 40 | return gcm, nil 41 | } 42 | 43 | // context returns the context slice to be used when encrypting a share 44 | func context(suite suites.Suite, dealer kyber.Point, verifiers []kyber.Point) []byte { 45 | h := suite.Hash() 46 | _, _ = h.Write([]byte("vss-dealer")) 47 | _, _ = dealer.MarshalTo(h) 48 | _, _ = h.Write([]byte("vss-verifiers")) 49 | for _, v := range verifiers { 50 | _, _ = v.MarshalTo(h) 51 | } 52 | return h.Sum(nil) 53 | } 54 | -------------------------------------------------------------------------------- /share/vss/pedersen/vss.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package vss; 3 | 4 | 5 | message EncryptedDeal { 6 | bytes dHKey = 1; 7 | bytes signature = 2; 8 | bytes nonce = 3; 9 | bytes cipher = 4; 10 | } 11 | 12 | message EncryptedDeals { 13 | repeated EncryptedDeal deals = 1; 14 | } 15 | 16 | message Response { 17 | bytes sessionID = 1; 18 | uint32 index = 2; 19 | bool status = 3; 20 | bytes signature = 4; 21 | } 22 | 23 | message Responses { 24 | repeated Response responses = 1; 25 | } 26 | 27 | message PublicKey { 28 | bytes binary = 1; 29 | bytes senderId = 2; 30 | } 31 | 32 | message PublicKeys { 33 | repeated PublicKey keys = 1; 34 | } 35 | 36 | message Signature { 37 | uint32 index = 1; 38 | bytes requestId = 2; 39 | bytes nonce = 3; 40 | bytes content = 4; 41 | bytes signature = 5; 42 | } 43 | -------------------------------------------------------------------------------- /sign/bls/bls.go: -------------------------------------------------------------------------------- 1 | // Package bls implements the Boneh-Lynn-Shacham (BLS) signature scheme which 2 | // was introduced in the paper "Short Signatures from the Weil Pairing". BLS 3 | // requires pairing-based cryptography. 4 | package bls 5 | 6 | import ( 7 | "crypto/cipher" 8 | "errors" 9 | 10 | "github.com/DOSNetwork/core/suites" 11 | "github.com/dedis/kyber" 12 | "golang.org/x/crypto/sha3" 13 | ) 14 | 15 | // NewKeyPair creates a new BLS signing key pair. The private key x is a scalar 16 | // and the public key X is a point on curve G2. 17 | func NewKeyPair(suite suites.Suite, random cipher.Stream) (kyber.Scalar, kyber.Point) { 18 | x := suite.G2().Scalar().Pick(random) 19 | X := suite.G2().Point().Mul(x, nil) 20 | return x, X 21 | } 22 | 23 | // Sign creates a BLS signature S = x * H(m) on a message m using the private 24 | // key x. The signature S is a point on curve G1. 25 | func Sign(suite suites.Suite, x kyber.Scalar, msg []byte) ([]byte, error) { 26 | HM := hashToPoint(suite, msg) 27 | xHM := HM.Mul(x, HM) 28 | s, err := xHM.MarshalBinary() 29 | if err != nil { 30 | return nil, err 31 | } 32 | return s, nil 33 | } 34 | 35 | // Verify checks the given BLS signature S on the message m using the public 36 | // key X by verifying that the equality e(H(m), X) == e(H(m), x*B2) == 37 | // e(x*H(m), B2) == e(S, B2) holds where e is the pairing operation and B2 is 38 | // the base point from curve G2. 39 | func Verify(suite suites.Suite, X kyber.Point, msg, sig []byte) error { 40 | HM := hashToPoint(suite, msg) 41 | s := suite.G1().Point() 42 | if err := s.UnmarshalBinary(sig); err != nil { 43 | return err 44 | } 45 | s.Neg(s) 46 | if !suite.PairingCheck([]kyber.Point{s, HM}, []kyber.Point{suite.G2().Point().Base(), X}) { 47 | return errors.New("bls: invalid signature") 48 | } 49 | return nil 50 | } 51 | 52 | // hashToPoint hashes a message to a point on curve G1. XXX: This should be replaced 53 | // eventually by a proper hash-to-point mapping like Elligator. 54 | func hashToPoint(suite suites.Suite, msg []byte) kyber.Point { 55 | hash := sha3.NewLegacyKeccak256() 56 | var buf []byte 57 | hash.Write(msg) 58 | buf = hash.Sum(buf) 59 | x := suite.G1().Scalar().SetBytes(buf) 60 | point := suite.G1().Point().Mul(x, nil) 61 | return point 62 | } 63 | -------------------------------------------------------------------------------- /sign/bls/bls_test.go: -------------------------------------------------------------------------------- 1 | package bls 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/DOSNetwork/core/suites" 7 | "github.com/dedis/kyber/util/random" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | var suite = suites.MustFind("bn256") 12 | 13 | func TestBLS(t *testing.T) { 14 | msg := []byte("Hello Boneh-Lynn-Shacham") 15 | private, public := NewKeyPair(suite, random.New()) 16 | sig, err := Sign(suite, private, msg) 17 | require.Nil(t, err) 18 | err = Verify(suite, public, msg, sig) 19 | require.Nil(t, err) 20 | } 21 | 22 | func TestBLSFailSig(t *testing.T) { 23 | msg := []byte("Hello Boneh-Lynn-Shacham") 24 | private, public := NewKeyPair(suite, random.New()) 25 | sig, err := Sign(suite, private, msg) 26 | require.Nil(t, err) 27 | sig[0] ^= 0x01 28 | if Verify(suite, public, msg, sig) == nil { 29 | t.Fatal("bls: verification succeeded unexpectedly") 30 | } 31 | } 32 | 33 | func TestBLSFailKey(t *testing.T) { 34 | msg := []byte("Hello Boneh-Lynn-Shacham") 35 | private, _ := NewKeyPair(suite, random.New()) 36 | sig, err := Sign(suite, private, msg) 37 | require.Nil(t, err) 38 | _, public := NewKeyPair(suite, random.New()) 39 | if Verify(suite, public, msg, sig) == nil { 40 | t.Fatal("bls: verification succeeded unexpectedly") 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sign/schnorr/schnorr.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package schnorr implements the vanilla Schnorr signature scheme. 3 | See https://en.wikipedia.org/wiki/Schnorr_signature. 4 | 5 | The only difference regarding the vanilla reference is the computation of 6 | the response. This implementation adds the random component with the 7 | challenge times private key while the Wikipedia article subtracts them. 8 | 9 | The resulting signature is compatible with EdDSA verification algorithm 10 | when using the edwards25519 group, and by extension the CoSi verification algorithm. 11 | */ 12 | package schnorr 13 | 14 | import ( 15 | "bytes" 16 | "crypto/sha512" 17 | "errors" 18 | "fmt" 19 | 20 | "github.com/dedis/kyber" 21 | ) 22 | 23 | // Suite represents the set of functionalities needed by the package schnorr. 24 | type Suite interface { 25 | kyber.Group 26 | kyber.Random 27 | } 28 | 29 | // Sign creates a Sign signature from a msg and a private key. This 30 | // signature can be verified with VerifySchnorr. It's also a valid EdDSA 31 | // signature when using the edwards25519 Group. 32 | func Sign(s Suite, private kyber.Scalar, msg []byte) ([]byte, error) { 33 | var g kyber.Group = s 34 | // create random secret k and public point commitment R 35 | k := g.Scalar().Pick(s.RandomStream()) 36 | R := g.Point().Mul(k, nil) 37 | 38 | // create hash(public || R || message) 39 | public := g.Point().Mul(private, nil) 40 | h, err := hash(g, public, R, msg) 41 | if err != nil { 42 | return nil, err 43 | } 44 | 45 | // compute response s = k + x*h 46 | xh := g.Scalar().Mul(private, h) 47 | S := g.Scalar().Add(k, xh) 48 | 49 | // return R || s 50 | var b bytes.Buffer 51 | if _, err := R.MarshalTo(&b); err != nil { 52 | return nil, err 53 | } 54 | if _, err := S.MarshalTo(&b); err != nil { 55 | return nil, err 56 | } 57 | return b.Bytes(), nil 58 | } 59 | 60 | // Verify verifies a given Schnorr signature. It returns nil iff the 61 | // given signature is valid. 62 | func Verify(g kyber.Group, public kyber.Point, msg, sig []byte) error { 63 | R := g.Point() 64 | s := g.Scalar() 65 | pointSize := R.MarshalSize() 66 | scalarSize := s.MarshalSize() 67 | sigSize := scalarSize + pointSize 68 | if len(sig) != sigSize { 69 | return fmt.Errorf("schnorr: signature of invalid length %d instead of %d", len(sig), sigSize) 70 | } 71 | if err := R.UnmarshalBinary(sig[:pointSize]); err != nil { 72 | return err 73 | } 74 | if err := s.UnmarshalBinary(sig[pointSize:]); err != nil { 75 | return err 76 | } 77 | // recompute hash(public || R || msg) 78 | h, err := hash(g, public, R, msg) 79 | if err != nil { 80 | return err 81 | } 82 | 83 | // compute S = g^s 84 | S := g.Point().Mul(s, nil) 85 | // compute RAh = R + A^h 86 | Ah := g.Point().Mul(h, public) 87 | RAs := g.Point().Add(R, Ah) 88 | 89 | if !S.Equal(RAs) { 90 | return errors.New("schnorr: invalid signature") 91 | } 92 | 93 | return nil 94 | } 95 | 96 | func hash(g kyber.Group, public, r kyber.Point, msg []byte) (kyber.Scalar, error) { 97 | h := sha512.New() 98 | if _, err := r.MarshalTo(h); err != nil { 99 | return nil, err 100 | } 101 | if _, err := public.MarshalTo(h); err != nil { 102 | return nil, err 103 | } 104 | if _, err := h.Write(msg); err != nil { 105 | return nil, err 106 | } 107 | return g.Scalar().SetBytes(h.Sum(nil)), nil 108 | } 109 | -------------------------------------------------------------------------------- /sign/schnorr/schnorr_test.go: -------------------------------------------------------------------------------- 1 | package schnorr 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/dedis/kyber/group/edwards25519" 7 | "github.com/dedis/kyber/sign/eddsa" 8 | "github.com/dedis/kyber/util/key" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestSchnorrSignature(t *testing.T) { 13 | msg := []byte("Hello Schnorr") 14 | suite := edwards25519.NewBlakeSHA256Ed25519() 15 | kp := key.NewKeyPair(suite) 16 | 17 | s, err := Sign(suite, kp.Private, msg) 18 | if err != nil { 19 | t.Fatalf("Couldn't sign msg: %s: %v", msg, err) 20 | } 21 | err = Verify(suite, kp.Public, msg, s) 22 | if err != nil { 23 | t.Fatalf("Couldn't verify signature: \n%+v\nfor msg:'%s'. Error:\n%v", s, msg, err) 24 | } 25 | 26 | // wrong size 27 | larger := append(s, []byte{0x01, 0x02}...) 28 | assert.Error(t, Verify(suite, kp.Public, msg, larger)) 29 | 30 | // wrong challenge 31 | wrongEncoding := []byte{243, 45, 180, 140, 73, 23, 41, 212, 250, 87, 157, 243, 32 | 242, 19, 114, 161, 145, 47, 76, 26, 174, 150, 22, 177, 78, 79, 122, 30, 74, 33 | 42, 156, 203} 34 | wrChall := make([]byte, len(s)) 35 | copy(wrChall[:32], wrongEncoding) 36 | copy(wrChall[32:], s[32:]) 37 | assert.Error(t, Verify(suite, kp.Public, msg, wrChall)) 38 | 39 | // wrong response 40 | wrResp := make([]byte, len(s)) 41 | copy(wrResp[32:], wrongEncoding) 42 | copy(wrResp[:32], s[:32]) 43 | assert.Error(t, Verify(suite, kp.Public, msg, wrResp)) 44 | 45 | // wrong public key 46 | wrKp := key.NewKeyPair(suite) 47 | assert.Error(t, Verify(suite, wrKp.Public, msg, s)) 48 | } 49 | 50 | func TestEdDSACompatibility(t *testing.T) { 51 | msg := []byte("Hello Schnorr") 52 | suite := edwards25519.NewBlakeSHA256Ed25519() 53 | kp := key.NewKeyPair(suite) 54 | 55 | s, err := Sign(suite, kp.Private, msg) 56 | if err != nil { 57 | t.Fatalf("Couldn't sign msg: %s: %v", msg, err) 58 | } 59 | err = eddsa.Verify(kp.Public, msg, s) 60 | if err != nil { 61 | t.Fatalf("Couldn't verify signature: \n%+v\nfor msg:'%s'. Error:\n%v", s, msg, err) 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /sign/tbls/tbls.go: -------------------------------------------------------------------------------- 1 | // Package tbls implements the (t,n)-threshold Boneh-Lynn-Shacham signature 2 | // scheme. During setup a group of n participants runs a distributed key 3 | // generation algorithm (see kyber/share/dkg) to compute a joint public signing 4 | // key X and one secret key share xi for each of the n signers. To compute a 5 | // signature S on a message m, at least t ouf of n signers have to provide 6 | // partial (BLS) signatures Si on m using their individual key shares xi which 7 | // can then be used to recover the full (regular) BLS signature S via Lagrange 8 | // interpolation. The signature S can be verified with the initially 9 | // established group key X. Signatures are points on curve G1 and public keys 10 | // are points on curve G2. 11 | package tbls 12 | 13 | import ( 14 | "bytes" 15 | "encoding/binary" 16 | 17 | "github.com/DOSNetwork/core/share" 18 | "github.com/DOSNetwork/core/sign/bls" 19 | "github.com/DOSNetwork/core/suites" 20 | ) 21 | 22 | // SigShare encodes a threshold BLS signature share Si = i || v where the 2-byte 23 | // big-endian value i corresponds to the share's index and v represents the 24 | // share's value. The signature share Si is a point on curve G1. 25 | type SigShare []byte 26 | 27 | // Index returns the index i of the TBLS share Si. 28 | func (s SigShare) Index() (int, error) { 29 | var index uint16 30 | buf := bytes.NewReader(s) 31 | err := binary.Read(buf, binary.BigEndian, &index) 32 | if err != nil { 33 | return -1, err 34 | } 35 | return int(index), nil 36 | } 37 | 38 | // Value returns the value v of the TBLS share Si. 39 | func (s *SigShare) Value() []byte { 40 | return []byte(*s)[2:] 41 | } 42 | 43 | // Sign creates a threshold BLS signature Si = xi * H(m) on the given message m 44 | // using the provided secret key share xi. 45 | func Sign(suite suites.Suite, private *share.PriShare, msg []byte) ([]byte, error) { 46 | buf := new(bytes.Buffer) 47 | if err := binary.Write(buf, binary.BigEndian, uint16(private.I)); err != nil { 48 | return nil, err 49 | } 50 | s, err := bls.Sign(suite, private.V, msg) 51 | if err != nil { 52 | return nil, err 53 | } 54 | if err := binary.Write(buf, binary.BigEndian, s); err != nil { 55 | return nil, err 56 | } 57 | return buf.Bytes(), nil 58 | } 59 | 60 | // Verify checks the given threshold BLS signature Si on the message m using 61 | // the public key share Xi that is associated to the secret key share xi. This 62 | // public key share Xi can be computed by evaluating the public sharing 63 | // polynonmial at the share's index i. 64 | func Verify(suite suites.Suite, public *share.PubPoly, msg, sig []byte) error { 65 | s := SigShare(sig) 66 | i, err := s.Index() 67 | if err != nil { 68 | return err 69 | } 70 | return bls.Verify(suite, public.Eval(i).V, msg, s.Value()) 71 | } 72 | 73 | func sliceUniqMap(s [][]byte) [][]byte { 74 | seen := make(map[string]struct{}, len(s)) 75 | j := 0 76 | for _, v := range s { 77 | if _, ok := seen[string(v)]; ok { 78 | continue 79 | } 80 | seen[string(v)] = struct{}{} 81 | s[j] = v 82 | j++ 83 | } 84 | return s[:j] 85 | } 86 | 87 | // Recover reconstructs the full BLS signature S = x * H(m) from a threshold t 88 | // of signature shares Si using Lagrange interpolation. The full signature S 89 | // can be verified through the regular BLS verification routine using the 90 | // shared public key X. The shared public key can be computed by evaluating the 91 | // public sharing polynomial at index 0. 92 | func Recover(suite suites.Suite, public *share.PubPoly, msg []byte, sigs [][]byte, t, n int) ([]byte, error) { 93 | pubShares := make([]*share.PubShare, 0) 94 | sigs = sliceUniqMap(sigs) 95 | for _, sig := range sigs { 96 | s := SigShare(sig) 97 | i, err := s.Index() 98 | 99 | if err != nil { 100 | return nil, err 101 | } 102 | if err = bls.Verify(suite, public.Eval(i).V, msg, s.Value()); err != nil { 103 | continue 104 | } 105 | point := suite.G1().Point() 106 | if err := point.UnmarshalBinary(s.Value()); err != nil { 107 | return nil, err 108 | } 109 | pubShares = append(pubShares, &share.PubShare{I: i, V: point}) 110 | if len(pubShares) >= t { 111 | break 112 | } 113 | } 114 | commit, err := share.RecoverCommit(suite.G1(), pubShares, t, n) 115 | if err != nil { 116 | return nil, err 117 | } 118 | sig, err := commit.MarshalBinary() 119 | if err != nil { 120 | return nil, err 121 | } 122 | return sig, nil 123 | } 124 | -------------------------------------------------------------------------------- /sign/tbls/tbls_test.go: -------------------------------------------------------------------------------- 1 | package tbls 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/DOSNetwork/core/share" 8 | "github.com/DOSNetwork/core/sign/bls" 9 | "github.com/DOSNetwork/core/suites" 10 | 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | var suite = suites.MustFind("bn256") 15 | 16 | func TestTBLS(test *testing.T) { 17 | var err error 18 | msg := []byte("Hello threshold Boneh-Lynn-Shacham") 19 | n := 10 20 | t := n/2 + 1 21 | secret := suite.Scalar().Pick(suite.RandomStream()) 22 | priPoly := share.NewPriPoly(suite, t, secret, suite.RandomStream()) 23 | pubPoly := priPoly.Commit(suite.Point().Base()) 24 | sigShares := make([][]byte, 0) 25 | for i, x := range priPoly.Shares(n) { 26 | sig, err := Sign(suite, x, msg) 27 | require.Nil(test, err) 28 | sigShares = append(sigShares, sig) 29 | //To simulate wrong signatures case 30 | if i <= 3 { 31 | sig[0] ^= 0x01 32 | } 33 | //To simulate duplicate signatures case 34 | sigShares = append(sigShares, sig) 35 | sigShares = append(sigShares, sig) 36 | } 37 | fmt.Println(len(sigShares)) 38 | sig, err := Recover(suite, pubPoly, msg, sigShares, t, n) 39 | require.Nil(test, err) 40 | err = bls.Verify(suite, pubPoly.Commit(), msg, sig) 41 | require.Nil(test, err) 42 | } 43 | -------------------------------------------------------------------------------- /suites/all.go: -------------------------------------------------------------------------------- 1 | package suites 2 | 3 | import ( 4 | "github.com/DOSNetwork/core/group/bn256" 5 | "github.com/DOSNetwork/core/group/edwards25519" 6 | ) 7 | 8 | func init() { 9 | register(edwards25519.NewBlakeSHA256Ed25519()) 10 | register(bn256.NewSuite()) 11 | } 12 | -------------------------------------------------------------------------------- /suites/suites.go: -------------------------------------------------------------------------------- 1 | // Package suites allows callers to look up Kyber suites by name. 2 | // 3 | // Currently, only the "ed25519" suite is available by default. To 4 | // have access to "curve25519" and the NIST suites (i.e. "P256"), 5 | // one needs to call the "go" tool with the tag "vartime", such as: 6 | // 7 | // go build -tags vartime 8 | // go install -tags vartime 9 | // go test -tags vartime 10 | package suites 11 | 12 | import ( 13 | "errors" 14 | "strings" 15 | 16 | "github.com/dedis/kyber" 17 | ) 18 | 19 | // Suite is the sum of all suites mix-ins in Kyber. 20 | type Suite interface { 21 | G1() kyber.Group 22 | G2() kyber.Group 23 | GT() kyber.Group 24 | Pair(p1, p2 kyber.Point) kyber.Point 25 | PairingCheck(a []kyber.Point, b []kyber.Point) bool 26 | kyber.Group 27 | kyber.Encoding 28 | kyber.HashFactory 29 | kyber.XOFFactory 30 | kyber.Random 31 | } 32 | 33 | var suites = map[string]Suite{} 34 | 35 | // register is called by suites to make themselves known to Kyber. 36 | // 37 | func register(s Suite) { 38 | suites[strings.ToLower(s.String())] = s 39 | } 40 | 41 | // ErrUnknownSuite indicates that the suite was not one of the 42 | // registered suites. 43 | var ErrUnknownSuite = errors.New("unknown suite") 44 | 45 | // Find looks up a suite by name. 46 | func Find(name string) (Suite, error) { 47 | if s, ok := suites[strings.ToLower(name)]; ok { 48 | return s, nil 49 | } 50 | return nil, ErrUnknownSuite 51 | } 52 | 53 | // MustFind looks up a suite by name and panics if it is not found. 54 | func MustFind(name string) Suite { 55 | s, err := Find(name) 56 | if err != nil { 57 | panic("Suite " + name + " not found.") 58 | } 59 | return s 60 | } 61 | -------------------------------------------------------------------------------- /upgrade.md: -------------------------------------------------------------------------------- 1 | #### How to upgrade your node to the latest version 2 | * Login into the server hosting client software. 3 | * Download the upgrade script by: 4 | - `curl https://raw.githubusercontent.com/DOSNetwork/core/master/upgrade.sh --output upgrade.sh` 5 | - Or `wget https://raw.githubusercontent.com/DOSNetwork/core/master/upgrade.sh -O upgrade.sh` 6 | * Make the script runnable: `chmod a+x upgrade.sh` 7 | * Export password of the keystore file the node operates with: `export PASSWORD="your-own-password"` 8 | * Start the updrade process and run the node with: `./upgrade.sh` 9 | * Congratulations, now you should've been done! Check node status by log files `tail -n 100 -f $(ls -l ~/vault/doslog.txt | cut -d '>' -f2)` or simply by querying rest endpoint `curl localhost:8080`. 10 | * Ask for help or additional questions in our node runner channel [here](https://t.me/dos_node). 11 | -------------------------------------------------------------------------------- /upgrade.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export DOSTAG="v1.0.4-m" 4 | 5 | sudo rm -f vault/dosclient.pid 6 | sudo docker stop $(docker ps -a -q) 7 | sudo docker rm -f $(docker ps -a -q) 8 | sudo rm -f vault/doslog.txt 9 | sudo rm -f vault/doslog.txt.* 10 | 11 | docker pull dosnetwork/dosnode:'$DOSTAG' 12 | docker run -it -d -p 7946:7946 -p 8080:8080 -p 9501:9501 --mount type=bind,source=/home/"$USER"/,target=/config --mount type=bind,source=/home/"$USER"/vault,target=/vault --hostname dos --name dosclient --env CONFIGPATH=config --env PASSPHRASE="$PASSWORD" --env APPSESSION="$DOSTAG-mainnet" --env LOG_LEVEL=debug dosnetwork/dosnode:"$DOSTAG" /dosclient start 13 | -------------------------------------------------------------------------------- /utils/utils.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "os/exec" 7 | "sync" 8 | ) 9 | 10 | func AllowConnection(ip, port string) error { 11 | args := []string{"allow", "from", fmt.Sprintf("%s", ip), "to", "any", "port", port} 12 | out, err := exec.Command("ufw", args...).Output() 13 | if err != nil { 14 | fmt.Println(fmt.Sprint(err)) 15 | return err 16 | } 17 | fmt.Printf("ufw: %s\n", out) 18 | return nil 19 | } 20 | 21 | func ResetConnList() error { 22 | out, err := exec.Command("ufw", "--force", "reset").Output() 23 | if err != nil { 24 | fmt.Println(fmt.Sprint(err)) 25 | return err 26 | } 27 | fmt.Printf("ufw: %s\n", out) 28 | out, err = exec.Command("ufw", "allow", "22/tcp").Output() 29 | if err != nil { 30 | fmt.Println(fmt.Sprint(err)) 31 | return err 32 | } 33 | fmt.Printf("ufw: %s\n", out) 34 | out, err = exec.Command("ufw", "allow", "7946").Output() 35 | if err != nil { 36 | fmt.Println(fmt.Sprint(err)) 37 | return err 38 | } 39 | fmt.Printf("ufw: %s\n", out) 40 | out, err = exec.Command("ufw", "--force", "enable").Output() 41 | if err != nil { 42 | fmt.Println(fmt.Sprint(err)) 43 | return err 44 | } 45 | fmt.Printf("ufw: %s\n", out) 46 | return nil 47 | } 48 | 49 | func ReportError(ctx context.Context, errc chan error, err error) { 50 | select { 51 | case <-ctx.Done(): 52 | case errc <- err: 53 | } 54 | return 55 | } 56 | 57 | func ReportResult(ctx context.Context, outc chan interface{}, result interface{}) { 58 | select { 59 | case <-ctx.Done(): 60 | case outc <- result: 61 | } 62 | return 63 | } 64 | 65 | func MergeErrors(ctx context.Context, cs ...<-chan error) chan error { 66 | var wg sync.WaitGroup 67 | // We must ensure that the output channel has the capacity to 68 | // hold as many errors 69 | // as there are error channels. 70 | // This will ensure that it never blocks, even 71 | // if WaitForPipeline returns early. 72 | out := make(chan error, len(cs)) 73 | // Start an output goroutine for each input channel in cs. output 74 | // copies values from c to out until c is closed, then calls 75 | // wg.Done. 76 | output := func(c <-chan error) { 77 | for n := range c { 78 | select { 79 | case <-ctx.Done(): 80 | return 81 | case out <- n: 82 | } 83 | } 84 | wg.Done() 85 | } 86 | wg.Add(len(cs)) 87 | for _, c := range cs { 88 | go output(c) 89 | } 90 | // Start a goroutine to close out once all the output goroutines 91 | // are done. This must start after the wg.Add call. 92 | go func() { 93 | wg.Wait() 94 | close(out) 95 | }() 96 | return out 97 | } 98 | --------------------------------------------------------------------------------