github.com/theQRL/go-zond@v0.2.1/cmd/zondkey/message.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "encoding/hex" 21 "fmt" 22 "os" 23 24 "github.com/theQRL/go-qrllib/dilithium" 25 "github.com/theQRL/go-zond/accounts" 26 "github.com/theQRL/go-zond/accounts/keystore" 27 "github.com/theQRL/go-zond/cmd/utils" 28 "github.com/theQRL/go-zond/common" 29 "github.com/theQRL/go-zond/crypto/pqcrypto" 30 "github.com/urfave/cli/v2" 31 ) 32 33 type outputSign struct { 34 Signature string 35 } 36 37 var msgfileFlag = &cli.StringFlag{ 38 Name: "msgfile", 39 Usage: "file containing the message to sign/verify", 40 } 41 42 var commandSignMessage = &cli.Command{ 43 Name: "signmessage", 44 Usage: "sign a message", 45 ArgsUsage: "<keyfile> <message>", 46 Description: ` 47 Sign the message with a keyfile. 48 49 To sign a message contained in a file, use the --msgfile flag. 50 `, 51 Flags: []cli.Flag{ 52 passphraseFlag, 53 jsonFlag, 54 msgfileFlag, 55 }, 56 Action: func(ctx *cli.Context) error { 57 message := getMessage(ctx, 1) 58 59 // Load the keyfile. 60 keyfilepath := ctx.Args().First() 61 keyjson, err := os.ReadFile(keyfilepath) 62 if err != nil { 63 utils.Fatalf("Failed to read the keyfile at '%s': %v", keyfilepath, err) 64 } 65 66 // Decrypt key with passphrase. 67 passphrase := getPassphrase(ctx, false) 68 key, err := keystore.DecryptKey(keyjson, passphrase) 69 if err != nil { 70 utils.Fatalf("Error decrypting key: %v", err) 71 } 72 73 signature, err := pqcrypto.Sign(accounts.TextHash(message), key.Dilithium) 74 if err != nil { 75 utils.Fatalf("Failed to sign message: %v", err) 76 } 77 out := outputSign{Signature: hex.EncodeToString(signature)} 78 if ctx.Bool(jsonFlag.Name) { 79 mustPrintJSON(out) 80 } else { 81 fmt.Println("Signature:", out.Signature) 82 } 83 84 return nil 85 }, 86 } 87 88 type outputVerify struct { 89 Success bool 90 } 91 92 // TODO(now.youtrack.cloud/issue/TGZ-3) 93 var commandVerifyMessage = &cli.Command{ 94 Name: "verifymessage", 95 Usage: "verify the signature of a signed message", 96 ArgsUsage: "<signature> <publickey> <message>", 97 Description: ` 98 Verify the signature of the message. 99 It is possible to refer to a file containing the message.`, 100 Flags: []cli.Flag{ 101 jsonFlag, 102 msgfileFlag, 103 }, 104 Action: func(ctx *cli.Context) error { 105 signatureHex := ctx.Args().First() 106 pubKeyHex := ctx.Args().Get(1) 107 message := getMessage(ctx, 2) 108 109 signature := common.FromHex(signatureHex) 110 publicKey := common.FromHex(pubKeyHex) 111 112 dilithiumPublicKey := [2592]uint8(publicKey) 113 out := outputVerify{ 114 Success: dilithium.Verify(accounts.TextHash(message), [4595]uint8(signature), &dilithiumPublicKey), 115 } 116 if ctx.Bool(jsonFlag.Name) { 117 mustPrintJSON(out) 118 } else { 119 if out.Success { 120 fmt.Println("Signature verification successful!") 121 } else { 122 fmt.Println("Signature verification failed!") 123 } 124 } 125 return nil 126 }, 127 } 128 129 func getMessage(ctx *cli.Context, msgarg int) []byte { 130 if file := ctx.String(msgfileFlag.Name); file != "" { 131 if ctx.NArg() > msgarg { 132 utils.Fatalf("Can't use --msgfile and message argument at the same time.") 133 } 134 msg, err := os.ReadFile(file) 135 if err != nil { 136 utils.Fatalf("Can't read message file: %v", err) 137 } 138 return msg 139 } else if ctx.NArg() == msgarg+1 { 140 return []byte(ctx.Args().Get(msgarg)) 141 } 142 utils.Fatalf("Invalid number of arguments: want %d, got %d", msgarg+1, ctx.NArg()) 143 return nil 144 }