├── logo.png ├── src ├── services │ ├── compile.sh │ ├── services.proto │ └── services.pb.go ├── .dockerignore ├── localtest │ ├── reset.sh │ └── simple.sh ├── Makefile ├── networking │ ├── test │ │ ├── clock.go │ │ ├── bulletinboard.go │ │ └── nodes.go │ ├── clock │ │ └── clock.go │ ├── bulletinboard │ │ └── bulletinboard.go │ └── nodes │ │ └── nodes.go ├── cmd │ ├── clock.go │ ├── bb.go │ └── node.go ├── utils │ ├── conv │ │ └── conv.go │ ├── commitment │ │ ├── dl_test.go │ │ ├── dl.go │ │ ├── kate_test.go │ │ └── kate.go │ ├── polypoint │ │ └── polypoint.go │ ├── vector │ │ └── vec.go │ ├── encryption │ │ ├── encryption_test.go │ │ └── encryption.go │ ├── ecparam │ │ └── pbc.go │ ├── interpolation │ │ ├── interpolation_test.go │ │ └── interpolation.go │ ├── polycommit │ │ ├── p521 │ │ │ ├── compress.go │ │ │ ├── comm_test.go │ │ │ └── comm.go │ │ └── pbc │ │ │ ├── comm_test.go │ │ │ └── comm.go │ └── polyring │ │ ├── polyring_test.go │ │ └── polyring.go ├── go.mod └── go.sum ├── dockerfiles ├── build_docker_builder.sh ├── Dockerfile-builder └── Dockerfile-runtime ├── Dockerfile ├── .gitignore └── README.md /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CHURPTeam/CHURP/HEAD/logo.png -------------------------------------------------------------------------------- /src/services/compile.sh: -------------------------------------------------------------------------------- 1 | protoc --go_out=plugins=grpc:. *.proto 2 | -------------------------------------------------------------------------------- /src/.dockerignore: -------------------------------------------------------------------------------- 1 | metadata 2 | awstest 3 | protocols/schultz/bin/*.exe 4 | -------------------------------------------------------------------------------- /src/localtest/reset.sh: -------------------------------------------------------------------------------- 1 | COUNTER=11100 2 | for i in `seq 11000 $COUNTER`; 3 | do 4 | lsof -t -i tcp:$i | xargs kill 5 | done 6 | -------------------------------------------------------------------------------- /dockerfiles/build_docker_builder.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker build -f ./Dockerfile-builder -t churp/builder . 4 | docker push churp/builder 5 | 6 | docker build -f ./Dockerfile-runtime -t churp/runtime . 7 | docker push churp/runtime -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | all: node clock bb 2 | 3 | clean: 4 | @rm -rf *.exe 5 | 6 | node: 7 | go build -o node.exe ./cmd/node.go 8 | 9 | clock: 10 | go build -o clock.exe ./cmd/clock.go 11 | 12 | bb: 13 | go build -o bb.exe ./cmd/bb.go 14 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # docker build -t churp/churp . 2 | 3 | FROM churp/builder as builder 4 | 5 | COPY src /src 6 | WORKDIR /src 7 | 8 | RUN make 9 | 10 | FROM churp/runtime 11 | 12 | WORKDIR /root/ 13 | 14 | RUN apk add --no-cache bash 15 | COPY localtest/* /root/ 16 | COPY --from=builder /src/*.exe /root/ -------------------------------------------------------------------------------- /src/networking/test/clock.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "../clock" 5 | "flag" 6 | ) 7 | 8 | func main() { 9 | metadataPath := flag.String("path", "/mpss/metadata", "Enter the metadata path") 10 | flag.Parse() 11 | 12 | clock, _ := clock.New(*metadataPath) 13 | clock.Connect() 14 | clock.ClientStartEpoch() 15 | } 16 | -------------------------------------------------------------------------------- /src/cmd/clock.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "flag" 4 | import "github.com/bl4ck5un/ChuRP/src/networking/clock" 5 | 6 | func main() { 7 | metadataPath := flag.String("path", "/mpss/metadata", "Enter the metadata path") 8 | flag.Parse() 9 | 10 | clock, _ := clock.New(*metadataPath) 11 | clock.Connect() 12 | clock.ClientStartEpoch() 13 | } 14 | -------------------------------------------------------------------------------- /src/utils/conv/conv.go: -------------------------------------------------------------------------------- 1 | package conv 2 | 3 | import "math/big" 4 | import "github.com/ncw/gmp" 5 | 6 | func BigInt2GmpInt(a *big.Int) *gmp.Int { 7 | b := gmp.NewInt(0) 8 | b.SetBytes(a.Bytes()) 9 | 10 | return b 11 | } 12 | 13 | func GmpInt2BigInt(a *gmp.Int) *big.Int { 14 | b := new(big.Int) 15 | b.SetBytes(a.Bytes()) 16 | 17 | return b 18 | } 19 | -------------------------------------------------------------------------------- /src/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/bl4ck5un/ChuRP/src 2 | 3 | require ( 4 | github.com/BurntSushi/toml v0.3.1 5 | github.com/Nik-U/pbc v0.0.0-20181205041846-3e516ca0c5d6 6 | github.com/golang/protobuf v1.3.0 7 | github.com/montanaflynn/stats v0.5.0 8 | github.com/ncw/gmp v1.0.3 9 | github.com/sirupsen/logrus v1.3.0 10 | github.com/stretchr/testify v1.2.2 11 | google.golang.org/grpc v1.19.0 12 | ) 13 | -------------------------------------------------------------------------------- /src/utils/commitment/dl_test.go: -------------------------------------------------------------------------------- 1 | package commitment 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ncw/gmp" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestDLCommit(t *testing.T) { 11 | c := DLCommit{} 12 | c.SetupFix() 13 | 14 | // res = g^x 15 | res := c.pairing.NewG1() 16 | x := gmp.NewInt(100) 17 | c.Commit(res, x) 18 | 19 | assert.True(t, c.Verify(res, x), "dl_commit") 20 | } 21 | -------------------------------------------------------------------------------- /dockerfiles/Dockerfile-builder: -------------------------------------------------------------------------------- 1 | FROM golang:1.12.0-alpine3.9 2 | 3 | # install Pairing Based Cryptography library (PBC) 4 | RUN apk add --no-cache gmp-dev build-base flex bison git bash 5 | 6 | RUN wget https://crypto.stanford.edu/pbc/files/pbc-0.5.14.tar.gz && \ 7 | tar xvzf pbc-0.5.14.tar.gz && \ 8 | cd pbc-0.5.14 && \ 9 | ./configure && \ 10 | make && \ 11 | make install && \ 12 | make clean && \ 13 | cd .. && \ 14 | rm pbc-0.5.14.tar.gz && \ 15 | rm -rf pbc-0.5.14 -------------------------------------------------------------------------------- /src/networking/test/bulletinboard.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "../bulletinboard" 5 | "flag" 6 | ) 7 | 8 | func main() { 9 | cnt := flag.Int("c", 2, "Enter number of nodes") 10 | degree := flag.Int("d", 1, "Enter the polynomial degree") 11 | metadataPath := flag.String("path", "/mpss/metadata", "Enter the metadata path") 12 | aws := flag.Bool("aws", false, "if test on real aws") 13 | flag.Parse() 14 | 15 | bb, _ := bulletinboard.New(*degree, *cnt, *metadataPath) 16 | bb.Serve(*aws) 17 | } 18 | -------------------------------------------------------------------------------- /src/cmd/bb.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "flag" 4 | 5 | import "github.com/bl4ck5un/ChuRP/src/networking/bulletinboard" 6 | 7 | func main() { 8 | cnt := flag.Int("c", 2, "Enter number of nodes") 9 | degree := flag.Int("d", 1, "Enter the polynomial degree") 10 | metadataPath := flag.String("path", "/mpss/metadata", "Enter the metadata path") 11 | aws := flag.Bool("aws", false, "if test on real aws") 12 | flag.Parse() 13 | 14 | bb, _ := bulletinboard.New(*degree, *cnt, *metadataPath) 15 | bb.Serve(*aws) 16 | } 17 | -------------------------------------------------------------------------------- /src/networking/test/nodes.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "../nodes" 5 | "flag" 6 | ) 7 | 8 | func main() { 9 | label := flag.Int("l", 1, "Enter node label") 10 | counter := flag.Int("c", 1, "Enter number of nodes") 11 | degree := flag.Int("d", 1, "Enter the polynomial degree") 12 | metadataPath := flag.String("path", "/mpss/metadata", "Enter the metadata path") 13 | aws := flag.Bool("aws", false, "if test on real aws") 14 | flag.Parse() 15 | 16 | n, _ := nodes.New(*degree, *label, *counter, *metadataPath) 17 | n.Serve(*aws) 18 | } 19 | -------------------------------------------------------------------------------- /src/utils/polypoint/polypoint.go: -------------------------------------------------------------------------------- 1 | package polypoint 2 | 3 | import ( 4 | "github.com/Nik-U/pbc" 5 | "github.com/ncw/gmp" 6 | ) 7 | 8 | type PolyPoint struct { 9 | X int32 10 | Y *gmp.Int 11 | PolyWit *pbc.Element 12 | } 13 | 14 | func NewZeroPoint() *PolyPoint { 15 | return &PolyPoint{ 16 | X: 0, 17 | Y: gmp.NewInt(0), 18 | PolyWit: nil, 19 | } 20 | } 21 | 22 | func NewPoint(x int32, y *gmp.Int, w *pbc.Element) *PolyPoint { 23 | return &PolyPoint{ 24 | X: x, 25 | Y: y, 26 | PolyWit: w, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/cmd/node.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "flag" 4 | import "github.com/bl4ck5un/ChuRP/src/networking/nodes" 5 | 6 | func main() { 7 | label := flag.Int("l", 1, "Enter node label") 8 | counter := flag.Int("c", 1, "Enter number of nodes") 9 | degree := flag.Int("d", 1, "Enter the polynomial degree") 10 | metadataPath := flag.String("path", "/mpss/metadata", "Enter the metadata path") 11 | aws := flag.Bool("aws", false, "if test on real aws") 12 | flag.Parse() 13 | 14 | n, _ := nodes.New(*degree, *label, *counter, *metadataPath) 15 | n.Serve(*aws) 16 | } 17 | -------------------------------------------------------------------------------- /src/utils/vector/vec.go: -------------------------------------------------------------------------------- 1 | package vector 2 | 3 | import "github.com/ncw/gmp" 4 | 5 | type Vector struct { 6 | v []*gmp.Int 7 | } 8 | 9 | func New(len int) Vector { 10 | if len < 0 { 11 | panic("len < 0") 12 | } 13 | 14 | v := Vector{ 15 | make([]*gmp.Int, len), 16 | } 17 | 18 | for i := range v.v { 19 | v.v[i] = gmp.NewInt(0) 20 | } 21 | 22 | return v 23 | } 24 | 25 | func FromInt64(elems ...int64) Vector { 26 | v := New(len(elems)) 27 | 28 | for i, elem := range elems { 29 | v.v[i].SetInt64(int64(elem)) 30 | } 31 | 32 | return v 33 | } 34 | 35 | func (vec Vector) GetPtr() []*gmp.Int { 36 | return vec.v 37 | } 38 | -------------------------------------------------------------------------------- /dockerfiles/Dockerfile-runtime: -------------------------------------------------------------------------------- 1 | FROM alpine:3.9 2 | 3 | # install Pairing Based Cryptography library (PBC) 4 | # we MUST use a compound command (i.e., multiple commands chained with &&) 5 | # because we can only remove packages in the same layer. 6 | # See: https://github.com/gliderlabs/docker-alpine/issues/45 7 | RUN apk add --no-cache gmp-dev build-base flex bison && \ 8 | wget https://crypto.stanford.edu/pbc/files/pbc-0.5.14.tar.gz && \ 9 | tar xvzf pbc-0.5.14.tar.gz && \ 10 | cd pbc-0.5.14 && \ 11 | ./configure && \ 12 | make && \ 13 | make install && \ 14 | make clean && \ 15 | cd .. && \ 16 | rm pbc-0.5.14.tar.gz && \ 17 | rm -rf pbc-0.5.14 && \ 18 | apk del build-base flex bison -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lagrange_interpolate/lr_itpl 2 | golang_package 3 | src/protobuf/protobuf-cpp-3.6.1.tar.gz 4 | src/protobuf/protobuf 5 | aws/kms-key.pem 6 | src/protocol/test.sh 7 | src/metadata 8 | aws/metadata 9 | src/localtest/metadata 10 | ./src/localtest/metadata/ip_list 11 | src/awstest/metadata 12 | /home/wanglun/ChuRP/visualize/raw_data/* 13 | /home/wanglun/ChuRP/visualize/figures/* 14 | /home/wanglun/ChuRP/visualize/data/* 15 | 16 | # Binaries for programs and plugins 17 | *.exe 18 | *.exe~ 19 | *.dll 20 | *.so 21 | *.dylib 22 | 23 | # Test binary, build with `go test -c` 24 | *.test 25 | 26 | # Output of the go coverage tool, specifically when used with LiteIDE 27 | *.out 28 | 29 | # IDE stuff 30 | .idea 31 | 32 | # macOS quirks 33 | .DS_Store 34 | 35 | # log files 36 | *.log 37 | 38 | *.pdf 39 | *.png 40 | -------------------------------------------------------------------------------- /src/utils/encryption/encryption_test.go: -------------------------------------------------------------------------------- 1 | package encryption 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ncw/gmp" 7 | "github.com/stretchr/testify/assert" 8 | "math/rand" 9 | ) 10 | 11 | func TestEncryption(t *testing.T) { 12 | 13 | pk := new(PublicKey) 14 | sk := new(PrivateKey) 15 | rnd := rand.New(rand.NewSource(99)) 16 | q := gmp.NewInt(7) 17 | g := gmp.NewInt(2) 18 | 19 | KeyGen(pk, sk, q, g, rnd) 20 | m := gmp.NewInt(0) 21 | m.Rand(rnd, pk.q) 22 | 23 | ei := new(EncryptedInt) 24 | proof := new(Proof) 25 | Encrypt(ei, proof, pk, m, rnd) 26 | 27 | di := gmp.NewInt(0) 28 | Decrypt(di, pk, sk, ei) 29 | 30 | assert.Equal(t, m, di, "The decrypted message should be the same as the original message.") 31 | 32 | assert.True(t, Verify(proof, m, ei, pk), "Verify correct proof should give out true") 33 | } 34 | -------------------------------------------------------------------------------- /src/localtest/simple.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | COUNTER=$1 4 | DEGREE=$2 5 | 6 | # initialize the ip file 7 | if [ ! -d "metadata" ]; then 8 | mkdir metadata 9 | fi 10 | cd metadata 11 | rm ip_list 12 | export IP_PATH=$(pwd) 13 | if [ -d "ip_list" ]; then 14 | rm ip_list 15 | fi 16 | for i in `seq 0 $COUNTER` 17 | do 18 | port=$(($i+11000)) 19 | echo 127.0.0.1:$port >> ip_list 20 | done 21 | cd .. 22 | 23 | # start a thread representing bulletinboard 24 | go run ../networking/test/bulletinboard.go -d $DEGREE -c $COUNTER -path $IP_PATH & 25 | 26 | # start threads representing nodes 27 | for i in `seq 1 $COUNTER`; 28 | do 29 | go run ../networking/test/nodes.go -l $i -c $COUNTER -d $DEGREE -path $IP_PATH & 30 | done 31 | 32 | # wait some time for all the nodes to finish initializing 33 | sleep 6 34 | 35 | # send the clock message to bulletinboard to start an epoch 36 | go run ../networking/test/clock.go -path $IP_PATH 37 | 38 | # wait some time for the protocol to finish running 39 | # LASTPORT=$(($COUNTER + 11000)) 40 | # for i in `seq 11000 $LASTPORT`; 41 | # do 42 | # lsof -t -i tcp:$i | xargs kill 43 | # done 44 | -------------------------------------------------------------------------------- /src/utils/commitment/dl.go: -------------------------------------------------------------------------------- 1 | package commitment 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/Nik-U/pbc" 7 | "github.com/ncw/gmp" 8 | ) 9 | 10 | // DLCommit for x is g^x 11 | type DLCommit struct { 12 | pairing *pbc.Pairing 13 | pk *pbc.Element 14 | } 15 | 16 | // Setup initializes a DLCommit. 17 | // group order is 2^rbits, finite field is F_q where q is ~2^qbits. 18 | // suggested parameters are rbits = 160, qbits = 512 19 | func (c *DLCommit) Setup(rbits, qbits uint32) { 20 | panic("unimplemented") 21 | } 22 | 23 | // Setup initializes a fixed DLCommit 24 | func (c *DLCommit) SetupFix() { 25 | c.pairing = Curve.Pairing 26 | c.pk = Curve.G 27 | } 28 | 29 | func (c *DLCommit) NewG1() *pbc.Element { 30 | return c.pairing.NewG1() 31 | } 32 | 33 | func (c *DLCommit) NewGT() *pbc.Element { 34 | return c.pairing.NewGT() 35 | } 36 | 37 | // Commit sets res to g^x 38 | func (c *DLCommit) Commit(res *pbc.Element, x *gmp.Int) { 39 | if c.pairing == nil || c.pk == nil { 40 | panic("not initialized") 41 | } 42 | exp := big.NewInt(0) 43 | exp.SetString(x.String(), 10) 44 | res.PowBig(c.pk, exp) 45 | } 46 | 47 | // Verify checks C == g^x 48 | func (c *DLCommit) Verify(C *pbc.Element, x *gmp.Int) bool { 49 | if c.pairing == nil || c.pk == nil { 50 | panic("not initialized") 51 | } 52 | tmp := c.pairing.NewG1() 53 | exp := big.NewInt(0) 54 | exp.SetString(x.String(), 10) 55 | tmp.PowBig(c.pk, exp) 56 | return tmp.Equals(C) 57 | } 58 | -------------------------------------------------------------------------------- /src/utils/ecparam/pbc.go: -------------------------------------------------------------------------------- 1 | package ecparam 2 | 3 | import ( 4 | "github.com/Nik-U/pbc" 5 | "github.com/ncw/gmp" 6 | "math/big" 7 | ) 8 | 9 | var PBC256 = initializeParams() 10 | 11 | const configString = "type a q 7551229346118097707657055192679868878245809937493679053434400908343538795134604198250280897597927293593086560738424067354362094283307245214081272453750739 h 130427378862502999532171986493880300490778513023419182702204867119101398441940 r 57896044618658097711785492504343953926634992332820282019728792006155588075521 exp2 255 exp1 41 sign1 1 sign0 1" 12 | 13 | const order = "57896044618658097711785492504343953926634992332820282019728792006155588075521" 14 | 15 | type ECParams struct { 16 | Params *pbc.Params 17 | Pairing *pbc.Pairing 18 | Nbig *big.Int 19 | Ngmp *gmp.Int 20 | G *pbc.Element 21 | } 22 | 23 | func initializeParams() ECParams { 24 | p, err := pbc.NewParamsFromString(configString) 25 | if err != nil { 26 | panic(err.Error()) 27 | } 28 | 29 | var pp ECParams 30 | 31 | pp.Params = p 32 | pp.Pairing = p.NewPairing() 33 | pp.Nbig = big.NewInt(0) 34 | pp.Nbig.SetString(order, 10) 35 | pp.Ngmp = gmp.NewInt(0) 36 | pp.Ngmp.SetString(order, 10) 37 | pp.G = pp.Pairing.NewG1() 38 | pp.G.SetString("[4133724144590655254194602165057338253581374248311829415804358586850519521096709820505371851539736973052316311123290392470565023776459368655389261216524371, 3477043631151308457697380491861699444387375269849172071603708732050642928211953792333616861215138231339668243778249230704600690552449532564174180095431116]", 10) 39 | 40 | return pp 41 | } 42 | -------------------------------------------------------------------------------- /src/utils/interpolation/interpolation_test.go: -------------------------------------------------------------------------------- 1 | package interpolation 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "math/rand" 7 | "testing" 8 | 9 | . "github.com/bl4ck5un/ChuRP/src/utils/polyring" 10 | "github.com/ncw/gmp" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | const POLY_ORDER = 500 15 | const RAND_SEED = 2 16 | 17 | var large_str string 18 | 19 | func gen_prime(p *gmp.Int, bitnum int) { 20 | var buffer bytes.Buffer 21 | for i := 0; i < bitnum; i++ { 22 | buffer.WriteString("0") 23 | } 24 | 25 | large_str = "1" 26 | large_str += buffer.String() 27 | 28 | p.SetString(large_str, 10) 29 | // No next_prime method in go yet. Placeholder for now 30 | p.Set(gmp.NewInt(15486511)) 31 | // p.Set(gmp.NewInt(7)) 32 | } 33 | 34 | func TestLagrangeInterpolate(t *testing.T) { 35 | p := gmp.NewInt(0) 36 | gen_prime(p, 256) 37 | r := rand.New(rand.NewSource(RAND_SEED)) 38 | 39 | fmt.Printf("Prime p = %s\n", p.String()) 40 | 41 | originalPoly, err := NewRand(POLY_ORDER, r, p) 42 | assert.Nil(t, err, "New") 43 | 44 | // Test EvalArray 45 | x := make([]*gmp.Int, POLY_ORDER+1) 46 | y := make([]*gmp.Int, POLY_ORDER+1) 47 | VecInit(x) 48 | VecInit(y) 49 | VecRand(x, p, r) 50 | 51 | originalPoly.EvalModArray(x, p, y) 52 | 53 | fmt.Println("Finished eval") 54 | fmt.Println("Starting interpolation") 55 | 56 | reconstructedPoly, err := LagrangeInterpolate(POLY_ORDER, x, y, p) 57 | assert.Nil(t, err, "New") 58 | 59 | //fmt.Printf("Original Poly ") 60 | //originalPoly.Print() 61 | 62 | //fmt.Printf("Reconstructed Poly ") 63 | //reconstructedPoly.Print() 64 | assert.True(t, reconstructedPoly.IsSame(originalPoly)) 65 | } 66 | -------------------------------------------------------------------------------- /src/networking/clock/clock.go: -------------------------------------------------------------------------------- 1 | package clock 2 | 3 | import ( 4 | "context" 5 | pb "github.com/bl4ck5un/ChuRP/src/services" 6 | "google.golang.org/grpc" 7 | "io/ioutil" 8 | "log" 9 | "strings" 10 | ) 11 | 12 | // Clock Simulator Structure 13 | type Clock struct { 14 | // Metadata Directory Path 15 | metadataPath string 16 | // BulltinBoard IP 17 | bip string 18 | // BulletinBoard Service Client 19 | bConn *grpc.ClientConn 20 | bClient pb.BulletinBoardServiceClient 21 | } 22 | 23 | func (clock *Clock) Connect() { 24 | bConn, err := grpc.Dial(clock.bip, grpc.WithInsecure()) 25 | if err != nil { 26 | log.Fatalf("clock did not connect: %v", err) 27 | } 28 | clock.bConn = bConn 29 | clock.bClient = pb.NewBulletinBoardServiceClient(clock.bConn) 30 | } 31 | 32 | func (clock *Clock) Disconnect() { 33 | clock.bConn.Close() 34 | } 35 | 36 | func (clock *Clock) ClientStartEpoch() { 37 | ctx, cancel := context.WithCancel(context.Background()) 38 | defer cancel() 39 | log.Print("client start epoch") 40 | _, err := clock.bClient.StartEpoch(ctx, &pb.EmptyMsg{}) 41 | if err != nil { 42 | log.Fatalf("clock start epoch failed: %v", err) 43 | } 44 | } 45 | 46 | func ReadIpList(metadataPath string) []string { 47 | ipData, err := ioutil.ReadFile(metadataPath + "/ip_list") 48 | if err != nil { 49 | log.Fatalf("clock failed to read iplist %v\n", err) 50 | } 51 | return strings.Split(string(ipData), "\n") 52 | } 53 | 54 | // New returns a network node structure 55 | func New(metadataPath string) (Clock, error) { 56 | bip := ReadIpList(metadataPath)[0] 57 | return Clock{ 58 | metadataPath: metadataPath, 59 | bip: bip, 60 | }, nil 61 | } 62 | -------------------------------------------------------------------------------- /src/services/services.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package services; 3 | 4 | // The bulletinboard service definition 5 | service BulletinBoardService { 6 | // Start a epoch 7 | rpc StartEpoch(EmptyMsg) returns (AckMsg) {} 8 | // BulletinBoard RPC for recontruction phase 9 | rpc ReadPhase1(EmptyMsg) returns (stream Cmt1Msg) {} 10 | // BulletinBoard RPC for proactivization phase 11 | rpc WritePhase2(Cmt2Msg) returns (AckMsg) {} 12 | rpc ReadPhase2(EmptyMsg) returns (stream Cmt2Msg) {} 13 | // BulletinBoard RPC for share distribution phase 14 | rpc WritePhase3(Cmt1Msg) returns (AckMsg) {} 15 | rpc ReadPhase3(EmptyMsg) returns (stream Cmt1Msg) {} 16 | } 17 | 18 | // The node service definition 19 | service NodeService { 20 | // Node RPC for reconstruction phase 21 | rpc StartPhase1(EmptyMsg) returns (AckMsg) {} 22 | rpc SharePhase1(PointMsg) returns (AckMsg) {} 23 | // Node RPC for proactivization phase 24 | rpc SharePhase2(ZeroMsg) returns (AckMsg) {} 25 | rpc StartVerifPhase2(EmptyMsg) returns (AckMsg) {} 26 | // Node RPC for share distribution phase 27 | rpc SharePhase3(PointMsg) returns (AckMsg) {} 28 | rpc StartVerifPhase3(EmptyMsg) returns (AckMsg) {} 29 | } 30 | 31 | message EmptyMsg {} 32 | 33 | message AckMsg {} 34 | 35 | message Cmt1Msg { 36 | int32 index = 1; 37 | bytes polycmt = 2; 38 | } 39 | 40 | message Cmt2Msg { 41 | int32 index = 1; 42 | bytes sharecmt = 2; 43 | bytes polycmt = 3; 44 | bytes zerowitness = 4; 45 | } 46 | 47 | message PointMsg { 48 | int32 index = 1; 49 | int32 x = 2; 50 | bytes y = 3; 51 | bytes witness = 4; 52 | } 53 | 54 | message ZeroMsg { 55 | int32 index = 1; 56 | bytes share = 2; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/utils/polycommit/p521/compress.go: -------------------------------------------------------------------------------- 1 | package p521 2 | 3 | import ( 4 | "crypto/elliptic" 5 | "math/big" 6 | ) 7 | 8 | // Marshal encodes a ECC Point into it's compressed representation 9 | func Marshal(curve elliptic.Curve, x, y *big.Int) []byte { 10 | byteLen := (curve.Params().BitSize + 7) >> 3 11 | 12 | ret := make([]byte, 1+byteLen) 13 | 14 | // handle point at infinity specially 15 | if x.BitLen() == 0 && y.BitLen() == 0 { 16 | ret[0] = 0xff 17 | return ret 18 | } 19 | 20 | ret[0] = 2 + byte(y.Bit(0)) 21 | 22 | xBytes := x.Bytes() 23 | copy(ret[1+byteLen-len(xBytes):], xBytes) 24 | 25 | return ret 26 | } 27 | 28 | // Unmarshal decodes an ECC Point from any representation 29 | func Unmarshal(curve elliptic.Curve, data []byte) (x, y *big.Int) { 30 | // handle infinity points specially 31 | if data[0] == 0xff { 32 | x = big.NewInt(0) 33 | y = big.NewInt(0) 34 | return 35 | } 36 | 37 | // Split the sign byte from the rest 38 | sign_byte := uint(data[0]) 39 | x_bytes := data[1:] 40 | 41 | // Convert to big Int. 42 | x = new(big.Int).SetBytes(x_bytes) 43 | 44 | // We use 3 a couple of times 45 | three := big.NewInt(3) 46 | 47 | // The params for P256 48 | c := curve.Params() 49 | 50 | // The equation is y^2 = x^3 - 3x + b 51 | // x^3, mod P 52 | x_cubed := new(big.Int).Exp(x, three, c.P) 53 | 54 | // 3x, mod P 55 | three_X := new(big.Int).Mul(x, three) 56 | three_X.Mod(three_X, c.P) 57 | 58 | // x^3 - 3x 59 | y_squared := new(big.Int).Sub(x_cubed, three_X) 60 | 61 | // ... + b mod P 62 | y_squared.Add(y_squared, c.B) 63 | y_squared.Mod(y_squared, c.P) 64 | 65 | // Now we need to find the square root mod P. 66 | // This is where Go's big int library redeems itself. 67 | y = big.NewInt(0).ModSqrt(y_squared, c.P) 68 | if y == nil { 69 | // If this happens then you're dealing with an invalid point. 70 | // Panic, return an error, whatever you want. 71 | panic("Invalid point") 72 | return 73 | } 74 | 75 | // Finally, check if you have the correct root. If not you want 76 | // -y mod P 77 | if y.Bit(0) != sign_byte&1 { 78 | y.Neg(y) 79 | y.Mod(y, c.P) 80 | } 81 | 82 | return x, y 83 | } 84 | -------------------------------------------------------------------------------- /src/utils/interpolation/interpolation.go: -------------------------------------------------------------------------------- 1 | package interpolation 2 | 3 | import ( 4 | "errors" 5 | 6 | . "github.com/bl4ck5un/ChuRP/src/utils/polyring" 7 | "github.com/ncw/gmp" 8 | ) 9 | 10 | func deduplicate(s []int) []int { 11 | seen := make(map[int]struct{}, len(s)) 12 | j := 0 13 | for _, v := range s { 14 | if _, ok := seen[v]; ok { 15 | continue 16 | } 17 | seen[v] = struct{}{} 18 | s[j] = v 19 | j++ 20 | } 21 | return s[:j] 22 | } 23 | 24 | // LagrangeInterpolate returns a polynomial of specified degree that pass through all points in x and y 25 | func LagrangeInterpolate(degree int, x []*gmp.Int, y []*gmp.Int, mod *gmp.Int) (Polynomial, error) { 26 | // initialize variables 27 | tmp, err := New(1) 28 | if err != nil { 29 | return Polynomial{}, err 30 | } 31 | 32 | inter, err := New(degree) 33 | if err != nil { 34 | return Polynomial{}, err 35 | } 36 | 37 | product := NewOne() 38 | 39 | resultPoly, err := New(degree) 40 | if err != nil { 41 | return Polynomial{}, err 42 | } 43 | 44 | denominator := gmp.NewInt(0) 45 | 46 | // tmp(x) = x - x[i] 47 | tmp.SetCoefficient(1, 1) 48 | // note only the first degree points are used 49 | for i := 0; i <= degree; i++ { 50 | tmp.GetPtrToConstant().Neg(x[i]) 51 | product.MulSelf(tmp) 52 | } 53 | 54 | for i := 0; i <= degree; i++ { 55 | denominator.Set(gmp.NewInt(1)) 56 | // compute denominator and numerator 57 | 58 | // tmp = x - x[i] 59 | tmp.SetCoefficient(1, 1) // i don't think this needed... 60 | tmp.GetPtrToConstant().Neg(x[i]) 61 | 62 | // inner(x) = (x-1)(x_2)...(x-n) except for (x-i) 63 | err = inter.Div2(product, tmp) 64 | if err != nil { 65 | return Polynomial{}, err 66 | } 67 | 68 | // lambda_i(x) = inner(x) * y[i] / inner(x[i]) 69 | 70 | inter.Mod(mod) 71 | inter.EvalMod(x[i], mod, denominator) 72 | 73 | // panic if denominator == 0 74 | if 0 == denominator.CmpInt32(0) { 75 | return Polynomial{}, errors.New("internal error: check duplication in x[]") 76 | } 77 | 78 | denominator.ModInverse(denominator, mod) 79 | denominator.Mul(denominator, y[i]) 80 | resultPoly.AddMul(inter, denominator) 81 | } 82 | 83 | resultPoly.Mod(mod) 84 | 85 | return resultPoly, nil 86 | } 87 | -------------------------------------------------------------------------------- /src/utils/polycommit/pbc/comm_test.go: -------------------------------------------------------------------------------- 1 | package commitpbc 2 | 3 | import ( 4 | "bytes" 5 | "encoding/gob" 6 | "math/rand" 7 | "testing" 8 | "time" 9 | 10 | "github.com/bl4ck5un/ChuRP/src/utils/conv" 11 | "github.com/bl4ck5un/ChuRP/src/utils/polyring" 12 | "github.com/ncw/gmp" 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | var poly = polyring.FromVec(0, 2, 3, 4, 5, 6) 17 | var poly2 = polyring.FromVec(11, 12, 13, 14, 15, 16) 18 | 19 | func TestParams_String(t *testing.T) { 20 | println(Curve.Params.String()) 21 | } 22 | 23 | func TestCommit(t *testing.T) { 24 | comm := NewPolyCommit(poly) 25 | assert.True(t, comm.Verify(poly)) 26 | } 27 | 28 | func TestPolyCommit_Verify(t *testing.T) { 29 | comm := NewPolyCommit(poly) 30 | assert.True(t, comm.Verify(poly)) 31 | } 32 | 33 | func TestPolyCommit_Gob(t *testing.T) { 34 | comm := NewPolyCommit(poly) 35 | assert.True(t, comm.Verify(poly)) 36 | 37 | buf := bytes.Buffer{} 38 | enc := gob.NewEncoder(&buf) 39 | 40 | err := enc.Encode(comm) 41 | if err != nil { 42 | assert.Fail(t, err.Error()) 43 | } 44 | 45 | dec := gob.NewDecoder(&buf) 46 | 47 | var commNew PolyCommit 48 | 49 | err = dec.Decode(&commNew) 50 | assert.Nil(t, err) 51 | 52 | assert.True(t, commNew.Equals(comm), "decoding") 53 | } 54 | 55 | func TestPolyCommit_VerifyEval(t *testing.T) { 56 | x := gmp.NewInt(15623523536) 57 | y := gmp.NewInt(0) 58 | poly.EvalMod(x, Curve.Ngmp, y) 59 | 60 | comm := NewPolyCommit(poly) 61 | r := comm.VerifyEval(conv.GmpInt2BigInt(x), conv.GmpInt2BigInt(y)) 62 | 63 | assert.True(t, r) 64 | } 65 | 66 | func TestAdditiveHomomorphism(t *testing.T) { 67 | com1 := NewPolyCommit(poly) 68 | com2 := NewPolyCommit(poly2) 69 | 70 | poly3 := polyring.Polynomial{} 71 | poly3.Add(poly, poly2) 72 | poly3.Mod(Curve.Ngmp) 73 | 74 | comm3 := AdditiveHomomorphism(com1, com2) 75 | assert.True(t, comm3.Verify(poly3)) 76 | } 77 | 78 | const bigPolyDegree = 100 79 | 80 | var rnd = rand.New(rand.NewSource(time.Now().UTC().UnixNano())) 81 | 82 | func BenchmarkVerifyEval(b *testing.B) { 83 | poly100, err := polyring.NewRand(bigPolyDegree, rnd, Curve.Ngmp) 84 | assert.Nil(b, err) 85 | 86 | // x is a random point 87 | x := new(gmp.Int) 88 | x.Rand(rnd, Curve.Ngmp) 89 | 90 | y := gmp.NewInt(0) 91 | poly100.EvalMod(x, Curve.Ngmp, y) 92 | 93 | comm := NewPolyCommit(poly100) 94 | 95 | b.Run("VerifyEval", func(b *testing.B) { 96 | //start := time.Now() 97 | for i := 0; i < b.N; i++ { 98 | comm.VerifyEval(conv.GmpInt2BigInt(x), conv.GmpInt2BigInt(y)) 99 | } 100 | }) 101 | } 102 | -------------------------------------------------------------------------------- /src/utils/encryption/encryption.go: -------------------------------------------------------------------------------- 1 | package encryption 2 | 3 | import ( 4 | "github.com/ncw/gmp" 5 | "crypto/sha256" 6 | "math/rand" 7 | ) 8 | 9 | // We need a hash function 10 | 11 | type PublicKey struct { 12 | q *gmp.Int 13 | g *gmp.Int 14 | h *gmp.Int 15 | } 16 | 17 | type PrivateKey struct { 18 | x *gmp.Int 19 | } 20 | 21 | type EncryptedInt struct { 22 | fst *gmp.Int 23 | snd *gmp.Int 24 | } 25 | 26 | type Proof struct { 27 | a *gmp.Int 28 | b *gmp.Int 29 | z *gmp.Int 30 | } 31 | 32 | func KeyGen(pk *PublicKey, sk *PrivateKey, q *gmp.Int, g *gmp.Int, rnd *rand.Rand) { 33 | 34 | pk.q = q 35 | pk.g = g 36 | sk.x = gmp.NewInt(0) 37 | sk.x.Rand(rnd, q) 38 | pk.h = gmp.NewInt(0) 39 | pk.h.Exp(g, sk.x, q) 40 | 41 | } 42 | 43 | func Encrypt(ei *EncryptedInt, proof *Proof, pk *PublicKey, m *gmp.Int, rnd *rand.Rand) { 44 | 45 | y := gmp.NewInt(0) 46 | y.Rand(rnd, pk.q) 47 | 48 | ei.fst = gmp.NewInt(0) 49 | ei.fst.Exp(pk.g, y, pk.q) 50 | ei.snd = gmp.NewInt(0) 51 | ei.snd.Exp(pk.h, y, pk.q) 52 | ei.snd.Mul(m, ei.snd) 53 | 54 | // pk.g, pk.h, ei.fst, ei.snd/m is a DH tuple 55 | r := gmp.NewInt(0) 56 | r.Rand(rnd, pk.q) 57 | proof.a = gmp.NewInt(0) 58 | proof.a.Exp(pk.g, r, pk.q) 59 | proof.b = gmp.NewInt(0) 60 | proof.b.Exp(pk.h, r, pk.q) 61 | bytes := append(pk.g.Bytes(), pk.h.Bytes()...) 62 | bytes = append(bytes, ei.fst.Bytes()...) 63 | tmp := gmp.NewInt(0) 64 | tmp.Div(ei.snd, m) 65 | bytes = append(bytes, tmp.Bytes()...) 66 | e := gmp.NewInt(0) 67 | tmp2 := sha256.Sum256(bytes) 68 | e.SetBytes(tmp2[:]) 69 | proof.z = gmp.NewInt(0) 70 | proof.z.Mul(e, y) 71 | proof.z.Add(r, proof.z) 72 | } 73 | 74 | func Decrypt(di *gmp.Int, pk *PublicKey, sk *PrivateKey, ei *EncryptedInt) { 75 | 76 | di.Exp(ei.fst, sk.x, pk.q) 77 | di.Div(ei.snd, di) 78 | } 79 | 80 | func Verify(proof *Proof, m *gmp.Int, ei *EncryptedInt, pk *PublicKey) bool { 81 | 82 | bytes := append(pk.g.Bytes(), pk.h.Bytes()...) 83 | bytes = append(bytes, ei.fst.Bytes()...) 84 | tmp := gmp.NewInt(0) 85 | tmp.Div(ei.snd, m) 86 | bytes = append(bytes, tmp.Bytes()...) 87 | e := gmp.NewInt(0) 88 | 89 | tmp1 := gmp.NewInt(0) 90 | tmp1.Exp(pk.g, proof.z, pk.q) 91 | 92 | tmp2 := gmp.NewInt(0) 93 | tmp2.Exp(ei.fst, e, pk.q) 94 | tmp2.Mul(proof.a, tmp2) 95 | 96 | judgement := (tmp1.Cmp(tmp2) == 0) 97 | 98 | tmp1.Exp(pk.h, proof.z, pk.q) 99 | 100 | tmp2.Exp(tmp, e, pk.q) 101 | tmp2.Mul(proof.b, tmp2) 102 | 103 | judgement = judgement && (tmp1.Cmp(tmp2) == 0) 104 | 105 | return judgement 106 | } 107 | -------------------------------------------------------------------------------- /src/utils/polycommit/p521/comm_test.go: -------------------------------------------------------------------------------- 1 | package p521 2 | 3 | import ( 4 | "bytes" 5 | "encoding/gob" 6 | "math/big" 7 | "testing" 8 | 9 | "github.com/bl4ck5un/ChuRP/src/utils/conv" 10 | "github.com/bl4ck5un/ChuRP/src/utils/polyring" 11 | "github.com/ncw/gmp" 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | var poly = polyring.FromVec(0, 2, 3, 4, 5, 6) 16 | var poly2 = polyring.FromVec(11, 12, 13, 14, 15, 16) 17 | 18 | func TestECPoint(t *testing.T) { 19 | x, y := Curve.ScalarBaseMult(big.NewInt(23487263784).Bytes()) 20 | ecp := ECPoint{ 21 | x: x, 22 | y: y, 23 | } 24 | 25 | buf := bytes.Buffer{} 26 | enc := gob.NewEncoder(&buf) 27 | 28 | err := enc.Encode(ecp) 29 | assert.Nil(t, err) 30 | 31 | dec := gob.NewDecoder(&buf) 32 | ecpNew := ECPoint{} 33 | 34 | err = dec.Decode(&ecpNew) 35 | assert.Nil(t, err) 36 | 37 | println(ecp.String()) 38 | println(ecpNew.String()) 39 | 40 | assert.True(t, ecpNew.Equals(ecp)) 41 | } 42 | 43 | func TestECPointZero(t *testing.T) { 44 | x, y := Curve.ScalarBaseMult(big.NewInt(0).Bytes()) 45 | ecp := ECPoint{ 46 | x: x, 47 | y: y, 48 | } 49 | 50 | buf := bytes.Buffer{} 51 | enc := gob.NewEncoder(&buf) 52 | 53 | err := enc.Encode(ecp) 54 | assert.Nil(t, err) 55 | 56 | dec := gob.NewDecoder(&buf) 57 | ecpNew := ECPoint{} 58 | 59 | err = dec.Decode(&ecpNew) 60 | assert.Nil(t, err) 61 | 62 | println(ecp.String()) 63 | println(ecpNew.String()) 64 | 65 | assert.True(t, ecpNew.Equals(ecp)) 66 | } 67 | 68 | func TestCommit(t *testing.T) { 69 | comm := NewPolyCommit(poly) 70 | assert.True(t, comm.Verify(poly)) 71 | } 72 | 73 | func TestPolyCommit_Verify(t *testing.T) { 74 | comm := NewPolyCommit(poly) 75 | assert.True(t, comm.Verify(poly)) 76 | } 77 | 78 | func TestPolyCommit_Gob(t *testing.T) { 79 | comm := NewPolyCommit(poly) 80 | assert.True(t, comm.Verify(poly)) 81 | 82 | buf := bytes.Buffer{} 83 | enc := gob.NewEncoder(&buf) 84 | 85 | err := enc.Encode(comm) 86 | if err != nil { 87 | assert.Fail(t, err.Error()) 88 | } 89 | 90 | dec := gob.NewDecoder(&buf) 91 | 92 | commNew := PolyCommit{} 93 | 94 | err = dec.Decode(&commNew) 95 | assert.Nil(t, err) 96 | 97 | assert.True(t, commNew.Equals(comm), "decoding") 98 | } 99 | 100 | func TestPolyCommit_VerifyEval(t *testing.T) { 101 | x := gmp.NewInt(15623523536) 102 | y := gmp.NewInt(0) 103 | poly.EvalMod(x, conv.BigInt2GmpInt(Curve.Params().N), y) 104 | 105 | comm := NewPolyCommit(poly) 106 | r := comm.VerifyEval(conv.GmpInt2BigInt(x), conv.GmpInt2BigInt(y)) 107 | 108 | assert.True(t, r) 109 | } 110 | 111 | func TestAdditiveHomomorphism(t *testing.T) { 112 | com1 := NewPolyCommit(poly) 113 | com2 := NewPolyCommit(poly2) 114 | 115 | poly3 := polyring.Polynomial{} 116 | poly3.Add(poly, poly2) 117 | poly3.Mod(conv.BigInt2GmpInt(Curve.Params().N)) 118 | 119 | comm3 := AdditiveHomomorphism(com1, com2) 120 | assert.True(t, comm3.Verify(poly3)) 121 | } 122 | -------------------------------------------------------------------------------- /src/utils/commitment/kate_test.go: -------------------------------------------------------------------------------- 1 | package commitment 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | 8 | "github.com/bl4ck5un/ChuRP/src/utils/polyring" 9 | . "github.com/ncw/gmp" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestDLCommit_Commit(test *testing.T) { 14 | c := new(DLPolyCommit) 15 | const t = 5 16 | p := new(Int) 17 | p.SetString("11", 10) 18 | rnd := rand.New(rand.NewSource(99)) 19 | 20 | // Test Setup 21 | c.SetupFix(t) 22 | //c.printPublicKey() 23 | 24 | // Sample a Poly and an x 25 | poly, err := polyring.NewRand(t, rnd, p) 26 | assert.Nil(test, err, "NewRand") 27 | 28 | // x is a random point 29 | x := new(Int) 30 | x.Rand(rnd, p) 31 | polyOfX := new(Int) 32 | 33 | C := c.pairing.NewG1() 34 | w := c.pairing.NewG1() 35 | 36 | // Test PolyCommit 37 | c.Commit(C, poly) 38 | 39 | assert.True(test, c.VerifyPoly(C, poly), "VerifyPoly") 40 | 41 | // Test EvalCommit 42 | c.polyEval(polyOfX, poly, x) 43 | c.CreateWitness(w, poly, x) 44 | assert.True(test, c.VerifyEval(C, x, polyOfX, w), "VerifyEval") 45 | } 46 | 47 | func TestDLCommit_Large(test *testing.T) { 48 | c := new(DLPolyCommit) 49 | const t = 5 50 | p := new(Int) 51 | p.SetString("3932072858627806935726538339277743355414825585881591575522777707551535001573144400655144117202165255655144740729157349730442866695802580292372730337639931", 10) 52 | rnd := rand.New(rand.NewSource(time.Now().UTC().UnixNano())) 53 | 54 | // Test Setup 55 | c.SetupFix(t) 56 | //c.printPublicKey() 57 | 58 | // Sample a Poly and an x 59 | poly, err := polyring.NewRand(t, rnd, p) 60 | assert.Nil(test, err, "NewRand") 61 | 62 | // x is a random point 63 | x := new(Int) 64 | x.Rand(rnd, p) 65 | polyOfX := new(Int) 66 | 67 | C := c.pairing.NewG1() 68 | w := c.pairing.NewG1() 69 | 70 | // Test PolyCommit 71 | c.Commit(C, poly) 72 | 73 | assert.True(test, c.VerifyPoly(C, poly), "VerifyPoly") 74 | 75 | // Test EvalCommit 76 | c.polyEval(polyOfX, poly, x) 77 | c.CreateWitness(w, poly, x) 78 | assert.True(test, c.VerifyEval(C, x, polyOfX, w), "VerifyEval") 79 | } 80 | 81 | const bigPolyDegree = 100 82 | 83 | var rnd = rand.New(rand.NewSource(time.Now().UTC().UnixNano())) 84 | 85 | func BenchmarkDLPolyCommit_VerifyEval(b *testing.B) { 86 | c := new(DLPolyCommit) 87 | 88 | c.SetupFix(bigPolyDegree) 89 | 90 | poly100, err := polyring.NewRand(bigPolyDegree, rnd, c.p) 91 | assert.Nil(b, err) 92 | 93 | // x is a random point 94 | x := new(Int) 95 | x.Rand(rnd, c.p) 96 | polyOfX := new(Int) 97 | 98 | C := c.pairing.NewG1() 99 | w := c.pairing.NewG1() 100 | 101 | // Test PolyCommit 102 | c.Commit(C, poly100) 103 | 104 | // Test EvalCommit 105 | c.polyEval(polyOfX, poly100, x) 106 | c.CreateWitness(w, poly100, x) 107 | 108 | b.Run("VerifyEval", func(b *testing.B) { 109 | for i := 0; i < b.N; i++ { 110 | assert.True(b, c.VerifyEval(C, x, polyOfX, w), "VerifyEval") 111 | } 112 | }) 113 | } 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------- 2 | 3 | **The CHURP code is an academic research prototype, and meant to elucidate protocol details and for proofs-of-concept, and benchmarking. It has not been developed in a production environment and is not meant for deployment.** 4 | 5 | ---------------------------------------------------------------- 6 | 7 | ![logo](logo.png) 8 | 9 | # CHURP: Dynamic-Committee Proactive Secret Sharing 10 | 11 | [![CircleCI](https://circleci.com/gh/bl4ck5un/ChuRP.svg?style=svg&circle-token=34c3da94eba4225de1da5c4eaabd37466cd50a8a)](https://circleci.com/gh/bl4ck5un/ChuRP) 12 | 13 | 14 | Achieving decentralization requires decentralized cryptography. CHURP (CHUrn-Robust Proactive secret sharing) is a cryptographic protocol for secret sharing in decentralized settings, where committee nodes may come and go. In such a setting, traditional secret sharing (e.g., Shamir's) is no longer secure. Featuring several fundamental innovations, CHURP accomplishes the mission while being 2300x more efficient than previous schemes! 15 | 16 | ## Getting Started 17 | 18 | This the repo for CHURP code (in Golang). Below you can find build and usage instructions. 19 | 20 | If you want to run a demo or play with pre-complied CHURP, the easiest way to get started is to use docker. Please refer to the [docker document](https://docs.docker.com/install/#supported-platforms) for installation instructions. 21 | 22 | If you want to build CHURP from source, we've prepared a special `builder` docker image for that, with dependecies installed. (If you really want to build/run the code natively, please refer to the [dockerfiles](dockerfiles/).) 23 | 24 | 25 | ### Run CHURP 26 | 27 | We release compiled executables in the docker image `churp/churp`. For example, to run a demo of 5 nodes, you can use the script `simple.sh` which is part of the docker image: 28 | 29 | ~~~ 30 | docker run -ti churp/churp bash 31 | # ./simple.sh 5 2 32 | ~~~ 33 | 34 | `simple.sh` starts a demo with n=5 nodes using a polynomial of degree t=2. **Note that we require n >= 2t+1**. 35 | 36 | ### Build 37 | 38 | We prepared a special `builder` docker image for building CHURP from source code. Make sure you're in the root of the repo (i.e., the directory that has `src`), then run the following to launch the builder: 39 | 40 | ~~~ 41 | docker run -ti -v $(pwd)/src:/src --workdir /src churp/builder bash 42 | # make # build using the provided Makefile 43 | ~~~ 44 | 45 | ## API 46 | 47 | At a high level, CHURP provides the following API: 48 | 49 | * `initialize(t, [nodeList], ...)`: Set the required parameters for CHURP: `t` stands for the threshold and `nodeList` represents the set of nodes that form a committee. Some other parameters that need to be set are the epoch duration and commitment scheme parameters. 50 | 51 | * (Optional) `storeSecret(SK)`: Distribute the secret `SK` using [(t, n)-sharing](https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing) `(n=|nodeList|)` such that each node in `nodeList` stores a share of the secret. (Note that this function is optional. For some applications, the secret might be generated randomly using [Distributed Key Generation](https://en.wikipedia.org/wiki/Distributed_key_generation) protocols.) 52 | 53 | * `changeCommittee([newNodeList])`: Execute CHURP to handoff the secret `SK` from the old committee, `nodeList`, to the new committee, `newNodeList`. 54 | 55 | * (Optional) `retrieveSecret() -> SK`: Reconstruct the secret from shares retrieved from nodes in the `nodeList`. (Note that this function is optional, i.e., CHURP works without any need to explicitly reconstruct the secret.) 56 | 57 | ## Acknowledges 58 | 59 | Currently CHURP is built on [Pairing Based Cryptography library](https://crypto.stanford.edu/pbc/) (LGPL) and its [Go wrapper](https://github.com/Nik-U/pbc), [GNU Multi Precision library](https://gmplib.org/) and its [Go wrapper](https://github.com/ncw/gmp) (BSD), and [Google Protobuffer](https://github.com/golang/protobuf). 60 | -------------------------------------------------------------------------------- /src/utils/polycommit/pbc/comm.go: -------------------------------------------------------------------------------- 1 | package commitpbc 2 | 3 | import ( 4 | "bytes" 5 | "encoding/gob" 6 | "fmt" 7 | "math/big" 8 | 9 | "github.com/Nik-U/pbc" 10 | "github.com/bl4ck5un/ChuRP/src/utils/conv" 11 | "github.com/bl4ck5un/ChuRP/src/utils/ecparam" 12 | "github.com/bl4ck5un/ChuRP/src/utils/polyring" 13 | ) 14 | 15 | var Curve = ecparam.PBC256 16 | 17 | // a commitment to a polynomial {a0, a1, ..., at} is g^at 18 | // ai are from the multiplicative group of integers modulo p 19 | type PolyCommit struct { 20 | c []*pbc.Element 21 | } 22 | 23 | func (comm PolyCommit) GobEncode() ([]byte, error) { 24 | var buf bytes.Buffer 25 | enc := gob.NewEncoder(&buf) 26 | 27 | binary := make([][]byte, len(comm.c)) 28 | 29 | for i := range binary { 30 | binary[i] = comm.c[i].CompressedBytes() 31 | if comm.c[i].Is0() { 32 | binary[i][0] = 0xff 33 | } 34 | } 35 | 36 | if err := enc.Encode(binary); err != nil { 37 | return nil, err 38 | } 39 | 40 | return buf.Bytes(), nil 41 | } 42 | 43 | func (comm *PolyCommit) GobDecode(buf []byte) error { 44 | r := bytes.NewBuffer(buf) 45 | dec := gob.NewDecoder(r) 46 | 47 | var binary [][]byte 48 | 49 | if err := dec.Decode(&binary); err != nil { 50 | return err 51 | } 52 | 53 | comm.c = make([]*pbc.Element, len(binary)) 54 | 55 | for i := range binary { 56 | comm.c[i] = Curve.Pairing.NewG1() 57 | // handling infinity point specially 58 | if binary[i][0] == 0xff { 59 | comm.c[i].Set0() 60 | } else { 61 | comm.c[i].SetCompressedBytes(binary[i]) 62 | } 63 | } 64 | 65 | return nil 66 | } 67 | 68 | func (comm PolyCommit) Equals(other PolyCommit) bool { 69 | if len(comm.c) != len(other.c) { 70 | return false 71 | } 72 | 73 | for i := range other.c { 74 | if !comm.c[i].Equals(other.c[i]) { 75 | return false 76 | } 77 | } 78 | 79 | return true 80 | } 81 | 82 | func (comm PolyCommit) Bytes() []byte { 83 | binary, err := comm.GobEncode() 84 | if err != nil { 85 | panic(err.Error()) 86 | } 87 | 88 | return binary 89 | } 90 | 91 | func (comm PolyCommit) String() string { 92 | s := "" 93 | for i := range comm.c { 94 | s += fmt.Sprintf("%s, ", comm.c[i]) 95 | } 96 | 97 | return s 98 | } 99 | 100 | func (comm PolyCommit) Print() { 101 | fmt.Println("comm =", comm.String()) 102 | } 103 | 104 | func NewPolyCommit(polynomial polyring.Polynomial) PolyCommit { 105 | allCoeff := polynomial.GetAllCoefficients() 106 | 107 | comm := PolyCommit{ 108 | c: make([]*pbc.Element, len(allCoeff)), 109 | } 110 | 111 | for i, coeff := range allCoeff { 112 | comm.c[i] = Curve.Pairing.NewG1() 113 | pow := conv.GmpInt2BigInt(coeff) 114 | Curve.G.PowBig(comm.c[i], pow) 115 | } 116 | 117 | return comm 118 | } 119 | 120 | func (comm PolyCommit) Verify(poly polyring.Polynomial) bool { 121 | coeffs := poly.GetAllCoefficients() 122 | 123 | commCheck := PolyCommit{ 124 | c: make([]*pbc.Element, len(coeffs)), 125 | } 126 | 127 | for i, coeff := range coeffs { 128 | commCheck.c[i] = Curve.Pairing.NewG1() 129 | Curve.G.PowBig(commCheck.c[i], conv.GmpInt2BigInt(coeff)) 130 | if !commCheck.c[i].Equals(comm.c[i]) { 131 | return false 132 | } 133 | } 134 | 135 | return true 136 | } 137 | 138 | func (comm PolyCommit) VerifyEval(x *big.Int, y *big.Int) bool { 139 | gYRef := Curve.Pairing.NewG1() 140 | Curve.G.PowBig(gYRef, y) 141 | 142 | xx := big.NewInt(1) 143 | 144 | gPx := Curve.Pairing.NewG1() 145 | gPx.Set1() 146 | 147 | tmp := Curve.Pairing.NewG1() 148 | for i := range comm.c { 149 | // tmp = g^ai^{x^i} 150 | tmp.PowBig(comm.c[i], xx) 151 | 152 | gPx.Mul(tmp, gPx) 153 | 154 | xx.Mul(xx, x) 155 | xx.Mod(xx, Curve.Nbig) 156 | } 157 | 158 | return gPx.Equals(gYRef) 159 | } 160 | 161 | // return a commitment to Q+R 162 | func AdditiveHomomorphism(commQ, commR PolyCommit) PolyCommit { 163 | if len(commQ.c) != len(commR.c) { 164 | panic("mismatch degree") 165 | } 166 | 167 | comm := PolyCommit{ 168 | c: make([]*pbc.Element, len(commQ.c)), 169 | } 170 | 171 | for i := range comm.c { 172 | comm.c[i] = Curve.Pairing.NewG1() 173 | comm.c[i].Mul(commQ.c[i], commR.c[i]) 174 | } 175 | 176 | return comm 177 | } 178 | -------------------------------------------------------------------------------- /src/utils/polycommit/p521/comm.go: -------------------------------------------------------------------------------- 1 | package p521 2 | 3 | import ( 4 | "bytes" 5 | "crypto/elliptic" 6 | "encoding/gob" 7 | "fmt" 8 | "math/big" 9 | 10 | "github.com/bl4ck5un/ChuRP/src/utils/polyring" 11 | ) 12 | 13 | // this uses Curve 14 | var Curve = elliptic.P521() 15 | 16 | type ECPoint struct { 17 | x *big.Int 18 | y *big.Int 19 | } 20 | 21 | func NewECPoint(x, y *big.Int) ECPoint { 22 | return ECPoint{ 23 | x: x, 24 | y: y, 25 | } 26 | } 27 | 28 | func (ecp ECPoint) GobEncode() ([]byte, error) { 29 | return Marshal(Curve, ecp.x, ecp.y), nil 30 | } 31 | 32 | func (ecp *ECPoint) GobDecode(buf []byte) error { 33 | ecp.x, ecp.y = Unmarshal(Curve, buf) 34 | return nil 35 | } 36 | 37 | func (ecp ECPoint) Equals(other ECPoint) bool { 38 | return 0 == ecp.x.Cmp(other.x) && 0 == ecp.y.Cmp(other.y) 39 | } 40 | 41 | func (ecp ECPoint) String() string { 42 | return fmt.Sprintf("(%s, %s)", ecp.x.String(), ecp.y.String()) 43 | } 44 | 45 | // a commitment to a polynomial {a0, a1, ..., at} is g^at 46 | // ai are from the multiplicative group of integers modulo p 47 | type PolyCommit struct { 48 | c []ECPoint 49 | } 50 | 51 | func (comm PolyCommit) GobEncode() ([]byte, error) { 52 | var buf bytes.Buffer 53 | enc := gob.NewEncoder(&buf) 54 | 55 | lenC := int32(len(comm.c)) 56 | 57 | if err := enc.Encode(lenC); err != nil { 58 | return nil, err 59 | } 60 | 61 | if err := enc.Encode(comm.c); err != nil { 62 | return nil, err 63 | } 64 | 65 | return buf.Bytes(), nil 66 | } 67 | 68 | func (comm *PolyCommit) GobDecode(buf []byte) error { 69 | r := bytes.NewBuffer(buf) 70 | dec := gob.NewDecoder(r) 71 | 72 | var lenC int32 = 0 73 | 74 | if err := dec.Decode(&lenC); err != nil { 75 | return err 76 | } 77 | 78 | comm.c = make([]ECPoint, lenC) 79 | if err := dec.Decode(&comm.c); err != nil { 80 | return err 81 | } 82 | 83 | return nil 84 | } 85 | 86 | func (comm PolyCommit) Equals(other PolyCommit) bool { 87 | if len(comm.c) != len(other.c) { 88 | return false 89 | } 90 | 91 | for i := range other.c { 92 | if !comm.c[i].Equals(other.c[i]) { 93 | return false 94 | } 95 | } 96 | 97 | return true 98 | } 99 | 100 | func (comm PolyCommit) Bytes() []byte { 101 | binary, err := comm.GobEncode() 102 | if err != nil { 103 | panic(err.Error()) 104 | } 105 | 106 | return binary 107 | } 108 | 109 | func (comm PolyCommit) String() string { 110 | s := "" 111 | for i := range comm.c { 112 | s += fmt.Sprintf("%s, ", comm.c[i].String()) 113 | } 114 | 115 | return s 116 | } 117 | 118 | func (comm PolyCommit) Print() { 119 | fmt.Println("comm =", comm.String()) 120 | } 121 | 122 | func NewPolyCommit(polynomial polyring.Polynomial) PolyCommit { 123 | allCoeff := polynomial.GetAllCoefficients() 124 | 125 | comm := PolyCommit{ 126 | make([]ECPoint, len(allCoeff)), 127 | } 128 | 129 | for i, coeff := range allCoeff { 130 | x, y := Curve.ScalarBaseMult(coeff.Bytes()) 131 | comm.c[i] = ECPoint{ 132 | x: x, 133 | y: y, 134 | } 135 | } 136 | 137 | return comm 138 | } 139 | 140 | func (comm PolyCommit) Verify(poly polyring.Polynomial) bool { 141 | allCoeff := poly.GetAllCoefficients() 142 | 143 | commCheck := PolyCommit{ 144 | make([]ECPoint, len(allCoeff)), 145 | } 146 | 147 | for i, coeff := range allCoeff { 148 | x, y := Curve.ScalarBaseMult(coeff.Bytes()) 149 | commCheck.c[i] = ECPoint{ 150 | x: x, 151 | y: y, 152 | } 153 | if !commCheck.c[i].Equals(comm.c[i]) { 154 | return false 155 | } 156 | } 157 | 158 | return true 159 | } 160 | 161 | func (comm PolyCommit) VerifyEval(x *big.Int, y *big.Int) bool { 162 | gYRef := NewECPoint(Curve.ScalarBaseMult(y.Bytes())) 163 | 164 | xx := big.NewInt(1) 165 | 166 | gPxx := big.NewInt(0) 167 | gPxy := big.NewInt(0) 168 | for i := range comm.c { 169 | px, py := Curve.ScalarMult(comm.c[i].x, comm.c[i].y, xx.Bytes()) 170 | 171 | gPxx, gPxy = Curve.Add(gPxx, gPxy, px, py) 172 | 173 | xx.Mul(xx, x) 174 | xx.Mod(xx, Curve.Params().N) 175 | } 176 | 177 | gPx := NewECPoint(gPxx, gPxy) 178 | 179 | return gPx.Equals(gYRef) 180 | } 181 | 182 | // return a commitment to Q+R 183 | func AdditiveHomomorphism(commQ, commR PolyCommit) PolyCommit { 184 | if len(commQ.c) != len(commR.c) { 185 | panic("mismatch degree") 186 | } 187 | 188 | comm := PolyCommit{ 189 | c: make([]ECPoint, len(commQ.c)), 190 | } 191 | 192 | for i := range comm.c { 193 | x, y := Curve.Add(commQ.c[i].x, commQ.c[i].y, commR.c[i].x, commR.c[i].y) 194 | comm.c[i] = NewECPoint(x, y) 195 | } 196 | 197 | return comm 198 | } 199 | -------------------------------------------------------------------------------- /src/utils/commitment/kate.go: -------------------------------------------------------------------------------- 1 | package commitment 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | 7 | . "github.com/Nik-U/pbc" 8 | "github.com/bl4ck5un/ChuRP/src/utils/conv" 9 | "github.com/bl4ck5un/ChuRP/src/utils/ecparam" 10 | "github.com/bl4ck5un/ChuRP/src/utils/polyring" 11 | . "github.com/ncw/gmp" 12 | ) 13 | 14 | type DLPolyCommit struct { 15 | pairing *Pairing 16 | pk []*Power 17 | degree int 18 | p *Int 19 | } 20 | 21 | // Generate New G1 22 | func (c *DLPolyCommit) NewG1() *Element { 23 | return c.pairing.NewG1() 24 | } 25 | 26 | //Generate New GT 27 | func (c *DLPolyCommit) NewGT() *Element { 28 | return c.pairing.NewGT() 29 | } 30 | 31 | // polyEval sets res to polyring(x) 32 | func (c *DLPolyCommit) polyEval(res *Int, poly polyring.Polynomial, x *Int) { 33 | 34 | poly.EvalMod(x, c.p, res) 35 | } 36 | 37 | // Let polyring(x)=c0 + c1*x + ... cn * x^n, polyEvalInExponent sets res to g^polyring(alpha) 38 | func (c *DLPolyCommit) polyEvalInExponent(res *Element, poly polyring.Polynomial) { 39 | // res = 1 40 | res.Set1() 41 | tmp := c.pairing.NewG1() 42 | for i := 0; i <= poly.GetDegree(); i++ { 43 | // tmp = g^{a^i} ^ ci 44 | ci, err := poly.GetCoefficient(i) 45 | if err != nil { 46 | panic("can't get coeff i") 47 | } 48 | 49 | c.pk[i].PowBig(tmp, conv.GmpInt2BigInt(&ci)) 50 | res.Mul(res, tmp) 51 | } 52 | } 53 | 54 | // print the public keys 55 | func (c *DLPolyCommit) printPublicKey() { 56 | for i := 0; i <= c.degree; i++ { 57 | fmt.Printf("g^(SK^%d): %s\n", i, c.pk[i].Source().String()) 58 | } 59 | } 60 | 61 | var Curve = ecparam.PBC256 62 | 63 | // SetupFix initializes a fixed pairing 64 | func (c *DLPolyCommit) SetupFix(degree int) { 65 | c.degree = degree 66 | 67 | // setup the pairing 68 | c.pairing = Curve.Pairing 69 | c.p = Curve.Ngmp 70 | 71 | // trusted setup 72 | c.pk = make([]*Power, degree+1) 73 | 74 | // a generator g 75 | g := Curve.G 76 | 77 | // secret key 78 | sk := new(big.Int) 79 | sk.SetString("2", 10) 80 | 81 | tmp := new(big.Int) 82 | for i := 0; i <= degree; i++ { 83 | // tmp = sk ^ i 84 | bigP := big.NewInt(0) 85 | bigP.SetString(c.p.String(), 10) 86 | tmp.Exp(sk, big.NewInt(int64(i)), bigP) 87 | // pk[i] = g ^ tmp 88 | // Search pk and modify them all 89 | inter := c.pairing.NewG1() 90 | c.pk[i] = inter.PowBig(g, tmp).PreparePower() 91 | } 92 | } 93 | 94 | // Commit sets res to g^polyring(alpha) 95 | func (c *DLPolyCommit) Commit(res *Element, poly polyring.Polynomial) { 96 | c.polyEvalInExponent(res, poly) 97 | } 98 | 99 | // Open is not used 100 | func (c *DLPolyCommit) Open() { 101 | panic("unimplemented") 102 | } 103 | 104 | // VerifyPoly checks C == g ^ polyring(alpha) 105 | func (c *DLPolyCommit) VerifyPoly(C *Element, poly polyring.Polynomial) bool { 106 | tmp := c.pairing.NewG1() 107 | c.polyEvalInExponent(tmp, poly) 108 | return tmp.Equals(C) 109 | } 110 | 111 | // CreateWitness sets res to g ^ phi(alpha) where phi(x) = (polyring(x)-polyring(x0)) / (x - x0) 112 | func (c *DLPolyCommit) CreateWitness(res *Element, polynomial polyring.Polynomial, x0 *Int) { 113 | poly_t := polynomial.DeepCopy() 114 | 115 | // tmp = polynomial(x0) 116 | tmp := new(Int) 117 | c.polyEval(tmp, poly_t, x0) 118 | // fmt.Printf("CreateWitness\n%s\n%s\n", polynomial.String(), tmp.String()) 119 | 120 | // poly_t = polynomial(x)-polynomial(x0) 121 | poly_t.GetPtrToConstant().Sub(poly_t.GetPtrToConstant(), tmp) 122 | 123 | // quot == poly_t / (x - x0) 124 | quot := polyring.NewEmpty() 125 | 126 | // denominator = x - x0 127 | denominator, err := polyring.New(1) 128 | if err != nil { 129 | panic("can't create polyring") 130 | } 131 | // FIXME: converting to int64 is dangerous 132 | denominator.SetCoefficient(1, 1) 133 | denominator.GetPtrToConstant().Neg(x0) 134 | 135 | quot.Div2(poly_t, denominator) 136 | // fmt.Printf("CreateWitness2\n%s\n", quot.String()) 137 | 138 | c.polyEvalInExponent(res, quot) 139 | } 140 | 141 | // VerifyEval checks the correctness of w, returns true/false 142 | func (c *DLPolyCommit) VerifyEval(C *Element, x *Int, polyX *Int, w *Element) bool { 143 | e1 := c.pairing.NewGT() 144 | e2 := c.pairing.NewGT() 145 | t1 := c.pairing.NewGT() 146 | t2 := c.pairing.NewG1() 147 | e1.Pair(C, c.pk[0].Source()) 148 | exp := big.NewInt(0) 149 | exp.SetString(x.String(), 10) 150 | c.pk[0].PowBig(t2, exp) 151 | t2.Div(c.pk[1].Source(), t2) 152 | e2.Pair(w, t2) 153 | t1.Pair(c.pk[0].Source(), c.pk[0].Source()) 154 | exp.SetString(polyX.String(), 10) 155 | t1.PowBig(t1, exp) 156 | e2.Mul(e2, t1) 157 | // fmt.Printf("e1\n%s\ne2\n%s\n", e1.String(), e2.String()) 158 | return e1.Equals(e2) 159 | } 160 | -------------------------------------------------------------------------------- /src/go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 3 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 4 | github.com/Nik-U/pbc v0.0.0-20181205041846-3e516ca0c5d6 h1:GU/vL5sj0IgGYEOIIAJ1HDI9dgqT0gJXkhXINri7Otc= 5 | github.com/Nik-U/pbc v0.0.0-20181205041846-3e516ca0c5d6/go.mod h1:Zt2U1SemYWNGXqS1fDiZC7u74nsJTAnWK5WVgvI8OAs= 6 | github.com/bl4ck5un/CHuRP v0.0.0-20190221163649-122e305c9fd0 h1:wFCbcoPDsVHakoLOuZq+PhZAei97fMLPcLocnOE0rJY= 7 | github.com/bl4ck5un/CHuRP v0.0.0-20190221163649-122e305c9fd0/go.mod h1:pBwP0HCYKplxjUSmjmyMLp9kjb48bKOkp0jfZeHFVng= 8 | github.com/bl4ck5un/ChURP v0.0.0-20190221163649-122e305c9fd0 h1:kS4W2Y68EJDAYLmjzrwQv8YC1niE85z9qcKPImzkHFk= 9 | github.com/bl4ck5un/ChURP v0.0.0-20190221163649-122e305c9fd0/go.mod h1:sVlQJKKfgRXlTE9Lsfh5+jBz1YDYXqbva6kF1NE1OOc= 10 | github.com/bl4ck5un/ChuRP v0.0.0-20190221163649-122e305c9fd0 h1:tI4o3WZ7zaMFqAMnygC1NlnqG1xZb3A2sspmJisjdQs= 11 | github.com/bl4ck5un/ChuRP v0.0.0-20190221163649-122e305c9fd0/go.mod h1:+EHXEt/hOLC3gcJnyyycuGC92Oj6fstX4MSZY1poOFM= 12 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 13 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 14 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 15 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 16 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 17 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 18 | github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk= 19 | github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= 20 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 21 | github.com/montanaflynn/stats v0.5.0 h1:2EkzeTSqBB4V4bJwWrt5gIIrZmpJBcoIRGS2kWLgzmk= 22 | github.com/montanaflynn/stats v0.5.0/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= 23 | github.com/ncw/gmp v1.0.3 h1:RRbpng3WhDiI6H33t2JF3p+MDpwtK2aT/+eGWtqlGD0= 24 | github.com/ncw/gmp v1.0.3/go.mod h1:9KgVqQFm/0I9jDkwYqpVpvx0tpb2oTDDqZSKvcxEPmg= 25 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 26 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 27 | github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME= 28 | github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 29 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 30 | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= 31 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 32 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= 33 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 34 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 35 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 36 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= 37 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 38 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 39 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 40 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 41 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= 42 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 43 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 44 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 45 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 46 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 47 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 48 | google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw= 49 | google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 50 | google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= 51 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 52 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 53 | -------------------------------------------------------------------------------- /src/networking/bulletinboard/bulletinboard.go: -------------------------------------------------------------------------------- 1 | package bulletinboard 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | pb "github.com/bl4ck5un/ChuRP/src/services" 8 | "github.com/bl4ck5un/ChuRP/src/utils/commitment" 9 | "github.com/bl4ck5un/ChuRP/src/utils/polyring" 10 | "io/ioutil" 11 | "log" 12 | "math/rand" 13 | "net" 14 | "os" 15 | "strings" 16 | "sync" 17 | // "time" 18 | "github.com/golang/protobuf/proto" 19 | "github.com/ncw/gmp" 20 | "google.golang.org/grpc" 21 | "google.golang.org/grpc/reflection" 22 | ) 23 | 24 | // BulletinBoard Simulator Structure 25 | type BulletinBoard struct { 26 | // Metadata Directory Path 27 | metadataPath string 28 | // Counter 29 | counter int 30 | // BulletinBoard IP Address 31 | bip string 32 | // IP 33 | ipList []string 34 | // Rand 35 | randState *rand.Rand 36 | // Reconstruction BulletinBoard 37 | reconstructionContent []*pb.Cmt1Msg 38 | // Proactivization BulletinBoard 39 | proCnt *int 40 | proactivizationContent []*pb.Cmt2Msg 41 | // Share Distribution BulletinBoard 42 | shaCnt *int 43 | 44 | // Mutexes 45 | mutex sync.Mutex 46 | 47 | nConn []*grpc.ClientConn 48 | nClient []pb.NodeServiceClient 49 | 50 | // Metrics 51 | totMsgSize *int 52 | } 53 | 54 | func (bb *BulletinBoard) StartEpoch(ctx context.Context, in *pb.EmptyMsg) (*pb.AckMsg, error) { 55 | log.Print("[bulletinboard] start epoch") 56 | bb.ClientStartPhase1() 57 | return &pb.AckMsg{}, nil 58 | } 59 | 60 | func (bb *BulletinBoard) ReadPhase1(in *pb.EmptyMsg, stream pb.BulletinBoardService_ReadPhase1Server) error { 61 | log.Print("[bulletinboard] is being read in phase 1") 62 | for i := 0; i < bb.counter; i++ { 63 | if err := stream.Send(bb.reconstructionContent[i]); err != nil { 64 | log.Fatalf("bulletinboard failed to read phase1: %v", err) 65 | return err 66 | } 67 | } 68 | return nil 69 | } 70 | 71 | func (bb *BulletinBoard) WritePhase2(ctx context.Context, msg *pb.Cmt2Msg) (*pb.AckMsg, error) { 72 | *bb.totMsgSize = *bb.totMsgSize + proto.Size(msg) 73 | log.Print("[bulletinboard] is being written in phase 2") 74 | index := msg.GetIndex() 75 | bb.proactivizationContent[index-1] = msg 76 | bb.mutex.Lock() 77 | *bb.proCnt = *bb.proCnt + 1 78 | flag := (*bb.proCnt == bb.counter) 79 | bb.mutex.Unlock() 80 | if flag { 81 | *bb.proCnt = 0 82 | bb.ClientStartVerifPhase2() 83 | } 84 | return &pb.AckMsg{}, nil 85 | } 86 | 87 | func (bb *BulletinBoard) ReadPhase2(in *pb.EmptyMsg, stream pb.BulletinBoardService_ReadPhase2Server) error { 88 | log.Print("[bulletinboard] is beting read in phase 2") 89 | for i := 0; i < bb.counter; i++ { 90 | if err := stream.Send(bb.proactivizationContent[i]); err != nil { 91 | log.Fatalf("bulletinboard failed to read phase2: %v", err) 92 | return err 93 | } 94 | } 95 | return nil 96 | } 97 | 98 | func (bb *BulletinBoard) WritePhase3(ctx context.Context, msg *pb.Cmt1Msg) (*pb.AckMsg, error) { 99 | *bb.totMsgSize = *bb.totMsgSize + proto.Size(msg) 100 | log.Print("[bulletinboard] is being written in phase 3") 101 | index := msg.GetIndex() 102 | bb.reconstructionContent[index-1] = msg 103 | bb.mutex.Lock() 104 | *bb.shaCnt = *bb.shaCnt + 1 105 | flag := (*bb.shaCnt == bb.counter) 106 | bb.mutex.Unlock() 107 | if flag { 108 | *bb.shaCnt = 0 109 | bb.ClientStartVerifPhase3() 110 | } 111 | return &pb.AckMsg{}, nil 112 | } 113 | 114 | func (bb *BulletinBoard) ReadPhase3(in *pb.EmptyMsg, stream pb.BulletinBoardService_ReadPhase3Server) error { 115 | log.Print("[bulletinboard] is being read in phase 3") 116 | for i := 0; i < bb.counter; i++ { 117 | if err := stream.Send(bb.reconstructionContent[i]); err != nil { 118 | log.Fatalf("bulletinboard failed to read phase2: %v", err) 119 | return err 120 | } 121 | } 122 | return nil 123 | } 124 | 125 | func (bb *BulletinBoard) Connect() { 126 | for i := 0; i < bb.counter; i++ { 127 | nConn, err := grpc.Dial(bb.ipList[i], grpc.WithInsecure()) 128 | if err != nil { 129 | log.Fatalf("bulletinboard did not connect: %v", err) 130 | } 131 | bb.nConn[i] = nConn 132 | bb.nClient[i] = pb.NewNodeServiceClient(nConn) 133 | } 134 | } 135 | 136 | func (bb *BulletinBoard) Disconnect() { 137 | for i := 0; i < bb.counter; i++ { 138 | bb.nConn[i].Close() 139 | } 140 | } 141 | 142 | func (bb *BulletinBoard) Serve(aws bool) { 143 | port := bb.bip 144 | if aws { 145 | port = "0.0.0.0:12001" 146 | } 147 | lis, err := net.Listen("tcp", port) 148 | if err != nil { 149 | log.Fatalf("bulletinboard failed to listen %v", err) 150 | } 151 | s := grpc.NewServer() 152 | pb.RegisterBulletinBoardServiceServer(s, bb) 153 | reflection.Register(s) 154 | log.Printf("bulletinboard serve on " + bb.bip) 155 | if err := s.Serve(lis); err != nil { 156 | log.Fatalf("bulletinboard failed to serve %v", err) 157 | } 158 | } 159 | 160 | func (bb *BulletinBoard) ClientStartPhase1() { 161 | if bb.nConn[0] == nil { 162 | bb.Connect() 163 | } 164 | var wg sync.WaitGroup 165 | for i := 0; i < bb.counter; i++ { 166 | log.Print("[bulletinboard] start phase 1") 167 | wg.Add(1) 168 | go func(i int) { 169 | defer wg.Done() 170 | ctx, cancel := context.WithCancel(context.Background()) 171 | defer cancel() 172 | bb.nClient[i].StartPhase1(ctx, &pb.EmptyMsg{}) 173 | }(i) 174 | } 175 | wg.Wait() 176 | } 177 | 178 | func (bb *BulletinBoard) ClientStartVerifPhase2() { 179 | var wg sync.WaitGroup 180 | for i := 0; i < bb.counter; i++ { 181 | log.Print("[bulletinboard] start verification in phase 2") 182 | wg.Add(1) 183 | go func(i int) { 184 | defer wg.Done() 185 | ctx, cancel := context.WithCancel(context.Background()) 186 | defer cancel() 187 | bb.nClient[i].StartVerifPhase2(ctx, &pb.EmptyMsg{}) 188 | }(i) 189 | } 190 | wg.Wait() 191 | } 192 | 193 | func (bb *BulletinBoard) ClientStartVerifPhase3() { 194 | var wg sync.WaitGroup 195 | for i := 0; i < bb.counter; i++ { 196 | log.Print("[bulletinboard] start verification in phase 3") 197 | wg.Add(1) 198 | go func(i int) { 199 | defer wg.Done() 200 | ctx, cancel := context.WithCancel(context.Background()) 201 | defer cancel() 202 | bb.nClient[i].StartVerifPhase3(ctx, &pb.EmptyMsg{}) 203 | }(i) 204 | } 205 | wg.Wait() 206 | *bb.proCnt = 0 207 | *bb.shaCnt = 0 208 | f, _ := os.OpenFile(bb.metadataPath+"/log0", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 209 | defer f.Close() 210 | fmt.Fprintf(f, "totMsgSize,%d\n", *bb.totMsgSize) 211 | *bb.totMsgSize = 0 212 | } 213 | 214 | func ReadIpList(metadataPath string) []string { 215 | ipData, err := ioutil.ReadFile(metadataPath + "/ip_list") 216 | if err != nil { 217 | log.Fatalf("bulletinboard failed to read iplist: %v", err) 218 | } 219 | return strings.Split(string(ipData), "\n") 220 | } 221 | 222 | // New returns a network node structure 223 | func New(degree int, counter int, metadataPath string) (BulletinBoard, error) { 224 | f, _ := os.Create(metadataPath + "/log0") 225 | defer f.Close() 226 | if counter < 0 { 227 | return BulletinBoard{}, errors.New(fmt.Sprintf("counter must be non-negative, got %d", counter)) 228 | } 229 | 230 | fixedRandState := rand.New(rand.NewSource(int64(3))) 231 | p := gmp.NewInt(0) 232 | p.SetString("57896044618658097711785492504343953926634992332820282019728792006155588075521", 10) 233 | dpc := commitment.DLPolyCommit{} 234 | dpc.SetupFix(counter) 235 | 236 | ipRaw := ReadIpList(metadataPath)[0 : counter+1] 237 | bip := ipRaw[0] 238 | ipList := ipRaw[1 : counter+1] 239 | 240 | proCnt := 0 241 | shaCnt := 0 242 | 243 | reconstructionContent := make([]*pb.Cmt1Msg, counter) 244 | poly, err := polyring.NewRand(degree, fixedRandState, p) 245 | if err != nil { 246 | log.Fatal("Error initializing random poly") 247 | } 248 | c := dpc.NewG1() 249 | dpc.Commit(c, poly) 250 | cBytes := c.CompressedBytes() 251 | for i := 0; i < counter; i++ { 252 | msg := &pb.Cmt1Msg{ 253 | Index: int32(i + 1), 254 | Polycmt: cBytes, 255 | } 256 | reconstructionContent[i] = msg 257 | } 258 | proactivizationContent := make([]*pb.Cmt2Msg, counter) 259 | 260 | nConn := make([]*grpc.ClientConn, counter) 261 | nClient := make([]pb.NodeServiceClient, counter) 262 | 263 | totMsgSize := 0 264 | 265 | return BulletinBoard{ 266 | metadataPath: metadataPath, 267 | counter: counter, 268 | bip: bip, 269 | ipList: ipList, 270 | proCnt: &proCnt, 271 | shaCnt: &shaCnt, 272 | reconstructionContent: reconstructionContent, 273 | proactivizationContent: proactivizationContent, 274 | nConn: nConn, 275 | nClient: nClient, 276 | totMsgSize: &totMsgSize, 277 | }, nil 278 | } 279 | -------------------------------------------------------------------------------- /src/utils/polyring/polyring_test.go: -------------------------------------------------------------------------------- 1 | package polyring 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | 7 | "github.com/ncw/gmp" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | const RAND_SEED = 1 12 | 13 | var randomness = rand.New(rand.NewSource(RAND_SEED)) 14 | 15 | func TestNew(t *testing.T) { 16 | ZERO := gmp.NewInt(0) 17 | 18 | degree := 100 19 | poly, err := New(degree) 20 | 21 | assert.Nil(t, err, "error in New") 22 | assert.Equal(t, degree+1, len(poly.coeff), "coeff len") 23 | 24 | for i := 0; i < len(poly.coeff); i++ { 25 | assert.Zero(t, poly.coeff[i].Cmp(ZERO)) 26 | } 27 | 28 | _, err = New(-1) 29 | assert.NotNil(t, err, "negative degree") 30 | } 31 | 32 | func TestNewOne(t *testing.T) { 33 | ONE := gmp.NewInt(1) 34 | 35 | onePoly := NewOne() 36 | 37 | assert.Equal(t, 0, onePoly.GetDegree(), "degree") 38 | assert.Equal(t, 1, len(onePoly.coeff), "coeff len") 39 | 40 | assert.Equal(t, 0, ONE.Cmp(onePoly.coeff[0])) 41 | } 42 | 43 | func TestNewEmpty(t *testing.T) { 44 | emptyPoly := NewEmpty() 45 | 46 | assert.Equal(t, 0, emptyPoly.GetDegree(), "degree") 47 | assert.Equal(t, int32(0), emptyPoly.GetPtrToConstant().Int32(), "const") 48 | } 49 | 50 | func TestNewRand(t *testing.T) { 51 | var degree = 100 52 | var n = gmp.NewInt(1000) 53 | 54 | r := rand.New(rand.NewSource(RAND_SEED)) 55 | poly, err := NewRand(degree, r, n) 56 | assert.Nil(t, err, "err in NewRand") 57 | 58 | assert.Equal(t, degree+1, len(poly.coeff), "coeff len") 59 | 60 | for i := range poly.coeff { 61 | assert.Equal(t, -1, poly.coeff[i].Cmp(n), "rand range") 62 | } 63 | } 64 | 65 | func TestPolynomial_ResetToDegree(t *testing.T) { 66 | op1 := FromVec(1, 1, 1, 1, 1, 1) 67 | 68 | op1.resetToDegree(100) 69 | } 70 | 71 | func TestPolynomialCap(t *testing.T) { 72 | op := FromVec(1, 1, 1, 1, 1, 1, 0, 0, 0) 73 | assert.Equal(t, 9, op.GetCap()) 74 | 75 | op.GrowCapTo(100) 76 | assert.Equal(t, 100, op.GetCap()) 77 | } 78 | 79 | func TestPolynomial_ShrinkToSize(t *testing.T) { 80 | op1 := FromVec(1, 1, 1, 1, 1, 1, 0, 0, 0) 81 | 82 | op1.shrinkToSize() 83 | 84 | assert.Equal(t, 5, op1.GetDegree()) 85 | 86 | op1 = FromVec(0, 0, 0, 0, 0) 87 | 88 | op1.shrinkToSize() 89 | 90 | assert.Equal(t, 0, op1.GetDegree()) 91 | } 92 | 93 | func TestPolynomial_Add(t *testing.T) { 94 | var degree = 10 95 | var n = gmp.NewInt(1000) 96 | 97 | poly1, err := NewRand(degree, randomness, n) 98 | assert.Nil(t, err, "err in NewRand") 99 | 100 | poly2, err := NewRand(degree, randomness, n) 101 | assert.Nil(t, err, "err in NewRand") 102 | 103 | result := NewEmpty() 104 | 105 | err = result.Add(poly1, poly2) 106 | assert.Nil(t, err, "add") 107 | 108 | var tmp = gmp.NewInt(0) 109 | for i := 0; i <= degree; i++ { 110 | tmp.Add(poly1.coeff[i], poly2.coeff[i]) 111 | assert.Zero(t, result.coeff[i].Cmp(tmp), "add result") 112 | tmp.SetInt64(0) 113 | } 114 | } 115 | 116 | func TestPolynomial_Sub(t *testing.T) { 117 | var tests = []struct { 118 | op1 []int64 119 | op2 []int64 120 | expected []int64 121 | }{ 122 | {[]int64{1, 1}, []int64{0, 1}, []int64{1}}, 123 | {[]int64{1, 1, 1}, []int64{1, 1, 1}, []int64{0}}, 124 | } 125 | 126 | for _, test := range tests { 127 | op1 := FromVec(test.op1...) 128 | op2 := FromVec(test.op2...) 129 | expected := FromVec(test.expected...) 130 | 131 | result, _ := New(op1.GetDegree()) 132 | result.Sub(op1, op2) 133 | 134 | assert.True(t, expected.IsSame(result)) 135 | } 136 | 137 | } 138 | 139 | func TestPolynomial_AddMul(t *testing.T) { 140 | var degree = 100 141 | var n = gmp.NewInt(1000) 142 | 143 | r := rand.New(rand.NewSource(RAND_SEED)) 144 | poly1, err := NewRand(degree, r, n) 145 | assert.Nil(t, err, "err in NewRand") 146 | 147 | poly2, err := NewRand(degree, r, n) 148 | assert.Nil(t, err, "err in NewRand") 149 | 150 | polyOnePlusTwo, _ := New(degree) 151 | polyOnePlusTwo.Add(poly1, poly2) 152 | 153 | poly1.AddMul(poly2, gmp.NewInt(1)) 154 | assert.True(t, poly1.IsSame(polyOnePlusTwo)) 155 | } 156 | 157 | func TestPolynomial_AddSelf(t *testing.T) { 158 | var degree = 100 159 | var n = gmp.NewInt(1000) 160 | 161 | poly1, err := NewRand(degree, randomness, n) 162 | assert.Nil(t, err, "err in NewRand") 163 | 164 | poly2, err := NewRand(degree, randomness, n) 165 | assert.Nil(t, err, "err in NewRand") 166 | 167 | // add two polys using Add 168 | result, err := New(degree) 169 | result.Add(poly1, poly2) 170 | 171 | // add two polys using AddSelf 172 | err = poly1.AddSelf(poly2) 173 | assert.Nil(t, err, "add") 174 | 175 | assert.True(t, result.IsSame(poly1), "addself") 176 | } 177 | 178 | func TestPolynomial_Mul(t *testing.T) { 179 | op1 := FromVec(1, 1, 1, 1, 1, 1) 180 | result := NewEmpty() 181 | 182 | err := result.Mul(op1, op1) 183 | assert.Nil(t, err, "Mul") 184 | 185 | expected := FromVec(1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1) 186 | assert.True(t, expected.IsSame(result), "Mul") 187 | } 188 | 189 | func TestPolynomial_MulSelf(t *testing.T) { 190 | op1 := FromVec(1, 1, 1, 1, 1, 1) 191 | 192 | poly := FromVec(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0) 193 | 194 | err := poly.MulSelf(op1) 195 | assert.Nil(t, err, "MulSelf") 196 | 197 | expected := FromVec(1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1) 198 | assert.True(t, expected.IsSame(poly), "MulSelf") 199 | } 200 | 201 | func TestPolynomial_Div2(t *testing.T) { 202 | var degree = 100 203 | 204 | var n = gmp.NewInt(1000) 205 | randPoly, err := NewRand(degree, randomness, n) 206 | assert.Nil(t, err, "NewRand") 207 | 208 | // op2(x) = x + 1 209 | op2 := FromVec(1, 1) 210 | 211 | productPoly, err := New(randPoly.GetDegree() + op2.GetDegree()) 212 | assert.Nil(t, err, "New") 213 | 214 | productPoly.Mul(randPoly, op2) 215 | 216 | result := NewEmpty() 217 | 218 | // result = randPoly / op2 219 | err = result.Div2(productPoly, op2) 220 | assert.Nil(t, err, "Div2") 221 | 222 | assert.True(t, result.IsSame(randPoly)) 223 | 224 | // test invalid input 225 | err = result.Div2(productPoly, randPoly) 226 | assert.NotNil(t, err, "Div2 only accept x-a as op2") 227 | } 228 | 229 | func TestPolynomial_GetDegree(t *testing.T) { 230 | var tests = []struct { 231 | coeffs []int64 232 | degree int 233 | }{ 234 | {[]int64{1, 1}, 1}, 235 | {[]int64{0, 1, 0}, 1}, 236 | {[]int64{0, 0}, 0}, 237 | {[]int64{1, 0, 0, 1}, 3}, 238 | } 239 | 240 | for _, test := range tests { 241 | p := FromVec(test.coeffs...) 242 | assert.Equal(t, test.degree, p.GetDegree(), "%s", test.coeffs) 243 | } 244 | } 245 | 246 | func TestPolynomial_GetCoefficient(t *testing.T) { 247 | var tests = []struct { 248 | coeffs []int64 249 | getAt int 250 | expected int64 251 | expectError bool 252 | }{ 253 | {[]int64{1, 1}, 1, 1, false}, 254 | {[]int64{0, 1, 0}, 3, 1, true}, 255 | {[]int64{0, 0}, 0, 0, false}, 256 | {[]int64{1, 0, 0, 1}, 3, 1, false}, 257 | } 258 | 259 | for _, test := range tests { 260 | p := FromVec(test.coeffs...) 261 | coeff, err := p.GetCoefficient(test.getAt) 262 | if test.expectError { 263 | assert.NotNil(t, err, p.ToString()) 264 | } else { 265 | assert.Equal(t, test.expected, coeff.Int64(), p.ToString()) 266 | } 267 | } 268 | } 269 | 270 | func TestPolynomial_EvalMod(t *testing.T) { 271 | var tests = []struct { 272 | coeffs []int64 273 | evalAt int64 274 | expected int64 275 | }{ 276 | {[]int64{1, 1}, 1, 2}, 277 | {[]int64{1, 2, 3}, 0, 1}, 278 | {[]int64{1, 2, 3}, 1, 6}, 279 | {[]int64{1, 2, 3}, 2, 17}, 280 | {[]int64{2, 2}, 0, 2}, 281 | {[]int64{1, 0, 0, 1, 0}, 3, 28}, 282 | } 283 | 284 | mod := gmp.NewInt(100) 285 | 286 | for _, test := range tests { 287 | p := FromVec(test.coeffs...) 288 | eval := gmp.NewInt(0) 289 | p.EvalMod(gmp.NewInt(test.evalAt), mod, eval) 290 | assert.Equal(t, test.expected, eval.Int64(), p.ToString()) 291 | } 292 | } 293 | 294 | func TestPolynomial_EvalModArray(t *testing.T) { 295 | var tests = []struct { 296 | coeffs []int64 297 | evalAt []int64 298 | expected []int64 299 | }{ 300 | {[]int64{1, 2, 3}, []int64{0, 1, 2}, []int64{1, 6, 17}}, 301 | } 302 | 303 | mod := gmp.NewInt(100) 304 | 305 | for _, test := range tests { 306 | p := FromVec(test.coeffs...) 307 | 308 | x := make([]*gmp.Int, len(test.evalAt)) 309 | for i, xx := range test.evalAt { 310 | x[i] = gmp.NewInt(xx) 311 | } 312 | 313 | evalResults := make([]*gmp.Int, len(test.evalAt)) 314 | VecInit(evalResults) 315 | 316 | p.EvalModArray(x, mod, evalResults) 317 | 318 | y := make([]int64, len(evalResults)) 319 | for i, yy := range evalResults { 320 | y[i] = yy.Int64() 321 | } 322 | assert.Equal(t, test.expected, y, p.ToString()) 323 | } 324 | } 325 | 326 | func TestPolynomial_GetLeadingCoefficient(t *testing.T) { 327 | var tests = []struct { 328 | coeffs []int64 329 | expected int64 330 | }{ 331 | {[]int64{1, 1}, 1}, 332 | {[]int64{1, 2, 3}, 3}, 333 | {[]int64{2, 2}, 2}, 334 | {[]int64{1, 0, 0, 1, 0}, 1}, 335 | } 336 | 337 | for _, test := range tests { 338 | p := FromVec(test.coeffs...) 339 | lc := p.GetLeadingCoefficient() 340 | assert.Equal(t, 0, gmp.NewInt(test.expected).Cmp(&lc)) 341 | } 342 | } 343 | 344 | func TestPolynomial_ResetTo(t *testing.T) { 345 | var tests = []struct { 346 | coeffs []int64 347 | expected int64 348 | }{ 349 | {[]int64{1, 1}, 7}, 350 | {[]int64{1, 2, 3}, 8}, 351 | {[]int64{2, 2}, 234}, 352 | {[]int64{1, 0, 0, 1, 0}, 12384776}, 353 | } 354 | 355 | for _, test := range tests { 356 | empty := NewEmpty() 357 | p := FromVec(test.coeffs...) 358 | empty.ResetTo(p) 359 | assert.True(t, empty.IsSame(p)) 360 | } 361 | } 362 | 363 | func TestDiv(t *testing.T) { 364 | mod := gmp.NewInt(17) 365 | 366 | // to test if q, r = DivMod(a, b) 367 | var tests = []struct { 368 | a []int64 369 | b []int64 370 | q []int64 371 | r []int64 372 | }{ 373 | {[]int64{1, 2, 1}, []int64{1, 1}, []int64{1, 1}, []int64{}}, 374 | {[]int64{7, 0, 0, 0, 2, 1}, []int64{-5, 0, 0, 1}, []int64{0, 2, 1}, []int64{7, 10, 5}}, 375 | {[]int64{7, 10, 5, 2}, []int64{4, 0, 1}, []int64{5, 2}, []int64{4, 2}}, 376 | {[]int64{1, 2, 1}, []int64{1, 2}, []int64{5, 9}, []int64{13}}, 377 | } 378 | 379 | for _, test := range tests { 380 | a := FromVec(test.a...) 381 | b := FromVec(test.b...) 382 | q := FromVec(test.q...) 383 | r := FromVec(test.r...) 384 | 385 | qq, rr := NewEmpty(), NewEmpty() 386 | err := DivMod(a, b, mod, &qq, &rr) 387 | assert.Nil(t, err, "DivMod") 388 | 389 | assert.True(t, qq.IsSame(q)) 390 | assert.True(t, rr.IsSame(r)) 391 | } 392 | } 393 | -------------------------------------------------------------------------------- /src/utils/polyring/polyring.go: -------------------------------------------------------------------------------- 1 | package polyring 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "math/rand" 7 | "strings" 8 | 9 | "github.com/ncw/gmp" 10 | ) 11 | 12 | type Polynomial struct { 13 | coeff []*gmp.Int // coefficients P(x) = coeff[0] + coeff[1] x + ... + coeff[degree] x^degree ... 14 | } 15 | 16 | // GetDegree returns the degree, ignoring removing leading zeroes 17 | func (poly Polynomial) GetDegree() int { 18 | deg := len(poly.coeff) - 1 19 | 20 | // note: i == 0 is not tested, because even the constant term is zero, we consider it's degree 0 21 | for i := deg; i > 0; i-- { 22 | if poly.coeff[i].CmpInt32(0) == 0 { 23 | deg-- 24 | } else { 25 | break 26 | } 27 | } 28 | 29 | return deg 30 | } 31 | 32 | // GetCoefficient returns coeff[i] 33 | func (poly Polynomial) GetCoefficient(i int) (gmp.Int, error) { 34 | if i < 0 || i >= len(poly.coeff) { 35 | return *gmp.NewInt(0), errors.New("out of boundary") 36 | } 37 | 38 | return *poly.coeff[i], nil 39 | } 40 | 41 | // GetAllCoeffcients returns a copy of 42 | func (poly Polynomial) GetAllCoefficients() (all []*gmp.Int) { 43 | all = make([]*gmp.Int, poly.GetDegree()+1) 44 | 45 | for i := range all { 46 | all[i] = gmp.NewInt(0) 47 | all[i] = poly.coeff[i] 48 | } 49 | 50 | return all 51 | } 52 | 53 | func (poly Polynomial) DeepCopy() Polynomial { 54 | dst, err := New(poly.GetDegree()) 55 | if err != nil { 56 | panic("deepcopy failed: " + err.Error()) 57 | } 58 | 59 | for i := 0; i < len(dst.coeff); i++ { 60 | dst.coeff[i].Set(poly.coeff[i]) 61 | } 62 | 63 | return dst 64 | } 65 | 66 | // GetLeadingCoefficient returns the coefficient of the highest degree of the variable 67 | func (poly Polynomial) GetLeadingCoefficient() gmp.Int { 68 | lc := gmp.NewInt(0) 69 | lc.Set(poly.coeff[poly.GetDegree()]) 70 | 71 | return *lc 72 | } 73 | 74 | // GetCoefficient returns a pointer to coeff[0] 75 | func (poly Polynomial) GetPtrToConstant() *gmp.Int { 76 | return poly.coeff[0] 77 | } 78 | 79 | // SetCoefficient sets the poly.coeff[i] to ci 80 | func (poly *Polynomial) SetCoefficient(i int, ci int64) error { 81 | if i < 0 || i >= len(poly.coeff) { 82 | return errors.New("out of boundary") 83 | } 84 | 85 | poly.coeff[i].SetInt64(ci) 86 | 87 | return nil 88 | } 89 | 90 | // SetCoefficientBig sets the poly.coeff[i] to ci (a gmp.Int) 91 | func (poly *Polynomial) SetCoefficientBig(i int, ci *gmp.Int) error { 92 | if i < 0 || i >= len(poly.coeff) { 93 | return errors.New("out of boundary") 94 | } 95 | 96 | poly.coeff[i].Set(ci) 97 | 98 | return nil 99 | } 100 | 101 | // Reset sets the coefficients to zeroes 102 | func (poly *Polynomial) Reset() { 103 | for i := 0; i < len(poly.coeff); i++ { 104 | poly.coeff[i].SetInt64(0) 105 | } 106 | } 107 | 108 | func (poly *Polynomial) ResetTo(other Polynomial) { 109 | poly.resetToDegree(other.GetDegree()) 110 | 111 | for i := 0; i < other.GetDegree()+1; i++ { 112 | poly.coeff[i].Set(other.coeff[i]) 113 | } 114 | } 115 | 116 | // resetToDegree resizes the slice to degree 117 | func (poly *Polynomial) resetToDegree(degree int) { 118 | // if we just need to shrink the size 119 | if degree+1 <= len(poly.coeff) { 120 | poly.coeff = poly.coeff[:degree+1] 121 | } else { 122 | // if we need to grow the slice 123 | needed := degree + 1 - len(poly.coeff) 124 | neededPointers := make([]*gmp.Int, needed) 125 | for i := 0; i < len(neededPointers); i++ { 126 | neededPointers[i] = gmp.NewInt(0) 127 | } 128 | 129 | poly.coeff = append(poly.coeff, neededPointers...) 130 | } 131 | 132 | poly.Reset() 133 | } 134 | 135 | func (poly *Polynomial) shrinkToSize() { 136 | poly.coeff = poly.coeff[:poly.GetDegree()+1] 137 | } 138 | 139 | func (poly Polynomial) GetCap() int { 140 | return len(poly.coeff) 141 | } 142 | 143 | func (poly *Polynomial) GrowCapTo(cap int) { 144 | current := poly.GetCap() 145 | if cap <= current { 146 | return 147 | } 148 | 149 | // if we need to grow the slice 150 | needed := cap - current 151 | neededPointers := make([]*gmp.Int, needed) 152 | for i := 0; i < len(neededPointers); i++ { 153 | neededPointers[i] = gmp.NewInt(0) 154 | } 155 | 156 | poly.coeff = append(poly.coeff, neededPointers...) 157 | } 158 | 159 | // New returns a polynomial P(x) = 0 with capacity degree + 1 160 | func New(degree int) (Polynomial, error) { 161 | if degree < 0 { 162 | return Polynomial{}, errors.New(fmt.Sprintf("degree must be non-negative, got %d", degree)) 163 | } 164 | 165 | coeff := make([]*gmp.Int, degree+1) 166 | 167 | for i := 0; i < len(coeff); i++ { 168 | coeff[i] = gmp.NewInt(0) 169 | } 170 | 171 | //set the leading coefficient 172 | //coeff[len(coeff) - 1].SetInt64(1) 173 | 174 | return Polynomial{coeff}, nil 175 | } 176 | 177 | // NewOne returns create a constant polynomial P(x) = c 178 | func NewConstant(c int64) Polynomial { 179 | zero, err := New(0) 180 | if err != nil { 181 | panic(err.Error()) 182 | } 183 | 184 | zero.coeff[0] = gmp.NewInt(c) 185 | return zero 186 | } 187 | 188 | // NewOne creates a constant polynomial P(x) = 1 189 | func NewOne() Polynomial { 190 | return NewConstant(1) 191 | } 192 | 193 | // NewEmpty creates a constant polynomial P(x) = 0 194 | func NewEmpty() Polynomial { 195 | return NewConstant(0) 196 | } 197 | 198 | // NewRand returns a randomized polynomial with specified degree 199 | // coefficients are pesudo-random numbers in [0, n) 200 | func NewRand(degree int, rand *rand.Rand, n *gmp.Int) (Polynomial, error) { 201 | p, e := New(degree) 202 | if e != nil { 203 | return Polynomial{}, e 204 | } 205 | 206 | p.Rand(rand, n) 207 | 208 | return p, nil 209 | } 210 | 211 | func FromVec(coeff ...int64) Polynomial { 212 | if len(coeff) == 0 { 213 | return NewConstant(0) 214 | } 215 | deg := len(coeff) - 1 216 | 217 | poly, err := New(deg) 218 | if err != nil { 219 | panic(err.Error()) 220 | } 221 | 222 | for i := range poly.coeff { 223 | poly.coeff[i].SetInt64(coeff[i]) 224 | } 225 | 226 | return poly 227 | } 228 | 229 | func FromString(s string) Polynomial { 230 | // Convert input string to slice of gmp.Int 231 | coeffStr := strings.Split(s, ";") 232 | if len(coeffStr) == 0 { 233 | return NewConstant(0) 234 | } 235 | coeff := make([]*gmp.Int, 0) 236 | for i := 0; i < len(coeffStr); i++ { 237 | tmp := gmp.NewInt(0) 238 | tmp.SetString(coeffStr[i], 10) 239 | coeff = append(coeff, tmp) 240 | } 241 | // Determine poly degree 242 | deg := len(coeff) - 1 243 | for i := len(coeff) - 1; i >= 0; i-- { 244 | if coeff[i].CmpInt32(0) != 0 { 245 | continue 246 | } 247 | deg = i 248 | } 249 | // Create and return new poly 250 | poly, err := New(deg) 251 | if err != nil { 252 | panic(err.Error()) 253 | } 254 | 255 | for i := range poly.coeff { 256 | poly.coeff[i].Set(coeff[i]) 257 | } 258 | 259 | return poly 260 | } 261 | 262 | // Rand sets the polynomial coefficients to a pseudo-random number in [0, n) 263 | // WARNING: Rand makes sure that the highest coefficient is not zero 264 | func (poly *Polynomial) Rand(rand *rand.Rand, mod *gmp.Int) { 265 | for i := range poly.coeff { 266 | poly.coeff[i].Rand(rand, mod) 267 | } 268 | 269 | highest := len(poly.coeff) - 1 270 | 271 | for { 272 | if 0 == poly.coeff[highest].CmpInt32(0) { 273 | poly.coeff[highest].Rand(rand, mod) 274 | } else { 275 | break 276 | } 277 | } 278 | 279 | } 280 | 281 | // Converts to a string representation. Can be converted back using SetString 282 | // 6 + 3x + 2x^2 => "6;3;2" 283 | func (poly Polynomial) String() string { 284 | s := "" 285 | for i, coeff := range poly.coeff { 286 | s += coeff.String() 287 | if i < len(poly.coeff)-1 { 288 | s += ";" 289 | } 290 | } 291 | return s 292 | } 293 | 294 | func (poly Polynomial) ToString() string { 295 | var s = "" 296 | 297 | for i := len(poly.coeff) - 1; i >= 0; i-- { 298 | // skip zero coefficients but the constant term 299 | if i != 0 && poly.coeff[i].CmpInt32(0) == 0 { 300 | continue 301 | } 302 | if i > 0 { 303 | s += fmt.Sprintf("%s x^%d + ", poly.coeff[i].String(), i) 304 | } else { 305 | // constant term 306 | s += fmt.Sprintf("%s", poly.coeff[i].String()) 307 | } 308 | } 309 | 310 | return s 311 | } 312 | 313 | // Print the polynomial 314 | func (poly Polynomial) Print(title ...string) { 315 | var name = "P(x)" 316 | if len(title) > 0 { 317 | name = title[0] 318 | } 319 | 320 | fmt.Printf("%s = %s\n", name, poly.ToString()) 321 | } 322 | 323 | // Print the degree 324 | func (poly Polynomial) PrintDegree(title ...string) { 325 | var name = "P(x)" 326 | if len(title) > 0 { 327 | name = title[0] 328 | } 329 | 330 | fmt.Printf("deg %s = %d\n", name, poly.GetDegree()) 331 | } 332 | 333 | // One sets the constant to one 334 | func (poly *Polynomial) One() { 335 | poly.Reset() 336 | poly.coeff[0].SetInt64(1) 337 | } 338 | 339 | // I hate Go! how can we don't have min for integers 340 | func min(a, b int) int { 341 | if a < b { 342 | return a 343 | } else { 344 | return b 345 | } 346 | } 347 | 348 | func max(a, b int) int { 349 | if a > b { 350 | return a 351 | } else { 352 | return b 353 | } 354 | } 355 | 356 | // Add sets poly to op1 + op2 357 | func (poly *Polynomial) Add(op1 Polynomial, op2 Polynomial) error { 358 | // make sure poly is as long as the longest of op1 and op2 359 | deg1 := op1.GetDegree() 360 | deg2 := op2.GetDegree() 361 | 362 | if deg1 > deg2 { 363 | poly.ResetTo(op1) 364 | } else { 365 | poly.ResetTo(op2) 366 | } 367 | 368 | for i := 0; i < min(deg1, deg2)+1; i++ { 369 | poly.coeff[i].Add(op1.coeff[i], op2.coeff[i]) 370 | } 371 | 372 | // FIXME: no need to return error 373 | return nil 374 | } 375 | 376 | // AddSelf sets poly to poly + op 377 | func (poly *Polynomial) AddSelf(op Polynomial) error { 378 | op1 := poly.DeepCopy() 379 | return poly.Add(op1, op) 380 | } 381 | 382 | // Sub sets poly to op1 - op2 383 | func (poly *Polynomial) Sub(op1 Polynomial, op2 Polynomial) error { 384 | // make sure poly is as long as the longest of op1 and op2 385 | deg1 := op1.GetDegree() 386 | deg2 := op2.GetDegree() 387 | 388 | if deg1 > deg2 { 389 | poly.ResetTo(op1) 390 | } else { 391 | poly.ResetTo(op2) 392 | } 393 | 394 | for i := 0; i < min(deg1, deg2)+1; i++ { 395 | poly.coeff[i].Sub(op1.coeff[i], op2.coeff[i]) 396 | } 397 | 398 | poly.shrinkToSize() 399 | 400 | // FIXME: no need to return error 401 | return nil 402 | } 403 | 404 | // SubSelf sets poly to poly - op 405 | func (poly *Polynomial) SubSelf(op Polynomial) error { 406 | // make sure poly is as long as the longest of op1 and op2 407 | deg1 := op.GetDegree() 408 | 409 | poly.GrowCapTo(deg1 + 1) 410 | 411 | for i := 0; i < deg1+1; i++ { 412 | poly.coeff[i].Sub(poly.coeff[i], op.coeff[i]) 413 | } 414 | 415 | poly.shrinkToSize() 416 | 417 | // FIXME: no need to return error 418 | return nil 419 | } 420 | 421 | // MulSelf set poly to op1 * op2 422 | func (poly *Polynomial) Mul(op1 Polynomial, op2 Polynomial) error { 423 | deg1 := op1.GetDegree() 424 | deg2 := op2.GetDegree() 425 | 426 | poly.resetToDegree(deg1 + deg2) 427 | 428 | for i := 0; i <= deg1; i++ { 429 | for j := 0; j <= deg2; j++ { 430 | poly.coeff[i+j].AddMul(op1.coeff[i], op2.coeff[j]) 431 | } 432 | } 433 | 434 | poly.shrinkToSize() 435 | // FIXME: no need to return 436 | return nil 437 | } 438 | 439 | // MulSelf set poly to poly * op 440 | func (poly *Polynomial) MulSelf(op Polynomial) error { 441 | op1 := poly.DeepCopy() 442 | return poly.Mul(op1, op) 443 | } 444 | 445 | // AddMul sets poly to poly + poly2 * k (k being a scalar) 446 | func (poly *Polynomial) AddMul(poly2 Polynomial, k *gmp.Int) { 447 | for i := 0; i <= poly2.GetDegree(); i++ { 448 | poly.coeff[i].AddMul(poly2.coeff[i], k) 449 | } 450 | } 451 | 452 | // DivMod sets computes q, r such that a = b*q + r. 453 | // This is an implementation of Euclidean division. The complexity is O(n^3)!! 454 | func DivMod(a Polynomial, b Polynomial, p *gmp.Int, q, r *Polynomial) (err error) { 455 | if b.IsZero() { 456 | return errors.New("divide by zero") 457 | } 458 | 459 | q.resetToDegree(0) 460 | r.ResetTo(a) 461 | 462 | d := b.GetDegree() 463 | c := b.GetLeadingCoefficient() 464 | 465 | // cInv = 1/c 466 | cInv := gmp.NewInt(0) 467 | cInv.ModInverse(&c, p) 468 | 469 | for r.GetDegree() >= d { 470 | lc := r.GetLeadingCoefficient() 471 | s, err := New(r.GetDegree() - d) 472 | if err != nil { 473 | return err 474 | } 475 | 476 | s.SetCoefficientBig(r.GetDegree()-d, lc.Mul(&lc, cInv)) 477 | 478 | q.AddSelf(s) 479 | 480 | sb := NewEmpty() 481 | sb.Mul(s, b) 482 | 483 | // deg r reduces by each iteration 484 | r.SubSelf(sb) 485 | 486 | // modulo p 487 | q.Mod(p) 488 | r.Mod(p) 489 | } 490 | 491 | return nil 492 | } 493 | 494 | // Div2 sets poly to op1 / op2. **op2 must be of format x+a ** 495 | // Complexity is O(deg1) 496 | func (poly *Polynomial) Div2(op1 Polynomial, op2 Polynomial) error { 497 | deg1 := op1.GetDegree() 498 | deg2 := op2.GetDegree() 499 | 500 | poly.resetToDegree(deg1) 501 | 502 | if deg2 != 1 { 503 | return errors.New("op2 must be of format x-a") 504 | } 505 | 506 | if poly.GetCap() < deg1-1 { 507 | return errors.New("receiver too small") 508 | } 509 | 510 | tmp := gmp.NewInt(0) 511 | 512 | inter, err := New(deg1) 513 | if err != nil { 514 | return errors.New("unknown error") 515 | } 516 | 517 | for i := 0; i <= deg1; i++ { 518 | inter.coeff[i].Set(op1.coeff[i]) 519 | } 520 | 521 | for i := deg1; i > 0; i-- { 522 | poly.coeff[i-1].Div(inter.coeff[i], op2.coeff[deg2]) 523 | for j := deg2; j >= 0; j-- { 524 | tmp.Mul(poly.coeff[i-1], op2.coeff[j]) 525 | inter.coeff[i+j-deg2].Sub(inter.coeff[i+j-deg2], tmp) 526 | } 527 | } 528 | 529 | poly.shrinkToSize() 530 | return nil 531 | } 532 | 533 | // Mod sets poly to poly % p 534 | func (poly *Polynomial) Mod(p *gmp.Int) { 535 | for i := 0; i < len(poly.coeff); i++ { 536 | poly.coeff[i].Mod(poly.coeff[i], p) 537 | } 538 | } 539 | 540 | // EvalMod returns poly(x) using Horner's rule. If p != nil, returns poly(x) mod p 541 | func (poly Polynomial) EvalMod(x *gmp.Int, p *gmp.Int, result *gmp.Int) { 542 | result.Set(poly.coeff[poly.GetDegree()]) 543 | 544 | for i := poly.GetDegree(); i >= 1; i-- { 545 | result.Mul(result, x) 546 | result.Add(result, poly.coeff[i-1]) 547 | } 548 | 549 | if p != nil { 550 | result.Mod(result, p) 551 | } 552 | } 553 | 554 | // EvalArray returns poly[x[1]], ..., poly[x[n]] 555 | func (poly Polynomial) EvalModArray(x []*gmp.Int, mod *gmp.Int, results []*gmp.Int) { 556 | for i := 0; i < len(x); i++ { 557 | poly.EvalMod(x[i], mod, results[i]) 558 | } 559 | } 560 | 561 | // IsSame returns op == poly 562 | func (poly Polynomial) IsSame(op Polynomial) bool { 563 | if op.GetDegree() != poly.GetDegree() { 564 | return false 565 | } 566 | 567 | for i := 0; i <= op.GetDegree(); i++ { 568 | if op.coeff[i].Cmp(poly.coeff[i]) != 0 { 569 | return false 570 | } 571 | } 572 | 573 | return true 574 | } 575 | 576 | // IsZero returns if poly == 0 577 | func (poly Polynomial) IsZero() bool { 578 | if poly.GetDegree() != 0 { 579 | return false 580 | } 581 | 582 | return poly.GetPtrToConstant().CmpInt32(0) == 0 583 | } 584 | 585 | func VecInit(vec []*gmp.Int) { 586 | for i := 0; i < len(vec); i++ { 587 | vec[i] = gmp.NewInt(0) 588 | } 589 | } 590 | 591 | func VecRand(vec []*gmp.Int, p *gmp.Int, rand_state *rand.Rand) { 592 | for i := 0; i < len(vec); i++ { 593 | vec[i].Rand(rand_state, p) 594 | } 595 | } 596 | 597 | func VecPrint(vec []*gmp.Int) { 598 | for i := 0; i < len(vec); i++ { 599 | fmt.Printf("%s, ", vec[i].String()) 600 | } 601 | fmt.Printf("\n") 602 | } 603 | -------------------------------------------------------------------------------- /src/networking/nodes/nodes.go: -------------------------------------------------------------------------------- 1 | package nodes 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "github.com/Nik-U/pbc" 8 | pb "github.com/bl4ck5un/ChuRP/src/services" 9 | "github.com/bl4ck5un/ChuRP/src/utils/commitment" 10 | "github.com/bl4ck5un/ChuRP/src/utils/interpolation" 11 | "github.com/bl4ck5un/ChuRP/src/utils/polypoint" 12 | "github.com/bl4ck5un/ChuRP/src/utils/polyring" 13 | "github.com/golang/protobuf/proto" 14 | "github.com/ncw/gmp" 15 | "google.golang.org/grpc" 16 | "google.golang.org/grpc/reflection" 17 | "io/ioutil" 18 | "log" 19 | "math/big" 20 | "math/rand" 21 | "net" 22 | "os" 23 | "strconv" 24 | "strings" 25 | "sync" 26 | "time" 27 | ) 28 | 29 | // Network Node Structure 30 | type Node struct { 31 | // Metadata Path 32 | metadataPath string 33 | // Basic Sharing Information 34 | // [+] Label of Node 35 | label int 36 | // [+] Number of Nodes 37 | counter int 38 | // [+] Polynomial Degree 39 | degree int 40 | // [+] Prime Defining Group Z_p 41 | p *gmp.Int 42 | 43 | // IP Information 44 | // [+] Bulletinboard IP Address 45 | bip string 46 | // [+] Node IP Address List 47 | ipList []string 48 | 49 | // Utilities 50 | // [+] Rand Source 51 | randState *rand.Rand 52 | // [+] Commitment 53 | dc *commitment.DLCommit 54 | dpc *commitment.DLPolyCommit 55 | 56 | // Sharing State 57 | // [+] Polynomial State 58 | secretShares []*polypoint.PolyPoint 59 | 60 | // Reconstruction Phase 61 | // [+] Polynomial Reconstruction State 62 | recShares []*polypoint.PolyPoint 63 | // [+] Counter of Polynomial Reconstruction State 64 | recCnt *int 65 | // [+] Mutex for everything 66 | mutex sync.Mutex 67 | // [+] Reconstructed Polynomial 68 | recPoly *polyring.Polynomial 69 | 70 | // Proactivization Phase 71 | // [+] Lagrange Coefficient 72 | lambda []*gmp.Int 73 | // [+] Zero Shares 74 | zeroShares []*gmp.Int 75 | // [+] Counter of Messages Received 76 | zeroCnt *int 77 | // [+] Zero Share 78 | zeroShare *gmp.Int 79 | // [+] Proactivization Polynomial 80 | proPoly *polyring.Polynomial 81 | // [+] Commitment & Witness in Phase 2 82 | zeroShareCmt *pbc.Element 83 | zeroPolyCmt *pbc.Element 84 | zeroPolyWit *pbc.Element 85 | 86 | // Share Distribution Phase 87 | // [+] New Poynomials 88 | newPoly *polyring.Polynomial 89 | // [+] Counter for New Secret Shares 90 | shareCnt *int 91 | 92 | // Commitment and Witness from BulletinBoard 93 | oldPolyCmt []*pbc.Element 94 | zerosumShareCmt []*pbc.Element 95 | zerosumPolyCmt []*pbc.Element 96 | zerosumPolyWit []*pbc.Element 97 | midPolyCmt []*pbc.Element 98 | newPolyCmt []*pbc.Element 99 | 100 | // Metrics 101 | totMsgSize *int 102 | s1 *time.Time 103 | e1 *time.Time 104 | s2 *time.Time 105 | e2 *time.Time 106 | s3 *time.Time 107 | e3 *time.Time 108 | 109 | // gRPC Clients and Server 110 | bConn *grpc.ClientConn 111 | nConn []*grpc.ClientConn 112 | bClient pb.BulletinBoardServiceClient 113 | nClient []pb.NodeServiceClient 114 | 115 | // Initialize Flag 116 | iniflag *bool 117 | } 118 | 119 | // Start Phase 1 120 | // Call ClientSharePhase1 to share secret shares with other nodes 121 | func (node *Node) StartPhase1(ctx context.Context, in *pb.EmptyMsg) (*pb.AckMsg, error) { 122 | log.Printf("[node %d] start phase 1", node.label) 123 | *node.s1 = time.Now() 124 | node.ClientSharePhase1() 125 | return &pb.AckMsg{}, nil 126 | } 127 | 128 | // Share Phase 1 129 | // The server function which takes the sent message of secret shares and store it locally. Then it starts ClientReadPhase1 to read the commitments of polynomials on bulletinboard. 130 | func (node *Node) SharePhase1(ctx context.Context, msg *pb.PointMsg) (*pb.AckMsg, error) { 131 | *node.totMsgSize = *node.totMsgSize + proto.Size(msg) 132 | index := msg.GetIndex() 133 | log.Printf("[node %d] receives point message from [node %d] in phase 1", node.label, index) 134 | x := msg.GetX() 135 | y := gmp.NewInt(0) 136 | y.SetBytes(msg.Y) 137 | witness := node.dpc.NewG1() 138 | witness.SetCompressedBytes(msg.Witness) 139 | p := polypoint.PolyPoint{ 140 | X: x, 141 | Y: y, 142 | PolyWit: witness, 143 | } 144 | node.mutex.Lock() 145 | node.recShares[*node.recCnt] = &p 146 | *node.recCnt = *node.recCnt + 1 147 | flag := (*node.recCnt == node.counter) 148 | node.mutex.Unlock() 149 | if flag { 150 | *node.recCnt = 0 151 | node.ClientReadPhase1() 152 | } 153 | return &pb.AckMsg{}, nil 154 | } 155 | 156 | // Share Phase 2 157 | // The server function which takes the sent message of zero shares and sum them up to get the final share and generate the proactivization polynomial according to the zero share. It then calls ClientWritePhase2 to write the commitment of zeroshare, zeropolynomial and the witness at zero on the bulletinboard. 158 | func (node *Node) SharePhase2(ctx context.Context, msg *pb.ZeroMsg) (*pb.AckMsg, error) { 159 | *node.totMsgSize = *node.totMsgSize + proto.Size(msg) 160 | index := msg.GetIndex() 161 | log.Printf("[node %d] receive zero message from [node %d] in phase 2", node.label, index) 162 | inter := gmp.NewInt(0) 163 | inter.SetBytes(msg.GetShare()) 164 | node.mutex.Lock() 165 | node.zeroShare.Add(node.zeroShare, inter) 166 | *node.zeroCnt = *node.zeroCnt + 1 167 | flag := (*node.zeroCnt == node.counter) 168 | node.mutex.Unlock() 169 | if flag { 170 | *node.zeroCnt = 0 171 | node.zeroShare.Mod(node.zeroShare, node.p) 172 | node.dc.Commit(node.zeroShareCmt, node.zeroShare) 173 | poly, _ := polyring.NewRand(node.degree, node.randState, node.p) 174 | poly.SetCoefficient(0, 0) 175 | node.dpc.Commit(node.zeroPolyCmt, poly) 176 | node.dpc.CreateWitness(node.zeroPolyWit, poly, gmp.NewInt(0)) 177 | 178 | poly.SetCoefficientBig(0, node.zeroShare) 179 | node.proPoly.ResetTo(poly.DeepCopy()) 180 | 181 | node.ClientWritePhase2() 182 | } 183 | return &pb.AckMsg{}, nil 184 | } 185 | 186 | // After the bulletinboard has received the writing of all nodes, it will start a client call to this function telling the nodes to read the commitment on it. 187 | func (node *Node) StartVerifPhase2(ctx context.Context, in *pb.EmptyMsg) (*pb.AckMsg, error) { 188 | log.Printf("[node %d] start verification in phase 2", node.label) 189 | node.ClientReadPhase2() 190 | return &pb.AckMsg{}, nil 191 | } 192 | 193 | // Share Phase 3 194 | // The server function which takes the sent message in share distribution phase and store it locally as the new secret shares. It then calls ClientWritePhase3 to write the commitment of the new polynomial on the bulletinboard. 195 | func (node *Node) SharePhase3(ctx context.Context, msg *pb.PointMsg) (*pb.AckMsg, error) { 196 | *node.totMsgSize = *node.totMsgSize + proto.Size(msg) 197 | index := msg.GetIndex() 198 | log.Printf("[node %d] receive point message from [node %d] in phase3", node.label, index) 199 | Y := msg.GetY() 200 | witness := msg.GetWitness() 201 | node.secretShares[index-1].Y.SetBytes(Y) 202 | node.secretShares[index-1].PolyWit.SetCompressedBytes(witness) 203 | node.mutex.Lock() 204 | *node.shareCnt = *node.shareCnt + 1 205 | flag := (*node.shareCnt == node.counter) 206 | node.mutex.Unlock() 207 | if flag { 208 | *node.shareCnt = 0 209 | node.ClientWritePhase3() 210 | } 211 | return &pb.AckMsg{}, nil 212 | } 213 | 214 | // After the bulletinboard receives all the writings in phase 3. It will start a client call to this function notifying the nodes to read the new commitment and verify its own shares. 215 | func (node *Node) StartVerifPhase3(ctx context.Context, in *pb.EmptyMsg) (*pb.AckMsg, error) { 216 | log.Printf("[node %d] start verification in phase 3", node.label) 217 | node.ClientReadPhase3() 218 | return &pb.AckMsg{}, nil 219 | } 220 | 221 | func (node *Node) Connect() { 222 | bConn, err := grpc.Dial(node.bip, grpc.WithInsecure()) 223 | if err != nil { 224 | log.Fatalf("node did not connect to bulletinboard: %v", err) 225 | } 226 | node.bConn = bConn 227 | node.bClient = pb.NewBulletinBoardServiceClient(node.bConn) 228 | for i := 0; i < node.counter; i++ { 229 | if i != node.label-1 { 230 | nConn, err := grpc.Dial(node.ipList[i], grpc.WithInsecure()) 231 | if err != nil { 232 | log.Fatalf("node did not connect to node: %v", err) 233 | } 234 | node.nConn[i] = nConn 235 | node.nClient[i] = pb.NewNodeServiceClient(nConn) 236 | } 237 | } 238 | } 239 | 240 | func (node *Node) Disconnect() { 241 | node.bConn.Close() 242 | for i := 0; i < node.counter; i++ { 243 | if i != node.label-1 { 244 | node.nConn[i].Close() 245 | } 246 | } 247 | } 248 | 249 | func (node *Node) Serve(aws bool) { 250 | port := node.ipList[node.label-1] 251 | if aws { 252 | port = "0.0.0.0:12001" 253 | } 254 | lis, err := net.Listen("tcp", port) 255 | if err != nil { 256 | log.Fatalf("node failed to listen %v", err) 257 | } 258 | s := grpc.NewServer() 259 | pb.RegisterNodeServiceServer(s, node) 260 | reflection.Register(s) 261 | log.Printf("node %d serve on %s", node.label, port) 262 | if err := s.Serve(lis); err != nil { 263 | log.Fatalf("node failed to serve %v", err) 264 | } 265 | } 266 | 267 | // The function that starts client calls to all other nodes to send the secret shares. 268 | func (node *Node) ClientSharePhase1() { 269 | if *node.iniflag { 270 | node.Connect() 271 | *node.iniflag = false 272 | } 273 | p := polypoint.PolyPoint{ 274 | X: node.secretShares[node.label-1].X, 275 | Y: node.secretShares[node.label-1].Y, 276 | PolyWit: node.secretShares[node.label-1].PolyWit, 277 | } 278 | // Race Condition Here 279 | node.mutex.Lock() 280 | node.recShares[*node.recCnt] = &p 281 | *node.recCnt = *node.recCnt + 1 282 | flag := (*node.recCnt == node.counter) 283 | node.mutex.Unlock() 284 | if flag { 285 | *node.recCnt = 0 286 | node.ClientReadPhase1() 287 | } 288 | var wg sync.WaitGroup 289 | for i := 0; i < node.counter; i++ { 290 | if i != node.label-1 { 291 | log.Printf("[node %d] send point message to [node %d] in phase 1", node.label, i+1) 292 | x := node.secretShares[i].X 293 | y := node.secretShares[i].Y.Bytes() 294 | witness := node.secretShares[i].PolyWit.CompressedBytes() 295 | msg := &pb.PointMsg{ 296 | X: x, 297 | Y: y, 298 | Witness: witness, 299 | } 300 | wg.Add(1) 301 | go func(i int, msg *pb.PointMsg) { 302 | defer wg.Done() 303 | ctx, cancel := context.WithCancel(context.Background()) 304 | defer cancel() 305 | node.nClient[i].SharePhase1(ctx, msg) 306 | }(i, msg) 307 | } 308 | } 309 | wg.Wait() 310 | } 311 | 312 | // Read from the bulletinboard and does the interpolation and verifiication. 313 | func (node *Node) ClientReadPhase1() { 314 | if *node.iniflag { 315 | node.Connect() 316 | *node.iniflag = false 317 | } 318 | log.Printf("[node %d] read bulletinboard in phase 1", node.label) 319 | ctx, cancel := context.WithCancel(context.Background()) 320 | defer cancel() 321 | stream, err := node.bClient.ReadPhase1(ctx, &pb.EmptyMsg{}) 322 | if err != nil { 323 | log.Fatalf("client failed to read phase1: %v", err) 324 | } 325 | for i := 0; i < node.counter; i++ { 326 | msg, err := stream.Recv() 327 | *node.totMsgSize = *node.totMsgSize + proto.Size(msg) 328 | if err != nil { 329 | log.Fatalf("client failed to receive in read phase1: %v", err) 330 | } 331 | index := msg.GetIndex() 332 | polycmt := msg.GetPolycmt() 333 | node.oldPolyCmt[index-1].SetCompressedBytes(polycmt) 334 | } 335 | x := make([]*gmp.Int, 0) 336 | y := make([]*gmp.Int, 0) 337 | polyCmt := node.dpc.NewG1() 338 | polyCmt.Set(node.oldPolyCmt[node.label-1]) 339 | for i := 0; i <= node.degree; i++ { 340 | point := node.recShares[i] 341 | x = append(x, gmp.NewInt(int64(point.X))) 342 | y = append(y, point.Y) 343 | if !node.dpc.VerifyEval(polyCmt, gmp.NewInt(int64(point.X)), point.Y, point.PolyWit) { 344 | panic("Reconstruction Verification failed") 345 | } 346 | } 347 | poly, err := interpolation.LagrangeInterpolate(node.degree, x, y, node.p) 348 | if err != nil { 349 | for i := 0; i < len(x); i++ { 350 | log.Print(x[i]) 351 | log.Print(y[i]) 352 | } 353 | log.Print(err) 354 | panic("Interpolation failed") 355 | } 356 | node.recPoly.ResetTo(poly) 357 | *node.e1 = time.Now() 358 | *node.s2 = time.Now() 359 | node.ClientSharePhase2() 360 | } 361 | 362 | // The function that really does the work of generating and sending zero shares. 363 | func (node *Node) ClientSharePhase2() { 364 | // Generate Random Numbers 365 | for i := 0; i < node.counter-1; i++ { 366 | node.zeroShares[i].Rand(node.randState, gmp.NewInt(10)) 367 | inter := gmp.NewInt(0) 368 | inter.Mul(node.zeroShares[i], node.lambda[i]) 369 | node.zeroShares[node.counter-1].Sub(node.zeroShares[node.counter-1], inter) 370 | } 371 | node.zeroShares[node.counter-1].Mod(node.zeroShares[node.counter-1], node.p) 372 | inter := gmp.NewInt(0) 373 | inter.ModInverse(node.lambda[node.counter-1], node.p) 374 | node.zeroShares[node.counter-1].Mul(node.zeroShares[node.counter-1], inter) 375 | node.zeroShares[node.counter-1].Mod(node.zeroShares[node.counter-1], node.p) 376 | node.mutex.Lock() 377 | node.zeroShare.Add(node.zeroShare, node.zeroShares[node.label-1]) 378 | *node.zeroCnt = *node.zeroCnt + 1 379 | flag := (*node.zeroCnt == node.counter) 380 | node.mutex.Unlock() 381 | if flag { 382 | *node.zeroCnt = 0 383 | node.zeroShare.Mod(node.zeroShare, node.p) 384 | node.dc.Commit(node.zeroShareCmt, node.zeroShare) 385 | poly, _ := polyring.NewRand(node.degree, node.randState, node.p) 386 | poly.SetCoefficient(0, 0) 387 | node.dpc.Commit(node.zeroPolyCmt, poly) 388 | node.dpc.CreateWitness(node.zeroPolyWit, poly, gmp.NewInt(0)) 389 | 390 | poly.SetCoefficientBig(0, node.zeroShare) 391 | node.proPoly.ResetTo(poly.DeepCopy()) 392 | node.ClientWritePhase2() 393 | } 394 | var wg sync.WaitGroup 395 | for i := 0; i < node.counter; i++ { 396 | if i != node.label-1 { 397 | log.Printf("[node %d] send message to [node %d] in phase 2", node.label, i+1) 398 | msg := &pb.ZeroMsg{ 399 | Index: int32(node.label), 400 | Share: node.zeroShares[i].Bytes(), 401 | } 402 | wg.Add(1) 403 | go func(i int, msg *pb.ZeroMsg) { 404 | defer wg.Done() 405 | ctx, cancel := context.WithCancel(context.Background()) 406 | defer cancel() 407 | node.nClient[i].SharePhase2(ctx, msg) 408 | }(i, msg) 409 | } 410 | } 411 | wg.Wait() 412 | } 413 | 414 | func (node *Node) ClientWritePhase2() { 415 | log.Printf("[node %d] write bulletinboard in phase 2", node.label) 416 | ctx, cancel := context.WithCancel(context.Background()) 417 | defer cancel() 418 | msg := &pb.Cmt2Msg{ 419 | Index: int32(node.label), 420 | Sharecmt: node.zeroShareCmt.CompressedBytes(), 421 | Polycmt: node.zeroPolyCmt.CompressedBytes(), 422 | Zerowitness: node.zeroPolyWit.CompressedBytes(), 423 | } 424 | node.bClient.WritePhase2(ctx, msg) 425 | } 426 | 427 | // Read from bulletinboard and does the verification in phase 2. 428 | func (node *Node) ClientReadPhase2() { 429 | log.Printf("[node %d] read bulletinboard in phase 2", node.label) 430 | ctx, cancel := context.WithCancel(context.Background()) 431 | defer cancel() 432 | stream, err := node.bClient.ReadPhase2(ctx, &pb.EmptyMsg{}) 433 | if err != nil { 434 | log.Fatalf("client failed to read phase2: %v", err) 435 | } 436 | for i := 0; i < node.counter; i++ { 437 | msg, err := stream.Recv() 438 | *node.totMsgSize = *node.totMsgSize + proto.Size(msg) 439 | if err != nil { 440 | log.Fatalf("client failed to receive in read phase1: %v", err) 441 | } 442 | index := msg.GetIndex() 443 | sharecmt := msg.GetSharecmt() 444 | polycmt := msg.GetPolycmt() 445 | zerowitness := msg.GetZerowitness() 446 | node.zerosumShareCmt[index-1].SetCompressedBytes(sharecmt) 447 | inter := node.dpc.NewG1() 448 | inter.SetString(node.zerosumShareCmt[index-1].String(), 10) 449 | node.zerosumPolyCmt[index-1].SetCompressedBytes(polycmt) 450 | node.midPolyCmt[index-1].Mul(inter, node.zerosumPolyCmt[index-1]) 451 | node.zerosumPolyWit[index-1].SetCompressedBytes(zerowitness) 452 | } 453 | exponentSum := node.dc.NewG1() 454 | exponentSum.Set1() 455 | for i := 0; i < node.counter; i++ { 456 | lambda := big.NewInt(0) 457 | lambda.SetString(node.lambda[i].String(), 10) 458 | tmp := node.dc.NewG1() 459 | tmp.PowBig(node.zerosumShareCmt[i], lambda) 460 | // log.Printf("label: %d #share %d\nlambda %s\nzeroshareCmt %s\ntmp %s", node.label, i+1, lambda.String(), node.zerosumShareCmt[i].String(), tmp.String()) 461 | exponentSum.Mul(exponentSum, tmp) 462 | } 463 | // log.Printf("%d exponentSum: %s", node.label, exponentSum.String()) 464 | if !exponentSum.Is1() { 465 | panic("Proactivization Verification 1 failed") 466 | } 467 | flag := true 468 | for i := 0; i < node.counter; i++ { 469 | if !node.dpc.VerifyEval(node.zerosumPolyCmt[i], gmp.NewInt(0), gmp.NewInt(0), node.zerosumPolyWit[i]) { 470 | flag = false 471 | } 472 | } 473 | if !flag { 474 | panic("Proactivization Verification 2 failed") 475 | } 476 | *node.e2 = time.Now() 477 | *node.s3 = time.Now() 478 | node.ClientSharePhase3() 479 | } 480 | 481 | // The function that does the real work of sending new secret shares to all nodes. 482 | func (node *Node) ClientSharePhase3() { 483 | node.newPoly.Add(*node.recPoly, *node.proPoly) 484 | var wg sync.WaitGroup 485 | for i := 0; i < node.counter; i++ { 486 | eval := gmp.NewInt(0) 487 | node.newPoly.EvalMod(gmp.NewInt(int64(i+1)), node.p, eval) 488 | witness := node.dpc.NewG1() 489 | node.dpc.CreateWitness(witness, *node.newPoly, gmp.NewInt(int64(i+1))) 490 | if i != node.label-1 { 491 | log.Printf("[node %d] send point message to [node %d] in phase 3", node.label, i+1) 492 | msg := &pb.PointMsg{ 493 | Index: int32(node.label), 494 | X: int32(i + 1), 495 | Y: eval.Bytes(), 496 | Witness: witness.CompressedBytes(), 497 | } 498 | wg.Add(1) 499 | go func(i int, msg *pb.PointMsg) { 500 | ctx, cancel := context.WithCancel(context.Background()) 501 | defer cancel() 502 | defer wg.Done() 503 | node.nClient[i].SharePhase3(ctx, msg) 504 | }(i, msg) 505 | } else { 506 | node.secretShares[i].Y.Set(eval) 507 | node.secretShares[i].PolyWit.Set(witness) 508 | node.mutex.Lock() 509 | *node.shareCnt = *node.shareCnt + 1 510 | flag := (*node.shareCnt == node.counter) 511 | node.mutex.Unlock() 512 | if flag { 513 | *node.shareCnt = 0 514 | node.ClientWritePhase3() 515 | } 516 | } 517 | } 518 | } 519 | 520 | func (node *Node) ClientWritePhase3() { 521 | log.Printf("[node %d] write bulletinboard in phase 3", node.label) 522 | ctx, cancel := context.WithCancel(context.Background()) 523 | defer cancel() 524 | C := node.dpc.NewG1() 525 | node.dpc.Commit(C, *node.newPoly) 526 | msg := &pb.Cmt1Msg{ 527 | Index: int32(node.label), 528 | Polycmt: C.CompressedBytes(), 529 | } 530 | node.bClient.WritePhase3(ctx, msg) 531 | } 532 | 533 | // Read from the bulletinboard and do the verification in phase 3. 534 | func (node *Node) ClientReadPhase3() { 535 | log.Printf("[node %d] read bulletinboard in phase 3", node.label) 536 | ctx, cancel := context.WithCancel(context.Background()) 537 | defer cancel() 538 | stream, err := node.bClient.ReadPhase3(ctx, &pb.EmptyMsg{}) 539 | if err != nil { 540 | log.Fatalf("client failed to read phase3: %v", err) 541 | } 542 | for i := 0; i < node.counter; i++ { 543 | msg, err := stream.Recv() 544 | *node.totMsgSize = *node.totMsgSize + proto.Size(msg) 545 | if err != nil { 546 | log.Fatalf("client failed to receive in read phase1: %v", err) 547 | } 548 | index := msg.GetIndex() 549 | polycmt := msg.GetPolycmt() 550 | node.newPolyCmt[index-1].SetCompressedBytes(polycmt) 551 | } 552 | for i := 0; i < node.counter; i++ { 553 | tmp := node.dpc.NewG1() 554 | if !node.newPolyCmt[i].Equals(tmp.Mul(node.oldPolyCmt[i], node.midPolyCmt[i])) { 555 | panic("Share Distribution Verification 1 failed") 556 | } 557 | if !node.dpc.VerifyEval(node.newPolyCmt[i], gmp.NewInt(int64(node.label)), node.secretShares[i].Y, node.secretShares[i].PolyWit) { 558 | panic("Share Distribution Verification 2 failed") 559 | } 560 | 561 | } 562 | *node.e3 = time.Now() 563 | f, _ := os.OpenFile(node.metadataPath+"/log"+strconv.Itoa(node.label), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 564 | defer f.Close() 565 | fmt.Fprintf(f, "totMsgSize,%d\n", *node.totMsgSize) 566 | fmt.Fprintf(f, "epochLatency,%d\n", node.e3.Sub(*node.s1).Nanoseconds()) 567 | fmt.Fprintf(f, "reconstructionLatency,%d\n", node.e1.Sub(*node.s1).Nanoseconds()) 568 | fmt.Fprintf(f, "proactivizationLatency,%d\n", node.e2.Sub(*node.s2).Nanoseconds()) 569 | fmt.Fprintf(f, "sharedistLatency,%d\n", node.e3.Sub(*node.s3).Nanoseconds()) 570 | *node.totMsgSize = 0 571 | for i := 0; i < node.counter; i++ { 572 | node.zeroShares[i].SetInt64(0) 573 | } 574 | node.zeroShare.SetInt64(0) 575 | } 576 | 577 | func ReadIpList(metadataPath string) []string { 578 | ipData, err := ioutil.ReadFile(metadataPath + "/ip_list") 579 | if err != nil { 580 | log.Fatalf("node failed to read iplist %v\n", err) 581 | } 582 | return strings.Split(string(ipData), "\n") 583 | } 584 | 585 | // New a Network Node Structure 586 | func New(degree int, label int, counter int, metadataPath string) (Node, error) { 587 | f, _ := os.Create(metadataPath + "/log" + strconv.Itoa(label)) 588 | defer f.Close() 589 | 590 | ipRaw := ReadIpList(metadataPath)[0 : counter+1] 591 | bip := ipRaw[0] 592 | ipList := ipRaw[1 : counter+1] 593 | 594 | if label < 0 { 595 | return Node{}, errors.New(fmt.Sprintf("label must be non-negative, got %d", label)) 596 | } 597 | 598 | if counter < 0 { 599 | return Node{}, errors.New(fmt.Sprintf("counter must be non-negtive, got %d", counter)) 600 | } 601 | 602 | randState := rand.New(rand.NewSource(time.Now().UTC().UnixNano())) 603 | fixedRandState := rand.New(rand.NewSource(int64(3))) 604 | dc := commitment.DLCommit{} 605 | dc.SetupFix() 606 | dpc := commitment.DLPolyCommit{} 607 | dpc.SetupFix(counter) 608 | 609 | p := gmp.NewInt(0) 610 | p.SetString("57896044618658097711785492504343953926634992332820282019728792006155588075521", 10) 611 | lambda := make([]*gmp.Int, counter) 612 | // Calculate Lagrange Interpolation 613 | denominator := polyring.NewOne() 614 | tmp, _ := polyring.New(1) 615 | tmp.SetCoefficient(1, 1) 616 | for i := 0; i < counter; i++ { 617 | tmp.GetPtrToConstant().Neg(gmp.NewInt(int64(i + 1))) 618 | denominator.MulSelf(tmp) 619 | } 620 | for i := 0; i < counter; i++ { 621 | lambda[i] = gmp.NewInt(0) 622 | deno, _ := polyring.New(0) 623 | tmp.GetPtrToConstant().Neg(gmp.NewInt(int64(i + 1))) 624 | deno.Div2(denominator, tmp) 625 | deno.EvalMod(gmp.NewInt(0), p, lambda[i]) 626 | inter := gmp.NewInt(0) 627 | deno.EvalMod(gmp.NewInt(int64(i+1)), p, inter) 628 | interInv := gmp.NewInt(0) 629 | interInv.ModInverse(inter, p) 630 | lambda[i].Mul(lambda[i], interInv) 631 | lambda[i].Mod(lambda[i], p) 632 | } 633 | 634 | zeroShares := make([]*gmp.Int, counter) 635 | for i := 0; i < counter; i++ { 636 | zeroShares[i] = gmp.NewInt(0) 637 | } 638 | zeroCnt := 0 639 | zeroShare := gmp.NewInt(0) 640 | 641 | recShares := make([]*polypoint.PolyPoint, counter) 642 | recCnt := 0 643 | 644 | secretShares := make([]*polypoint.PolyPoint, counter) 645 | poly, err := polyring.NewRand(degree, fixedRandState, p) 646 | for i := 0; i < counter; i++ { 647 | if err != nil { 648 | panic("Error initializing random poly") 649 | } 650 | x := int32(label) 651 | y := gmp.NewInt(0) 652 | w := dpc.NewG1() 653 | poly.EvalMod(gmp.NewInt(int64(x)), p, y) 654 | dpc.CreateWitness(w, poly, gmp.NewInt(int64(x))) 655 | secretShares[i] = polypoint.NewPoint(x, y, w) 656 | } 657 | 658 | proPoly, _ := polyring.New(degree) 659 | recPoly, _ := polyring.New(degree) 660 | newPoly, _ := polyring.New(degree) 661 | shareCnt := 0 662 | 663 | oldPolyCmt := make([]*pbc.Element, counter) 664 | midPolyCmt := make([]*pbc.Element, counter) 665 | newPolyCmt := make([]*pbc.Element, counter) 666 | for i := 0; i < counter; i++ { 667 | oldPolyCmt[i] = dpc.NewG1() 668 | midPolyCmt[i] = dpc.NewG1() 669 | newPolyCmt[i] = dpc.NewG1() 670 | } 671 | 672 | zeroShareCmt := dc.NewG1() 673 | zeroPolyCmt := dpc.NewG1() 674 | zeroPolyWit := dpc.NewG1() 675 | 676 | zerosumShareCmt := make([]*pbc.Element, counter) 677 | zerosumPolyCmt := make([]*pbc.Element, counter) 678 | zerosumPolyWit := make([]*pbc.Element, counter) 679 | 680 | for i := 0; i < counter; i++ { 681 | zerosumShareCmt[i] = dc.NewG1() 682 | zerosumPolyCmt[i] = dpc.NewG1() 683 | zerosumPolyWit[i] = dpc.NewG1() 684 | } 685 | 686 | totMsgSize := 0 687 | s1 := time.Now() 688 | e1 := time.Now() 689 | s2 := time.Now() 690 | e2 := time.Now() 691 | s3 := time.Now() 692 | e3 := time.Now() 693 | 694 | nConn := make([]*grpc.ClientConn, counter) 695 | nClient := make([]pb.NodeServiceClient, counter) 696 | 697 | iniflag := true 698 | return Node{ 699 | metadataPath: metadataPath, 700 | bip: bip, 701 | ipList: ipList, 702 | degree: degree, 703 | label: label, 704 | counter: counter, 705 | randState: randState, 706 | dc: &dc, 707 | dpc: &dpc, 708 | p: p, 709 | lambda: lambda, 710 | zeroShares: zeroShares, 711 | zeroCnt: &zeroCnt, 712 | zeroShare: zeroShare, 713 | secretShares: secretShares, 714 | recShares: recShares, 715 | recCnt: &recCnt, 716 | recPoly: &recPoly, 717 | proPoly: &proPoly, 718 | newPoly: &newPoly, 719 | shareCnt: &shareCnt, 720 | oldPolyCmt: oldPolyCmt, 721 | midPolyCmt: midPolyCmt, 722 | newPolyCmt: newPolyCmt, 723 | zeroShareCmt: zeroShareCmt, 724 | zeroPolyCmt: zeroPolyCmt, 725 | zeroPolyWit: zeroPolyWit, 726 | zerosumShareCmt: zerosumShareCmt, 727 | zerosumPolyCmt: zerosumPolyCmt, 728 | zerosumPolyWit: zerosumPolyWit, 729 | totMsgSize: &totMsgSize, 730 | s1: &s1, 731 | e1: &e1, 732 | s2: &s2, 733 | e2: &e2, 734 | s3: &s3, 735 | e3: &e3, 736 | nConn: nConn, 737 | nClient: nClient, 738 | iniflag: &iniflag, 739 | }, nil 740 | } 741 | -------------------------------------------------------------------------------- /src/services/services.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: services.proto 3 | 4 | package services 5 | 6 | import ( 7 | context "context" 8 | fmt "fmt" 9 | proto "github.com/golang/protobuf/proto" 10 | grpc "google.golang.org/grpc" 11 | math "math" 12 | ) 13 | 14 | // Reference imports to suppress errors if they are not otherwise used. 15 | var _ = proto.Marshal 16 | var _ = fmt.Errorf 17 | var _ = math.Inf 18 | 19 | // This is a compile-time assertion to ensure that this generated file 20 | // is compatible with the proto package it is being compiled against. 21 | // A compilation error at this line likely means your copy of the 22 | // proto package needs to be updated. 23 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 24 | 25 | type EmptyMsg struct { 26 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 27 | XXX_unrecognized []byte `json:"-"` 28 | XXX_sizecache int32 `json:"-"` 29 | } 30 | 31 | func (m *EmptyMsg) Reset() { *m = EmptyMsg{} } 32 | func (m *EmptyMsg) String() string { return proto.CompactTextString(m) } 33 | func (*EmptyMsg) ProtoMessage() {} 34 | func (*EmptyMsg) Descriptor() ([]byte, []int) { 35 | return fileDescriptor_8e16ccb8c5307b32, []int{0} 36 | } 37 | 38 | func (m *EmptyMsg) XXX_Unmarshal(b []byte) error { 39 | return xxx_messageInfo_EmptyMsg.Unmarshal(m, b) 40 | } 41 | func (m *EmptyMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 42 | return xxx_messageInfo_EmptyMsg.Marshal(b, m, deterministic) 43 | } 44 | func (m *EmptyMsg) XXX_Merge(src proto.Message) { 45 | xxx_messageInfo_EmptyMsg.Merge(m, src) 46 | } 47 | func (m *EmptyMsg) XXX_Size() int { 48 | return xxx_messageInfo_EmptyMsg.Size(m) 49 | } 50 | func (m *EmptyMsg) XXX_DiscardUnknown() { 51 | xxx_messageInfo_EmptyMsg.DiscardUnknown(m) 52 | } 53 | 54 | var xxx_messageInfo_EmptyMsg proto.InternalMessageInfo 55 | 56 | type AckMsg struct { 57 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 58 | XXX_unrecognized []byte `json:"-"` 59 | XXX_sizecache int32 `json:"-"` 60 | } 61 | 62 | func (m *AckMsg) Reset() { *m = AckMsg{} } 63 | func (m *AckMsg) String() string { return proto.CompactTextString(m) } 64 | func (*AckMsg) ProtoMessage() {} 65 | func (*AckMsg) Descriptor() ([]byte, []int) { 66 | return fileDescriptor_8e16ccb8c5307b32, []int{1} 67 | } 68 | 69 | func (m *AckMsg) XXX_Unmarshal(b []byte) error { 70 | return xxx_messageInfo_AckMsg.Unmarshal(m, b) 71 | } 72 | func (m *AckMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 73 | return xxx_messageInfo_AckMsg.Marshal(b, m, deterministic) 74 | } 75 | func (m *AckMsg) XXX_Merge(src proto.Message) { 76 | xxx_messageInfo_AckMsg.Merge(m, src) 77 | } 78 | func (m *AckMsg) XXX_Size() int { 79 | return xxx_messageInfo_AckMsg.Size(m) 80 | } 81 | func (m *AckMsg) XXX_DiscardUnknown() { 82 | xxx_messageInfo_AckMsg.DiscardUnknown(m) 83 | } 84 | 85 | var xxx_messageInfo_AckMsg proto.InternalMessageInfo 86 | 87 | type Cmt1Msg struct { 88 | Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` 89 | Polycmt []byte `protobuf:"bytes,2,opt,name=polycmt,proto3" json:"polycmt,omitempty"` 90 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 91 | XXX_unrecognized []byte `json:"-"` 92 | XXX_sizecache int32 `json:"-"` 93 | } 94 | 95 | func (m *Cmt1Msg) Reset() { *m = Cmt1Msg{} } 96 | func (m *Cmt1Msg) String() string { return proto.CompactTextString(m) } 97 | func (*Cmt1Msg) ProtoMessage() {} 98 | func (*Cmt1Msg) Descriptor() ([]byte, []int) { 99 | return fileDescriptor_8e16ccb8c5307b32, []int{2} 100 | } 101 | 102 | func (m *Cmt1Msg) XXX_Unmarshal(b []byte) error { 103 | return xxx_messageInfo_Cmt1Msg.Unmarshal(m, b) 104 | } 105 | func (m *Cmt1Msg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 106 | return xxx_messageInfo_Cmt1Msg.Marshal(b, m, deterministic) 107 | } 108 | func (m *Cmt1Msg) XXX_Merge(src proto.Message) { 109 | xxx_messageInfo_Cmt1Msg.Merge(m, src) 110 | } 111 | func (m *Cmt1Msg) XXX_Size() int { 112 | return xxx_messageInfo_Cmt1Msg.Size(m) 113 | } 114 | func (m *Cmt1Msg) XXX_DiscardUnknown() { 115 | xxx_messageInfo_Cmt1Msg.DiscardUnknown(m) 116 | } 117 | 118 | var xxx_messageInfo_Cmt1Msg proto.InternalMessageInfo 119 | 120 | func (m *Cmt1Msg) GetIndex() int32 { 121 | if m != nil { 122 | return m.Index 123 | } 124 | return 0 125 | } 126 | 127 | func (m *Cmt1Msg) GetPolycmt() []byte { 128 | if m != nil { 129 | return m.Polycmt 130 | } 131 | return nil 132 | } 133 | 134 | type Cmt2Msg struct { 135 | Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` 136 | Sharecmt []byte `protobuf:"bytes,2,opt,name=sharecmt,proto3" json:"sharecmt,omitempty"` 137 | Polycmt []byte `protobuf:"bytes,3,opt,name=polycmt,proto3" json:"polycmt,omitempty"` 138 | Zerowitness []byte `protobuf:"bytes,4,opt,name=zerowitness,proto3" json:"zerowitness,omitempty"` 139 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 140 | XXX_unrecognized []byte `json:"-"` 141 | XXX_sizecache int32 `json:"-"` 142 | } 143 | 144 | func (m *Cmt2Msg) Reset() { *m = Cmt2Msg{} } 145 | func (m *Cmt2Msg) String() string { return proto.CompactTextString(m) } 146 | func (*Cmt2Msg) ProtoMessage() {} 147 | func (*Cmt2Msg) Descriptor() ([]byte, []int) { 148 | return fileDescriptor_8e16ccb8c5307b32, []int{3} 149 | } 150 | 151 | func (m *Cmt2Msg) XXX_Unmarshal(b []byte) error { 152 | return xxx_messageInfo_Cmt2Msg.Unmarshal(m, b) 153 | } 154 | func (m *Cmt2Msg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 155 | return xxx_messageInfo_Cmt2Msg.Marshal(b, m, deterministic) 156 | } 157 | func (m *Cmt2Msg) XXX_Merge(src proto.Message) { 158 | xxx_messageInfo_Cmt2Msg.Merge(m, src) 159 | } 160 | func (m *Cmt2Msg) XXX_Size() int { 161 | return xxx_messageInfo_Cmt2Msg.Size(m) 162 | } 163 | func (m *Cmt2Msg) XXX_DiscardUnknown() { 164 | xxx_messageInfo_Cmt2Msg.DiscardUnknown(m) 165 | } 166 | 167 | var xxx_messageInfo_Cmt2Msg proto.InternalMessageInfo 168 | 169 | func (m *Cmt2Msg) GetIndex() int32 { 170 | if m != nil { 171 | return m.Index 172 | } 173 | return 0 174 | } 175 | 176 | func (m *Cmt2Msg) GetSharecmt() []byte { 177 | if m != nil { 178 | return m.Sharecmt 179 | } 180 | return nil 181 | } 182 | 183 | func (m *Cmt2Msg) GetPolycmt() []byte { 184 | if m != nil { 185 | return m.Polycmt 186 | } 187 | return nil 188 | } 189 | 190 | func (m *Cmt2Msg) GetZerowitness() []byte { 191 | if m != nil { 192 | return m.Zerowitness 193 | } 194 | return nil 195 | } 196 | 197 | type PointMsg struct { 198 | Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` 199 | X int32 `protobuf:"varint,2,opt,name=x,proto3" json:"x,omitempty"` 200 | Y []byte `protobuf:"bytes,3,opt,name=y,proto3" json:"y,omitempty"` 201 | Witness []byte `protobuf:"bytes,4,opt,name=witness,proto3" json:"witness,omitempty"` 202 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 203 | XXX_unrecognized []byte `json:"-"` 204 | XXX_sizecache int32 `json:"-"` 205 | } 206 | 207 | func (m *PointMsg) Reset() { *m = PointMsg{} } 208 | func (m *PointMsg) String() string { return proto.CompactTextString(m) } 209 | func (*PointMsg) ProtoMessage() {} 210 | func (*PointMsg) Descriptor() ([]byte, []int) { 211 | return fileDescriptor_8e16ccb8c5307b32, []int{4} 212 | } 213 | 214 | func (m *PointMsg) XXX_Unmarshal(b []byte) error { 215 | return xxx_messageInfo_PointMsg.Unmarshal(m, b) 216 | } 217 | func (m *PointMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 218 | return xxx_messageInfo_PointMsg.Marshal(b, m, deterministic) 219 | } 220 | func (m *PointMsg) XXX_Merge(src proto.Message) { 221 | xxx_messageInfo_PointMsg.Merge(m, src) 222 | } 223 | func (m *PointMsg) XXX_Size() int { 224 | return xxx_messageInfo_PointMsg.Size(m) 225 | } 226 | func (m *PointMsg) XXX_DiscardUnknown() { 227 | xxx_messageInfo_PointMsg.DiscardUnknown(m) 228 | } 229 | 230 | var xxx_messageInfo_PointMsg proto.InternalMessageInfo 231 | 232 | func (m *PointMsg) GetIndex() int32 { 233 | if m != nil { 234 | return m.Index 235 | } 236 | return 0 237 | } 238 | 239 | func (m *PointMsg) GetX() int32 { 240 | if m != nil { 241 | return m.X 242 | } 243 | return 0 244 | } 245 | 246 | func (m *PointMsg) GetY() []byte { 247 | if m != nil { 248 | return m.Y 249 | } 250 | return nil 251 | } 252 | 253 | func (m *PointMsg) GetWitness() []byte { 254 | if m != nil { 255 | return m.Witness 256 | } 257 | return nil 258 | } 259 | 260 | type ZeroMsg struct { 261 | Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` 262 | Share []byte `protobuf:"bytes,2,opt,name=share,proto3" json:"share,omitempty"` 263 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 264 | XXX_unrecognized []byte `json:"-"` 265 | XXX_sizecache int32 `json:"-"` 266 | } 267 | 268 | func (m *ZeroMsg) Reset() { *m = ZeroMsg{} } 269 | func (m *ZeroMsg) String() string { return proto.CompactTextString(m) } 270 | func (*ZeroMsg) ProtoMessage() {} 271 | func (*ZeroMsg) Descriptor() ([]byte, []int) { 272 | return fileDescriptor_8e16ccb8c5307b32, []int{5} 273 | } 274 | 275 | func (m *ZeroMsg) XXX_Unmarshal(b []byte) error { 276 | return xxx_messageInfo_ZeroMsg.Unmarshal(m, b) 277 | } 278 | func (m *ZeroMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 279 | return xxx_messageInfo_ZeroMsg.Marshal(b, m, deterministic) 280 | } 281 | func (m *ZeroMsg) XXX_Merge(src proto.Message) { 282 | xxx_messageInfo_ZeroMsg.Merge(m, src) 283 | } 284 | func (m *ZeroMsg) XXX_Size() int { 285 | return xxx_messageInfo_ZeroMsg.Size(m) 286 | } 287 | func (m *ZeroMsg) XXX_DiscardUnknown() { 288 | xxx_messageInfo_ZeroMsg.DiscardUnknown(m) 289 | } 290 | 291 | var xxx_messageInfo_ZeroMsg proto.InternalMessageInfo 292 | 293 | func (m *ZeroMsg) GetIndex() int32 { 294 | if m != nil { 295 | return m.Index 296 | } 297 | return 0 298 | } 299 | 300 | func (m *ZeroMsg) GetShare() []byte { 301 | if m != nil { 302 | return m.Share 303 | } 304 | return nil 305 | } 306 | 307 | func init() { 308 | proto.RegisterType((*EmptyMsg)(nil), "services.EmptyMsg") 309 | proto.RegisterType((*AckMsg)(nil), "services.AckMsg") 310 | proto.RegisterType((*Cmt1Msg)(nil), "services.Cmt1Msg") 311 | proto.RegisterType((*Cmt2Msg)(nil), "services.Cmt2Msg") 312 | proto.RegisterType((*PointMsg)(nil), "services.PointMsg") 313 | proto.RegisterType((*ZeroMsg)(nil), "services.ZeroMsg") 314 | } 315 | 316 | func init() { proto.RegisterFile("services.proto", fileDescriptor_8e16ccb8c5307b32) } 317 | 318 | var fileDescriptor_8e16ccb8c5307b32 = []byte{ 319 | // 380 bytes of a gzipped FileDescriptorProto 320 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xc1, 0x6f, 0xa2, 0x40, 321 | 0x14, 0xc6, 0xc5, 0x5d, 0x94, 0x3c, 0xcc, 0xc6, 0x9d, 0x78, 0x20, 0x9e, 0x0c, 0x27, 0x4f, 0x66, 322 | 0x1d, 0x34, 0x9b, 0xf6, 0x56, 0x1b, 0x8f, 0x36, 0x06, 0x13, 0x9b, 0xf4, 0x46, 0x61, 0xaa, 0x93, 323 | 0x2a, 0x43, 0x66, 0xa6, 0x55, 0xfa, 0xd7, 0x36, 0xe9, 0x3f, 0xd2, 0x30, 0x82, 0x4a, 0x44, 0xa5, 324 | 0x37, 0xbe, 0x81, 0xef, 0xfd, 0xde, 0xfb, 0xde, 0x04, 0xf8, 0x23, 0x08, 0x7f, 0xa7, 0x3e, 0x11, 325 | 0xbd, 0x88, 0x33, 0xc9, 0x90, 0x91, 0x69, 0x1b, 0xc0, 0x18, 0xaf, 0x23, 0x19, 0x4f, 0xc4, 0xc2, 326 | 0x36, 0xa0, 0x76, 0xe7, 0xbf, 0x26, 0x4f, 0x37, 0x50, 0xbf, 0x5f, 0xcb, 0xfe, 0x44, 0x2c, 0x50, 327 | 0x0b, 0x74, 0x1a, 0x06, 0x64, 0x6b, 0x69, 0x1d, 0xad, 0xab, 0xbb, 0x3b, 0x81, 0x2c, 0xa8, 0x47, 328 | 0x6c, 0x15, 0xfb, 0x6b, 0x69, 0x55, 0x3b, 0x5a, 0xb7, 0xe1, 0x66, 0xd2, 0xde, 0x28, 0x2b, 0x3e, 329 | 0x6f, 0x6d, 0x83, 0x21, 0x96, 0x1e, 0x27, 0x07, 0xef, 0x5e, 0x1f, 0x97, 0xfd, 0x95, 0x2b, 0x8b, 330 | 0x3a, 0x60, 0x7e, 0x10, 0xce, 0x36, 0x54, 0x86, 0x44, 0x08, 0xeb, 0xb7, 0x7a, 0x7b, 0x7c, 0x64, 331 | 0xcf, 0xc1, 0x98, 0x32, 0x1a, 0xca, 0xf3, 0xe4, 0x06, 0x68, 0x5b, 0x85, 0xd4, 0x5d, 0x4d, 0xa9, 332 | 0x38, 0xa5, 0x68, 0x71, 0x42, 0xce, 0xd7, 0xce, 0xa4, 0x3d, 0x84, 0xfa, 0x13, 0xe1, 0xec, 0x7c, 333 | 0xd9, 0x16, 0xe8, 0x6a, 0x80, 0x74, 0x9a, 0x9d, 0xc0, 0x5f, 0x55, 0x68, 0x8d, 0xde, 0x56, 0x2b, 334 | 0x22, 0x69, 0x38, 0x62, 0x1e, 0x0f, 0x66, 0xbb, 0xc8, 0xd1, 0x00, 0x60, 0x26, 0x3d, 0x2e, 0xc7, 335 | 0x11, 0xf3, 0x97, 0x08, 0xf5, 0xf6, 0xab, 0xc9, 0xf6, 0xd0, 0x6e, 0x1e, 0xce, 0xd2, 0x7d, 0x54, 336 | 0xd0, 0x7f, 0x00, 0x97, 0x78, 0xc1, 0x74, 0xe9, 0x09, 0xd2, 0x2f, 0x74, 0xfd, 0x3d, 0x9c, 0xa5, 337 | 0xbb, 0xb3, 0x2b, 0xff, 0x34, 0x34, 0x00, 0xf3, 0x91, 0x53, 0x49, 0x94, 0x13, 0xa3, 0xfc, 0x57, 338 | 0xb8, 0x0c, 0x0e, 0x97, 0xc0, 0xe1, 0x42, 0x9c, 0x83, 0x4e, 0x9b, 0xba, 0x8a, 0x73, 0x7e, 0x30, 339 | 0x1d, 0xfe, 0xac, 0x82, 0xf9, 0xc0, 0x02, 0x92, 0x85, 0x3b, 0x04, 0x53, 0x85, 0x7b, 0x21, 0xa7, 340 | 0x22, 0x7e, 0x62, 0x4b, 0xb6, 0x76, 0x6a, 0xcb, 0xae, 0x54, 0xa1, 0x6d, 0x70, 0x6c, 0xcb, 0x65, 341 | 0x9b, 0xde, 0x98, 0x42, 0xd7, 0x2d, 0x34, 0x55, 0x8f, 0x73, 0xc2, 0xe9, 0xcb, 0x85, 0x84, 0xaf, 342 | 0x36, 0xea, 0x94, 0x6e, 0xf4, 0x14, 0xe9, 0x94, 0x45, 0x3e, 0xd7, 0xd4, 0x2f, 0xc3, 0xf9, 0x0e, 343 | 0x00, 0x00, 0xff, 0xff, 0x0e, 0x16, 0xd4, 0xda, 0x44, 0x04, 0x00, 0x00, 344 | } 345 | 346 | // Reference imports to suppress errors if they are not otherwise used. 347 | var _ context.Context 348 | var _ grpc.ClientConn 349 | 350 | // This is a compile-time assertion to ensure that this generated file 351 | // is compatible with the grpc package it is being compiled against. 352 | const _ = grpc.SupportPackageIsVersion4 353 | 354 | // BulletinBoardServiceClient is the client API for BulletinBoardService service. 355 | // 356 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. 357 | type BulletinBoardServiceClient interface { 358 | // Start a epoch 359 | StartEpoch(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (*AckMsg, error) 360 | // BulletinBoard RPC for recontruction phase 361 | ReadPhase1(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (BulletinBoardService_ReadPhase1Client, error) 362 | // BulletinBoard RPC for proactivization phase 363 | WritePhase2(ctx context.Context, in *Cmt2Msg, opts ...grpc.CallOption) (*AckMsg, error) 364 | ReadPhase2(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (BulletinBoardService_ReadPhase2Client, error) 365 | // BulletinBoard RPC for share distribution phase 366 | WritePhase3(ctx context.Context, in *Cmt1Msg, opts ...grpc.CallOption) (*AckMsg, error) 367 | ReadPhase3(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (BulletinBoardService_ReadPhase3Client, error) 368 | } 369 | 370 | type bulletinBoardServiceClient struct { 371 | cc *grpc.ClientConn 372 | } 373 | 374 | func NewBulletinBoardServiceClient(cc *grpc.ClientConn) BulletinBoardServiceClient { 375 | return &bulletinBoardServiceClient{cc} 376 | } 377 | 378 | func (c *bulletinBoardServiceClient) StartEpoch(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (*AckMsg, error) { 379 | out := new(AckMsg) 380 | err := c.cc.Invoke(ctx, "/services.BulletinBoardService/StartEpoch", in, out, opts...) 381 | if err != nil { 382 | return nil, err 383 | } 384 | return out, nil 385 | } 386 | 387 | func (c *bulletinBoardServiceClient) ReadPhase1(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (BulletinBoardService_ReadPhase1Client, error) { 388 | stream, err := c.cc.NewStream(ctx, &_BulletinBoardService_serviceDesc.Streams[0], "/services.BulletinBoardService/ReadPhase1", opts...) 389 | if err != nil { 390 | return nil, err 391 | } 392 | x := &bulletinBoardServiceReadPhase1Client{stream} 393 | if err := x.ClientStream.SendMsg(in); err != nil { 394 | return nil, err 395 | } 396 | if err := x.ClientStream.CloseSend(); err != nil { 397 | return nil, err 398 | } 399 | return x, nil 400 | } 401 | 402 | type BulletinBoardService_ReadPhase1Client interface { 403 | Recv() (*Cmt1Msg, error) 404 | grpc.ClientStream 405 | } 406 | 407 | type bulletinBoardServiceReadPhase1Client struct { 408 | grpc.ClientStream 409 | } 410 | 411 | func (x *bulletinBoardServiceReadPhase1Client) Recv() (*Cmt1Msg, error) { 412 | m := new(Cmt1Msg) 413 | if err := x.ClientStream.RecvMsg(m); err != nil { 414 | return nil, err 415 | } 416 | return m, nil 417 | } 418 | 419 | func (c *bulletinBoardServiceClient) WritePhase2(ctx context.Context, in *Cmt2Msg, opts ...grpc.CallOption) (*AckMsg, error) { 420 | out := new(AckMsg) 421 | err := c.cc.Invoke(ctx, "/services.BulletinBoardService/WritePhase2", in, out, opts...) 422 | if err != nil { 423 | return nil, err 424 | } 425 | return out, nil 426 | } 427 | 428 | func (c *bulletinBoardServiceClient) ReadPhase2(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (BulletinBoardService_ReadPhase2Client, error) { 429 | stream, err := c.cc.NewStream(ctx, &_BulletinBoardService_serviceDesc.Streams[1], "/services.BulletinBoardService/ReadPhase2", opts...) 430 | if err != nil { 431 | return nil, err 432 | } 433 | x := &bulletinBoardServiceReadPhase2Client{stream} 434 | if err := x.ClientStream.SendMsg(in); err != nil { 435 | return nil, err 436 | } 437 | if err := x.ClientStream.CloseSend(); err != nil { 438 | return nil, err 439 | } 440 | return x, nil 441 | } 442 | 443 | type BulletinBoardService_ReadPhase2Client interface { 444 | Recv() (*Cmt2Msg, error) 445 | grpc.ClientStream 446 | } 447 | 448 | type bulletinBoardServiceReadPhase2Client struct { 449 | grpc.ClientStream 450 | } 451 | 452 | func (x *bulletinBoardServiceReadPhase2Client) Recv() (*Cmt2Msg, error) { 453 | m := new(Cmt2Msg) 454 | if err := x.ClientStream.RecvMsg(m); err != nil { 455 | return nil, err 456 | } 457 | return m, nil 458 | } 459 | 460 | func (c *bulletinBoardServiceClient) WritePhase3(ctx context.Context, in *Cmt1Msg, opts ...grpc.CallOption) (*AckMsg, error) { 461 | out := new(AckMsg) 462 | err := c.cc.Invoke(ctx, "/services.BulletinBoardService/WritePhase3", in, out, opts...) 463 | if err != nil { 464 | return nil, err 465 | } 466 | return out, nil 467 | } 468 | 469 | func (c *bulletinBoardServiceClient) ReadPhase3(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (BulletinBoardService_ReadPhase3Client, error) { 470 | stream, err := c.cc.NewStream(ctx, &_BulletinBoardService_serviceDesc.Streams[2], "/services.BulletinBoardService/ReadPhase3", opts...) 471 | if err != nil { 472 | return nil, err 473 | } 474 | x := &bulletinBoardServiceReadPhase3Client{stream} 475 | if err := x.ClientStream.SendMsg(in); err != nil { 476 | return nil, err 477 | } 478 | if err := x.ClientStream.CloseSend(); err != nil { 479 | return nil, err 480 | } 481 | return x, nil 482 | } 483 | 484 | type BulletinBoardService_ReadPhase3Client interface { 485 | Recv() (*Cmt1Msg, error) 486 | grpc.ClientStream 487 | } 488 | 489 | type bulletinBoardServiceReadPhase3Client struct { 490 | grpc.ClientStream 491 | } 492 | 493 | func (x *bulletinBoardServiceReadPhase3Client) Recv() (*Cmt1Msg, error) { 494 | m := new(Cmt1Msg) 495 | if err := x.ClientStream.RecvMsg(m); err != nil { 496 | return nil, err 497 | } 498 | return m, nil 499 | } 500 | 501 | // BulletinBoardServiceServer is the server API for BulletinBoardService service. 502 | type BulletinBoardServiceServer interface { 503 | // Start a epoch 504 | StartEpoch(context.Context, *EmptyMsg) (*AckMsg, error) 505 | // BulletinBoard RPC for recontruction phase 506 | ReadPhase1(*EmptyMsg, BulletinBoardService_ReadPhase1Server) error 507 | // BulletinBoard RPC for proactivization phase 508 | WritePhase2(context.Context, *Cmt2Msg) (*AckMsg, error) 509 | ReadPhase2(*EmptyMsg, BulletinBoardService_ReadPhase2Server) error 510 | // BulletinBoard RPC for share distribution phase 511 | WritePhase3(context.Context, *Cmt1Msg) (*AckMsg, error) 512 | ReadPhase3(*EmptyMsg, BulletinBoardService_ReadPhase3Server) error 513 | } 514 | 515 | func RegisterBulletinBoardServiceServer(s *grpc.Server, srv BulletinBoardServiceServer) { 516 | s.RegisterService(&_BulletinBoardService_serviceDesc, srv) 517 | } 518 | 519 | func _BulletinBoardService_StartEpoch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 520 | in := new(EmptyMsg) 521 | if err := dec(in); err != nil { 522 | return nil, err 523 | } 524 | if interceptor == nil { 525 | return srv.(BulletinBoardServiceServer).StartEpoch(ctx, in) 526 | } 527 | info := &grpc.UnaryServerInfo{ 528 | Server: srv, 529 | FullMethod: "/services.BulletinBoardService/StartEpoch", 530 | } 531 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 532 | return srv.(BulletinBoardServiceServer).StartEpoch(ctx, req.(*EmptyMsg)) 533 | } 534 | return interceptor(ctx, in, info, handler) 535 | } 536 | 537 | func _BulletinBoardService_ReadPhase1_Handler(srv interface{}, stream grpc.ServerStream) error { 538 | m := new(EmptyMsg) 539 | if err := stream.RecvMsg(m); err != nil { 540 | return err 541 | } 542 | return srv.(BulletinBoardServiceServer).ReadPhase1(m, &bulletinBoardServiceReadPhase1Server{stream}) 543 | } 544 | 545 | type BulletinBoardService_ReadPhase1Server interface { 546 | Send(*Cmt1Msg) error 547 | grpc.ServerStream 548 | } 549 | 550 | type bulletinBoardServiceReadPhase1Server struct { 551 | grpc.ServerStream 552 | } 553 | 554 | func (x *bulletinBoardServiceReadPhase1Server) Send(m *Cmt1Msg) error { 555 | return x.ServerStream.SendMsg(m) 556 | } 557 | 558 | func _BulletinBoardService_WritePhase2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 559 | in := new(Cmt2Msg) 560 | if err := dec(in); err != nil { 561 | return nil, err 562 | } 563 | if interceptor == nil { 564 | return srv.(BulletinBoardServiceServer).WritePhase2(ctx, in) 565 | } 566 | info := &grpc.UnaryServerInfo{ 567 | Server: srv, 568 | FullMethod: "/services.BulletinBoardService/WritePhase2", 569 | } 570 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 571 | return srv.(BulletinBoardServiceServer).WritePhase2(ctx, req.(*Cmt2Msg)) 572 | } 573 | return interceptor(ctx, in, info, handler) 574 | } 575 | 576 | func _BulletinBoardService_ReadPhase2_Handler(srv interface{}, stream grpc.ServerStream) error { 577 | m := new(EmptyMsg) 578 | if err := stream.RecvMsg(m); err != nil { 579 | return err 580 | } 581 | return srv.(BulletinBoardServiceServer).ReadPhase2(m, &bulletinBoardServiceReadPhase2Server{stream}) 582 | } 583 | 584 | type BulletinBoardService_ReadPhase2Server interface { 585 | Send(*Cmt2Msg) error 586 | grpc.ServerStream 587 | } 588 | 589 | type bulletinBoardServiceReadPhase2Server struct { 590 | grpc.ServerStream 591 | } 592 | 593 | func (x *bulletinBoardServiceReadPhase2Server) Send(m *Cmt2Msg) error { 594 | return x.ServerStream.SendMsg(m) 595 | } 596 | 597 | func _BulletinBoardService_WritePhase3_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 598 | in := new(Cmt1Msg) 599 | if err := dec(in); err != nil { 600 | return nil, err 601 | } 602 | if interceptor == nil { 603 | return srv.(BulletinBoardServiceServer).WritePhase3(ctx, in) 604 | } 605 | info := &grpc.UnaryServerInfo{ 606 | Server: srv, 607 | FullMethod: "/services.BulletinBoardService/WritePhase3", 608 | } 609 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 610 | return srv.(BulletinBoardServiceServer).WritePhase3(ctx, req.(*Cmt1Msg)) 611 | } 612 | return interceptor(ctx, in, info, handler) 613 | } 614 | 615 | func _BulletinBoardService_ReadPhase3_Handler(srv interface{}, stream grpc.ServerStream) error { 616 | m := new(EmptyMsg) 617 | if err := stream.RecvMsg(m); err != nil { 618 | return err 619 | } 620 | return srv.(BulletinBoardServiceServer).ReadPhase3(m, &bulletinBoardServiceReadPhase3Server{stream}) 621 | } 622 | 623 | type BulletinBoardService_ReadPhase3Server interface { 624 | Send(*Cmt1Msg) error 625 | grpc.ServerStream 626 | } 627 | 628 | type bulletinBoardServiceReadPhase3Server struct { 629 | grpc.ServerStream 630 | } 631 | 632 | func (x *bulletinBoardServiceReadPhase3Server) Send(m *Cmt1Msg) error { 633 | return x.ServerStream.SendMsg(m) 634 | } 635 | 636 | var _BulletinBoardService_serviceDesc = grpc.ServiceDesc{ 637 | ServiceName: "services.BulletinBoardService", 638 | HandlerType: (*BulletinBoardServiceServer)(nil), 639 | Methods: []grpc.MethodDesc{ 640 | { 641 | MethodName: "StartEpoch", 642 | Handler: _BulletinBoardService_StartEpoch_Handler, 643 | }, 644 | { 645 | MethodName: "WritePhase2", 646 | Handler: _BulletinBoardService_WritePhase2_Handler, 647 | }, 648 | { 649 | MethodName: "WritePhase3", 650 | Handler: _BulletinBoardService_WritePhase3_Handler, 651 | }, 652 | }, 653 | Streams: []grpc.StreamDesc{ 654 | { 655 | StreamName: "ReadPhase1", 656 | Handler: _BulletinBoardService_ReadPhase1_Handler, 657 | ServerStreams: true, 658 | }, 659 | { 660 | StreamName: "ReadPhase2", 661 | Handler: _BulletinBoardService_ReadPhase2_Handler, 662 | ServerStreams: true, 663 | }, 664 | { 665 | StreamName: "ReadPhase3", 666 | Handler: _BulletinBoardService_ReadPhase3_Handler, 667 | ServerStreams: true, 668 | }, 669 | }, 670 | Metadata: "services.proto", 671 | } 672 | 673 | // NodeServiceClient is the client API for NodeService service. 674 | // 675 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. 676 | type NodeServiceClient interface { 677 | // Node RPC for reconstruction phase 678 | StartPhase1(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (*AckMsg, error) 679 | SharePhase1(ctx context.Context, in *PointMsg, opts ...grpc.CallOption) (*AckMsg, error) 680 | // Node RPC for proactivization phase 681 | SharePhase2(ctx context.Context, in *ZeroMsg, opts ...grpc.CallOption) (*AckMsg, error) 682 | StartVerifPhase2(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (*AckMsg, error) 683 | // Node RPC for share distribution phase 684 | SharePhase3(ctx context.Context, in *PointMsg, opts ...grpc.CallOption) (*AckMsg, error) 685 | StartVerifPhase3(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (*AckMsg, error) 686 | } 687 | 688 | type nodeServiceClient struct { 689 | cc *grpc.ClientConn 690 | } 691 | 692 | func NewNodeServiceClient(cc *grpc.ClientConn) NodeServiceClient { 693 | return &nodeServiceClient{cc} 694 | } 695 | 696 | func (c *nodeServiceClient) StartPhase1(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (*AckMsg, error) { 697 | out := new(AckMsg) 698 | err := c.cc.Invoke(ctx, "/services.NodeService/StartPhase1", in, out, opts...) 699 | if err != nil { 700 | return nil, err 701 | } 702 | return out, nil 703 | } 704 | 705 | func (c *nodeServiceClient) SharePhase1(ctx context.Context, in *PointMsg, opts ...grpc.CallOption) (*AckMsg, error) { 706 | out := new(AckMsg) 707 | err := c.cc.Invoke(ctx, "/services.NodeService/SharePhase1", in, out, opts...) 708 | if err != nil { 709 | return nil, err 710 | } 711 | return out, nil 712 | } 713 | 714 | func (c *nodeServiceClient) SharePhase2(ctx context.Context, in *ZeroMsg, opts ...grpc.CallOption) (*AckMsg, error) { 715 | out := new(AckMsg) 716 | err := c.cc.Invoke(ctx, "/services.NodeService/SharePhase2", in, out, opts...) 717 | if err != nil { 718 | return nil, err 719 | } 720 | return out, nil 721 | } 722 | 723 | func (c *nodeServiceClient) StartVerifPhase2(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (*AckMsg, error) { 724 | out := new(AckMsg) 725 | err := c.cc.Invoke(ctx, "/services.NodeService/StartVerifPhase2", in, out, opts...) 726 | if err != nil { 727 | return nil, err 728 | } 729 | return out, nil 730 | } 731 | 732 | func (c *nodeServiceClient) SharePhase3(ctx context.Context, in *PointMsg, opts ...grpc.CallOption) (*AckMsg, error) { 733 | out := new(AckMsg) 734 | err := c.cc.Invoke(ctx, "/services.NodeService/SharePhase3", in, out, opts...) 735 | if err != nil { 736 | return nil, err 737 | } 738 | return out, nil 739 | } 740 | 741 | func (c *nodeServiceClient) StartVerifPhase3(ctx context.Context, in *EmptyMsg, opts ...grpc.CallOption) (*AckMsg, error) { 742 | out := new(AckMsg) 743 | err := c.cc.Invoke(ctx, "/services.NodeService/StartVerifPhase3", in, out, opts...) 744 | if err != nil { 745 | return nil, err 746 | } 747 | return out, nil 748 | } 749 | 750 | // NodeServiceServer is the server API for NodeService service. 751 | type NodeServiceServer interface { 752 | // Node RPC for reconstruction phase 753 | StartPhase1(context.Context, *EmptyMsg) (*AckMsg, error) 754 | SharePhase1(context.Context, *PointMsg) (*AckMsg, error) 755 | // Node RPC for proactivization phase 756 | SharePhase2(context.Context, *ZeroMsg) (*AckMsg, error) 757 | StartVerifPhase2(context.Context, *EmptyMsg) (*AckMsg, error) 758 | // Node RPC for share distribution phase 759 | SharePhase3(context.Context, *PointMsg) (*AckMsg, error) 760 | StartVerifPhase3(context.Context, *EmptyMsg) (*AckMsg, error) 761 | } 762 | 763 | func RegisterNodeServiceServer(s *grpc.Server, srv NodeServiceServer) { 764 | s.RegisterService(&_NodeService_serviceDesc, srv) 765 | } 766 | 767 | func _NodeService_StartPhase1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 768 | in := new(EmptyMsg) 769 | if err := dec(in); err != nil { 770 | return nil, err 771 | } 772 | if interceptor == nil { 773 | return srv.(NodeServiceServer).StartPhase1(ctx, in) 774 | } 775 | info := &grpc.UnaryServerInfo{ 776 | Server: srv, 777 | FullMethod: "/services.NodeService/StartPhase1", 778 | } 779 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 780 | return srv.(NodeServiceServer).StartPhase1(ctx, req.(*EmptyMsg)) 781 | } 782 | return interceptor(ctx, in, info, handler) 783 | } 784 | 785 | func _NodeService_SharePhase1_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 786 | in := new(PointMsg) 787 | if err := dec(in); err != nil { 788 | return nil, err 789 | } 790 | if interceptor == nil { 791 | return srv.(NodeServiceServer).SharePhase1(ctx, in) 792 | } 793 | info := &grpc.UnaryServerInfo{ 794 | Server: srv, 795 | FullMethod: "/services.NodeService/SharePhase1", 796 | } 797 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 798 | return srv.(NodeServiceServer).SharePhase1(ctx, req.(*PointMsg)) 799 | } 800 | return interceptor(ctx, in, info, handler) 801 | } 802 | 803 | func _NodeService_SharePhase2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 804 | in := new(ZeroMsg) 805 | if err := dec(in); err != nil { 806 | return nil, err 807 | } 808 | if interceptor == nil { 809 | return srv.(NodeServiceServer).SharePhase2(ctx, in) 810 | } 811 | info := &grpc.UnaryServerInfo{ 812 | Server: srv, 813 | FullMethod: "/services.NodeService/SharePhase2", 814 | } 815 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 816 | return srv.(NodeServiceServer).SharePhase2(ctx, req.(*ZeroMsg)) 817 | } 818 | return interceptor(ctx, in, info, handler) 819 | } 820 | 821 | func _NodeService_StartVerifPhase2_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 822 | in := new(EmptyMsg) 823 | if err := dec(in); err != nil { 824 | return nil, err 825 | } 826 | if interceptor == nil { 827 | return srv.(NodeServiceServer).StartVerifPhase2(ctx, in) 828 | } 829 | info := &grpc.UnaryServerInfo{ 830 | Server: srv, 831 | FullMethod: "/services.NodeService/StartVerifPhase2", 832 | } 833 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 834 | return srv.(NodeServiceServer).StartVerifPhase2(ctx, req.(*EmptyMsg)) 835 | } 836 | return interceptor(ctx, in, info, handler) 837 | } 838 | 839 | func _NodeService_SharePhase3_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 840 | in := new(PointMsg) 841 | if err := dec(in); err != nil { 842 | return nil, err 843 | } 844 | if interceptor == nil { 845 | return srv.(NodeServiceServer).SharePhase3(ctx, in) 846 | } 847 | info := &grpc.UnaryServerInfo{ 848 | Server: srv, 849 | FullMethod: "/services.NodeService/SharePhase3", 850 | } 851 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 852 | return srv.(NodeServiceServer).SharePhase3(ctx, req.(*PointMsg)) 853 | } 854 | return interceptor(ctx, in, info, handler) 855 | } 856 | 857 | func _NodeService_StartVerifPhase3_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 858 | in := new(EmptyMsg) 859 | if err := dec(in); err != nil { 860 | return nil, err 861 | } 862 | if interceptor == nil { 863 | return srv.(NodeServiceServer).StartVerifPhase3(ctx, in) 864 | } 865 | info := &grpc.UnaryServerInfo{ 866 | Server: srv, 867 | FullMethod: "/services.NodeService/StartVerifPhase3", 868 | } 869 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 870 | return srv.(NodeServiceServer).StartVerifPhase3(ctx, req.(*EmptyMsg)) 871 | } 872 | return interceptor(ctx, in, info, handler) 873 | } 874 | 875 | var _NodeService_serviceDesc = grpc.ServiceDesc{ 876 | ServiceName: "services.NodeService", 877 | HandlerType: (*NodeServiceServer)(nil), 878 | Methods: []grpc.MethodDesc{ 879 | { 880 | MethodName: "StartPhase1", 881 | Handler: _NodeService_StartPhase1_Handler, 882 | }, 883 | { 884 | MethodName: "SharePhase1", 885 | Handler: _NodeService_SharePhase1_Handler, 886 | }, 887 | { 888 | MethodName: "SharePhase2", 889 | Handler: _NodeService_SharePhase2_Handler, 890 | }, 891 | { 892 | MethodName: "StartVerifPhase2", 893 | Handler: _NodeService_StartVerifPhase2_Handler, 894 | }, 895 | { 896 | MethodName: "SharePhase3", 897 | Handler: _NodeService_SharePhase3_Handler, 898 | }, 899 | { 900 | MethodName: "StartVerifPhase3", 901 | Handler: _NodeService_StartVerifPhase3_Handler, 902 | }, 903 | }, 904 | Streams: []grpc.StreamDesc{}, 905 | Metadata: "services.proto", 906 | } 907 | --------------------------------------------------------------------------------