33package main
44
55import (
6+ "bytes"
67 "crypto/rand"
78 "encoding/binary"
89 "encoding/hex"
@@ -16,17 +17,20 @@ import (
1617 "runtime"
1718 "runtime/pprof"
1819 "strconv"
20+ "strings"
1921 "syscall"
2022 "time"
2123
2224 "go.uber.org/zap"
25+ "golang.org/x/crypto/sha3"
2326 "google.golang.org/protobuf/proto"
2427 "source.quilibrium.com/quilibrium/monorepo/node/execution/intrinsics/ceremony/application"
2528 "source.quilibrium.com/quilibrium/monorepo/node/p2p"
2629 "source.quilibrium.com/quilibrium/monorepo/node/protobufs"
2730 "source.quilibrium.com/quilibrium/monorepo/node/store"
2831 "source.quilibrium.com/quilibrium/monorepo/node/utils"
2932
33+ "github.com/cloudflare/circl/sign/ed448"
3034 "github.com/libp2p/go-libp2p/core/crypto"
3135 "github.com/libp2p/go-libp2p/core/peer"
3236 "github.com/pbnjay/memory"
@@ -94,11 +98,105 @@ var (
9498 0 ,
9599 "sets the active network for the node (mainnet = 0, primary testnet = 1)" ,
96100 )
101+ signatureCheck = flag .Bool (
102+ "signature-check" ,
103+ true ,
104+ "enables or disables signature validation (default true)" ,
105+ )
97106)
98107
108+ var signatories = []string {
109+ "b1214da7f355f5a9edb7bcc23d403bdf789f070cca10db2b4cadc22f2d837afb650944853e35d5f42ef3c4105b802b144b4077d5d3253e4100" ,
110+ "de4cfe7083104bfe32f0d4082fa0200464d8b10804a811653eedda376efcad64dd222f0f0ceb0b8ae58abe830d7a7e3f3b2d79d691318daa00" ,
111+ "540237a35e124882d6b64e7bb5718273fa338e553f772b77fe90570e45303762b34131bdcb6c0b9f2cf9e393d9c7e0f546eeab0bcbbd881680" ,
112+ "fbe4166e37f93f90d2ebf06305315ae11b37e501d09596f8bde11ba9d343034fbca80f252205aa2f582a512a72ad293df371baa582da072900" ,
113+ "4160572e493e1bf15c44e055b11bf75230c76c7d2c67b48066770ab03dfd5ed34c97b9a431ec18578c83a0df9250b8362c38068650e8b01400" ,
114+ "45170b626884b85d61ae109f2aa9b0e1ecc18b181508431ea6308f3869f2adae49da9799a0a594eaa4ef3ad492518fb1729decd44169d40d00" ,
115+ "92cd8ee5362f3ae274a75ab9471024dbc144bff441ed8af7d19750ac512ff51e40e7f7b01e4f96b6345dd58878565948c3eb52c53f250b5080" ,
116+ "001a4cbfce5d9aeb7e20665b0d236721b228a32f0baee62ffa77f45b82ecaf577e8a38b7ef91fcf7d2d2d2b504f085461398d30b24abb1d700" ,
117+ "65b835071731c6e785bb2d107c7d85d8a537d79c435c3f42bb2f87027f93f858d7b37c598cef267a5db46e345f7a6f81969b465686657d1e00" ,
118+ "4507626f7164e7d8c304c07ff8d2e23c113fe108b221d2e60672f4d07750345815e2b4b3cc3df4d3466bf2f669c35c3172e06511270612ab00" ,
119+ "4fb2537345e46be3d5f96340c1441007501702dd5bfaf6dbf6943bbefceca8fb2b94ec0a8a1a2f49850fbe1d10244889a4f40abfa9e0c9e000" ,
120+ "57be2861faf0fffcbfd122c85c77010dce8f213030905781b85b6f345d912c7b5ace17797d9810899dfb8d13e7c8369595740725ab3dd5bd00" ,
121+ "61628beef8f6964466fd078d6a2b90a397ab0777a14b9728227fd19f36752f9451b1a8d780740a0b9a8ce3df5f89ca7b9ff17de9274a270980" ,
122+ "5547afc71b02821e2f5bfdd30fbe1374c3853898deff20a1b5cc729b8e81670fbbb9d1e917f85d153ea4b26bbf6f9c546dc1b64b9916608d80" ,
123+ "81d63a45f068629f568de812f18be5807bfe828a830097f09cf02330d6acd35e3607401df3fda08b03b68ea6e68afd506b23506b11e87a0f80" ,
124+ "6e2872f73c4868c4286bef7bfe2f5479a41c42f4e07505efa4883c7950c740252e0eea78eef10c584b19b1dcda01f7767d3135d07c33244100" ,
125+ "a114b061f8d35e3f3497c8c43d83ba6b4af67aa7b39b743b1b0a35f2d66110b5051dd3d86f69b57122a35b64e624b8180bee63b6152fce4280" ,
126+ }
127+
99128func main () {
100129 flag .Parse ()
101130
131+ if * signatureCheck {
132+ if runtime .GOOS == "windows" {
133+ fmt .Println ("Signature check not available for windows yet, skipping..." )
134+ } else {
135+ ex , err := os .Executable ()
136+ if err != nil {
137+ panic (err )
138+ }
139+
140+ filepath := filepath .Dir (ex )
141+ b , err := os .ReadFile (filepath )
142+ if err != nil {
143+ fmt .Println (
144+ "Error encountered during signature check – are you running this " +
145+ "from source? (use --signature-check=false)" ,
146+ )
147+ panic (err )
148+ }
149+
150+ checksum := sha3 .Sum256 (b )
151+ digest , err := os .ReadFile (filepath + ".dgst" )
152+ if err != nil {
153+ fmt .Println ("Digest file not found" )
154+ os .Exit (1 )
155+ }
156+
157+ parts := strings .Split (string (digest ), " " )
158+ if len (parts ) != 2 {
159+ fmt .Println ("Invalid digest file format" )
160+ os .Exit (1 )
161+ }
162+
163+ digestBytes , err := hex .DecodeString (parts [1 ])
164+ if err != nil {
165+ fmt .Println ("Invalid digest file format" )
166+ os .Exit (1 )
167+ }
168+
169+ if ! bytes .Equal (checksum [:], digestBytes ) {
170+ fmt .Println ("Invalid digest for node" )
171+ os .Exit (1 )
172+ }
173+
174+ count := 0
175+
176+ for i := 1 ; i <= len (signatories ); i ++ {
177+ signatureFile := fmt .Sprintf (filepath + ".dgst.sig.%d" , i )
178+ sig , err := os .ReadFile (signatureFile )
179+ if err != nil {
180+ continue
181+ }
182+
183+ pubkey , _ := hex .DecodeString (signatories [i - 1 ])
184+ if ! ed448 .Verify (pubkey , digest , sig , "" ) {
185+ fmt .Printf ("Failed signature check for signatory #%d\n " , i )
186+ os .Exit (1 )
187+ }
188+ count ++
189+ }
190+
191+ if count < len (signatories )/ 2 {
192+ fmt .Printf ("Quorum on signatures not met" )
193+ os .Exit (1 )
194+ }
195+
196+ fmt .Printf ("Signature check passed" )
197+ }
198+ }
199+
102200 if * memprofile != "" {
103201 go func () {
104202 for {
0 commit comments