github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/chat/signencrypt/example/main.go (about) 1 package main 2 3 import ( 4 "encoding/hex" 5 "io" 6 "log" 7 "os" 8 "strconv" 9 10 docopt "github.com/docopt/docopt-go" 11 "github.com/keybase/client/go/chat/signencrypt" 12 "github.com/keybase/client/go/kbcrypto" 13 "github.com/keybase/go-crypto/ed25519" 14 ) 15 16 func failf(format string, args ...interface{}) { 17 log.Printf(format, args...) 18 os.Exit(1) 19 } 20 21 func decodeHexArg(arg string) []byte { 22 decoded, err := hex.DecodeString(arg) 23 if err != nil { 24 failf("'%s' is not valid hex: %s", arg, err) 25 } 26 return decoded 27 } 28 29 func zeroSecretboxKey() signencrypt.SecretboxKey { 30 var key [signencrypt.SecretboxKeySize]byte // all zeroes 31 return &key 32 } 33 34 func zeroNonce() signencrypt.Nonce { 35 var nonce [signencrypt.NonceSize]byte // all zeroes 36 return &nonce 37 } 38 39 func zeroVerifyKey() signencrypt.VerifyKey { 40 var key [ed25519.PublicKeySize]byte 41 // Generated from libsodium's crypto_sign_seed_keypair with a zero seed. 42 copy(key[:], ";j'\xbc\xce\xb6\xa4-b\xa3\xa8\xd0*o\rse2\x15w\x1d\xe2C\xa6:\xc0H\xa1\x8bY\xda)") 43 return &key 44 } 45 46 func zeroSignKey() signencrypt.SignKey { 47 var key [ed25519.PrivateKeySize]byte 48 // Generated from libsodium's crypto_sign_seed_keypair with a zero seed. 49 copy(key[:], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;j'\xbc\xce\xb6\xa4-b\xa3\xa8\xd0*o\rse2\x15w\x1d\xe2C\xa6:\xc0H\xa1\x8bY\xda)") 50 return &key 51 } 52 53 func seal(enckey signencrypt.SecretboxKey, signkey signencrypt.SignKey, signaturePrefix kbcrypto.SignaturePrefix, nonce signencrypt.Nonce, chunklen int64) error { 54 encoder := signencrypt.NewEncoder(enckey, signkey, signaturePrefix, nonce) 55 if chunklen != 0 { 56 encoder.ChangePlaintextChunkLenForTesting(chunklen) 57 } 58 var buf [4096]byte 59 for { 60 num, err := os.Stdin.Read(buf[:]) 61 if err == io.EOF { 62 break 63 } else if err != nil { 64 return err 65 } 66 encoded := encoder.Write(buf[0:num]) 67 _, err = os.Stdout.Write(encoded) 68 if err != nil { 69 return err 70 } 71 } 72 encoded := encoder.Finish() 73 _, err := os.Stdout.Write(encoded) 74 if err != nil { 75 return err 76 } 77 return nil 78 } 79 80 func open(enckey signencrypt.SecretboxKey, verifykey signencrypt.VerifyKey, signaturePrefix kbcrypto.SignaturePrefix, nonce signencrypt.Nonce, chunklen int64) error { 81 decoder := signencrypt.NewDecoder(enckey, verifykey, signaturePrefix, nonce) 82 if chunklen != 0 { 83 decoder.ChangePlaintextChunkLenForTesting(chunklen) 84 } 85 var buf [4096]byte 86 for { 87 num, err := os.Stdin.Read(buf[:]) 88 if err == io.EOF { 89 break 90 } else if err != nil { 91 return err 92 } 93 decoded, err := decoder.Write(buf[0:num]) 94 if err != nil { 95 return err 96 } 97 _, err = os.Stdout.Write(decoded) 98 if err != nil { 99 return err 100 } 101 } 102 decoded, err := decoder.Finish() 103 if err != nil { 104 return err 105 } 106 _, err = os.Stdout.Write(decoded) 107 if err != nil { 108 return err 109 } 110 return nil 111 } 112 113 func main() { 114 usage := `Usage: 115 example seal [--enckey=<enckey>] [--signkey=<signkey>] 116 [--sigprefix=<sigprefix>] [--nonce=<nonce>] [--chunklen=<chunklen>] 117 example open [--enckey=<enckey>] [--verifykey=<signkey>] 118 [--sigprefix=<sigprefix>] [--nonce=<nonce>] [--chunklen=<chunklen>] 119 120 Options: 121 --enckey=<enckey> the 32-byte encryption key (in hex) 122 --signkey=<signkey> the 64-byte signing private key (in hex) 123 --verifykey=<verifykey> the 32-byte signing public key (in hex) 124 --sigprefix=<sigprefix> the signature prefix (string) 125 --nonce=<nonce> the 16-byte nonce 126 --chunklen=<chunklen> the size of plaintext chunks, for testing, default 2^20 bytes 127 ` 128 arguments, _ := docopt.Parse(usage, nil, true, "signencrypt crypto example", false) 129 130 enckey := zeroSecretboxKey() 131 if arguments["--enckey"] != nil { 132 copy(enckey[:], decodeHexArg(arguments["--enckey"].(string))) 133 } 134 135 signkey := zeroSignKey() 136 if arguments["--signkey"] != nil { 137 copy(signkey[:], decodeHexArg(arguments["--signkey"].(string))) 138 } 139 140 verifykey := zeroVerifyKey() 141 if arguments["--verifykey"] != nil { 142 copy(verifykey[:], decodeHexArg(arguments["--verifykey"].(string))) 143 } 144 145 signaturePrefix := kbcrypto.SignaturePrefixTesting 146 if arguments["--sigprefix"] != nil { 147 signaturePrefixStr := arguments["--sigprefix"].(string) 148 signaturePrefix = kbcrypto.SignaturePrefix(signaturePrefixStr) 149 } 150 151 nonce := zeroNonce() 152 if arguments["--nonce"] != nil { 153 copy(nonce[:], decodeHexArg(arguments["--nonce"].(string))) 154 } 155 156 var chunklen int64 157 if arguments["--chunklen"] != nil { 158 parsed, err := strconv.Atoi(arguments["--chunklen"].(string)) 159 if err != nil { 160 failf("error converting: %s", err) 161 } 162 chunklen = int64(parsed) 163 } 164 165 var err error 166 if arguments["seal"].(bool) { 167 err = seal(enckey, signkey, signaturePrefix, nonce, chunklen) 168 } else { 169 err = open(enckey, verifykey, signaturePrefix, nonce, chunklen) 170 } 171 if err != nil { 172 failf("crypto error: %s", err) 173 } 174 }