Skip to content

Instantly share code, notes, and snippets.

@pedroalbanese
Created May 6, 2025 22:03
Show Gist options
  • Save pedroalbanese/d3ffcec2986e195443bdf19265448567 to your computer and use it in GitHub Desktop.
Save pedroalbanese/d3ffcec2986e195443bdf19265448567 to your computer and use it in GitHub Desktop.
EDGETk v1.5.7-gama
//go:generate goversioninfo -manifest=testdata/resource/goversioninfo.exe.manifest
/*
EDGE Toolkit -- Pure Go Command-line Unique Integrated Security Suite
Copyright (C) 2020-2025 Pedro F. Albanese <pedroalbanese@hotmail.com>
This program is free software: you can redistribute it and/or modify it
under the terms of the ISC License.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package main
import (
"bufio"
"bytes"
"crypto"
"crypto/aes"
"crypto/cipher"
"crypto/des"
"crypto/ecdh"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/hmac"
"crypto/md5"
"crypto/rand"
"crypto/rc4"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/ascii85"
"encoding/asn1"
"encoding/gob"
"encoding/base32"
"encoding/base64"
"encoding/binary"
"encoding/hex"
"encoding/pem"
"errors"
"flag"
"fmt"
"golang.org/x/crypto/argon2"
"golang.org/x/crypto/bcrypt"
"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/blake2s"
"golang.org/x/crypto/blowfish"
"golang.org/x/crypto/chacha20"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/hkdf"
"golang.org/x/crypto/md4"
"golang.org/x/crypto/pbkdf2"
"golang.org/x/crypto/poly1305"
"golang.org/x/crypto/ripemd160"
"golang.org/x/crypto/salsa20"
"golang.org/x/crypto/sha3"
"golang.org/x/crypto/twofish"
"golang.org/x/term"
"hash"
"io"
"io/ioutil"
"log"
"math/big"
"math/bits"
"net"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"unsafe"
"sort"
"crypto/go.cypherpunks.su/gogost/v6/gost3410"
"gitee.com/Trisia/gotlcp/tlcp"
"github.com/RyuaNerin/elliptic2/nist"
"github.com/RyuaNerin/go-krypto/aria"
"github.com/RyuaNerin/go-krypto/has160"
"github.com/RyuaNerin/go-krypto/lea"
"github.com/RyuaNerin/go-krypto/lsh256"
"github.com/RyuaNerin/go-krypto/lsh512"
"github.com/RyuaNerin/go-krypto/eckcdsa"
"github.com/RyuaNerin/go-krypto/kx509"
"github.com/deatil/go-cryptobin/cipher/clefia"
"github.com/deatil/go-cryptobin/cipher/saferplus"
"github.com/emmansun/certinfo"
"github.com/emmansun/gmsm/sm2"
"github.com/emmansun/gmsm/sm3"
"github.com/emmansun/gmsm/sm4"
"github.com/emmansun/gmsm/sm9"
"github.com/emmansun/gmsm/sm9/bn256"
"github.com/emmansun/gmsm/smx509"
"github.com/emmansun/gmsm/zuc"
"github.com/emmansun/go-pkcs12"
"github.com/pedroalbanese/bmw"
"github.com/pedroalbanese/brainpool"
"github.com/pedroalbanese/IGE-go/ige"
"github.com/pedroalbanese/anubis"
"github.com/pedroalbanese/belt"
"github.com/pedroalbanese/go-ascon"
"github.com/pedroalbanese/camellia"
"github.com/pedroalbanese/cast256"
"github.com/pedroalbanese/cast5"
"github.com/pedroalbanese/ccm"
"github.com/pedroalbanese/cfb1"
"github.com/pedroalbanese/cfb8"
"github.com/pedroalbanese/cmac"
"github.com/pedroalbanese/crypto/hc128"
"github.com/pedroalbanese/crypto/hc256"
"github.com/pedroalbanese/crypto/serpent"
"github.com/pedroalbanese/crypton"
"github.com/pedroalbanese/crystals-go/crystals-dilithium"
"github.com/pedroalbanese/crystals-go/crystals-kyber"
"github.com/pedroalbanese/cubehash"
"github.com/pedroalbanese/cubehash256"
"github.com/pedroalbanese/curupira1"
"github.com/pedroalbanese/curve448/ed448"
"github.com/pedroalbanese/curve448/x448"
"github.com/pedroalbanese/e2"
"github.com/pedroalbanese/eac"
elgamalphp "github.com/pedroalbanese/eac/elgamal"
"github.com/pedroalbanese/eax"
"github.com/pedroalbanese/ecb"
"github.com/pedroalbanese/echo"
"github.com/pedroalbanese/ecka-eg/core/curves"
"github.com/pedroalbanese/ecka-eg/elgamal"
elgamalAlt "github.com/pedroalbanese/ecka-eg/elgamal-alt"
"github.com/pedroalbanese/esch"
"github.com/pedroalbanese/gmac"
"github.com/pedroalbanese/go-chaskey"
"github.com/pedroalbanese/go-external-ip"
"github.com/pedroalbanese/go-idea"
"github.com/pedroalbanese/go-kcipher2"
"github.com/pedroalbanese/go-krcrypt"
"github.com/pedroalbanese/go-misty1"
"github.com/pedroalbanese/go-rc5"
"github.com/pedroalbanese/go-ripemd"
"github.com/pedroalbanese/gogost/gost28147"
"github.com/pedroalbanese/gogost/gost34112012256"
"github.com/pedroalbanese/gogost/gost34112012512"
"github.com/pedroalbanese/gogost/gost341194"
"github.com/pedroalbanese/gogost/gost341264"
// "github.com/pedroalbanese/gogost/gost3412128"
"github.com/pedroalbanese/gogost/mgm"
"github.com/pedroalbanese/golang-rc6"
"github.com/pedroalbanese/gopass"
"github.com/pedroalbanese/go-grain"
// "github.com/pedroalbanese/groestl-1"
"github.com/pedroalbanese/groestl"
"github.com/pedroalbanese/haraka"
"github.com/pedroalbanese/jh"
"github.com/pedroalbanese/kalyna"
"github.com/pedroalbanese/khazad"
"github.com/pedroalbanese/kupyna"
"github.com/pedroalbanese/kuznechik"
"github.com/pedroalbanese/loki97"
"github.com/pedroalbanese/lyra2re"
"github.com/pedroalbanese/lyra2rev2"
"github.com/pedroalbanese/makwa-go"
"github.com/pedroalbanese/magenta"
"github.com/pedroalbanese/mars"
"github.com/pedroalbanese/md6"
"github.com/pedroalbanese/noekeon"
"github.com/pedroalbanese/ocb"
"github.com/pedroalbanese/ocb3"
"github.com/pedroalbanese/panama"
"github.com/pedroalbanese/pmac"
"github.com/pedroalbanese/present"
"github.com/pedroalbanese/rabbitio"
"github.com/pedroalbanese/randomart"
"github.com/pedroalbanese/rc2"
"github.com/pedroalbanese/shacal2"
"github.com/pedroalbanese/siphash"
"github.com/pedroalbanese/skein"
skeincipher "github.com/pedroalbanese/skein-1"
"github.com/pedroalbanese/spritz"
"github.com/pedroalbanese/threefish"
"github.com/pedroalbanese/tiger"
"github.com/pedroalbanese/trivium"
"github.com/pedroalbanese/twine"
"github.com/pedroalbanese/vmac"
"github.com/pedroalbanese/whirlpool"
"github.com/pedroalbanese/ginga"
gingaHash "github.com/pedroalbanese/ginga/hash"
"github.com/pedroalbanese/xoodoo/xoodyak"
"github.com/zeebo/blake3"
"github.com/kasperdi/SPHINCSPLUS-golang/parameters"
"github.com/kasperdi/SPHINCSPLUS-golang/sphincs"
"github.com/pedroalbanese/go-nums"
"github.com/pedroalbanese/fugue"
"github.com/pedroalbanese/hamsi"
"github.com/pedroalbanese/luffa"
"github.com/pedroalbanese/shavite"
"github.com/pedroalbanese/simd"
"github.com/pedroalbanese/radio_gatun"
"github.com/pedroalbanese/siv"
// "github.com/deatil/go-cryptobin/eckcdsa"
"github.com/pedroalbanese/ecgdsa"
"github.com/pedroalbanese/ecsdsa"
"github.com/pedroalbanese/bip0340"
bigncurves "github.com/pedroalbanese/bign/curves"
"github.com/pedroalbanese/bign"
belthash "github.com/pedroalbanese/belt/hash/belt"
"github.com/pedroalbanese/bash"
"github.com/pedroalbanese/frp256v1"
"github.com/pedroalbanese/secp256k1"
"github.com/pedroalbanese/tom"
bn256i "github.com/pedroalbanese/bn256"
"github.com/cloudflare/circl/sign/bls"
"github.com/cloudflare/circl/ecc/bls12381"
"github.com/cloudflare/circl/ecc/bls12381/ff"
"git.sr.ht/~sircmpwn/go-bare"
)
var (
alg = flag.String("algorithm", "RSA", "Public key algorithm: EC, Ed25519, GOST2012, SM2.")
cacert = flag.String("cacert", "", "CA Certificate path. (for TLCP Protocol)")
cakey = flag.String("cakey", "", "CA Private key. (for TLCP Protocol)")
change = flag.Bool("change", false, "Change Passphrase of a Private Key.")
cert = flag.String("cert", "", "Certificate path.")
check = flag.Bool("check", false, "Check hashsum file. ('-' for STDIN)")
cph = flag.String("cipher", "aes", "Symmetric algorithm: aes, blowfish, magma or sm4.")
crl = flag.String("crl", "", "Certificate Revocation List path.")
crypt = flag.String("crypt", "", "Bulk Encryption with Stream and Block ciphers. [enc|dec|help]")
curveFlag = flag.String("curve", "", "Subjacent curve (secp256r1, secp256k1, bls12381g1/g2.)")
digest = flag.Bool("digest", false, "Target file/wildcard to generate hashsum list. ('-' for STDIN)")
encode = flag.String("hex", "", "Encode binary string to hex format and vice-versa. [enc|dump|dec]")
b85 = flag.String("base85", "", "Encode binary string to Base85 format and vice-versa. [enc|dec]")
b64 = flag.String("base64", "", "Encode binary string to Base64 format and vice-versa. [enc|dec]")
b32 = flag.String("base32", "", "Encode binary string to Base32 format and vice-versa. [enc|dec]")
days = flag.Int("days", 0, "Defines the validity of the certificate from the date of creation.")
factorb = flag.String("blind-factor", "", "Blind Factor in hexadecimal. (for Blind Signatures)")
factorPStr = flag.String("factorp", "", "Makwa private Factor P. (for Makwa Password-hashing Scheme)")
factorQStr = flag.String("factorq", "", "Makwa private Factor Q. (for Makwa Password-hashing Scheme)")
hierarchy = flag.Uint("hid", 0x01, "Hierarchy Identifier. (for SM9 User Private Key)")
id = flag.String("id", "", "User Identifier. (for SM9 User Private Key operations)")
id2 = flag.String("peerid", "", "Remote's side User Identifier. (for SM9 Key Exchange)")
info = flag.String("info", "", "Additional info. (for HKDF command and AEAD bulk encryption)")
iport = flag.String("ipport", "", "Local Port/remote's side Public IP:Port.")
isca = flag.Bool("isca", false, "The requested CSR is for a Certificate Authority (CA).")
iter = flag.Int("iter", 1, "Iter. (for Password-based key derivation function)")
kdf = flag.String("kdf", "", "Key derivation function. [pbkdf2|hkdf|scrypt|argon2|lyra2re2]")
key = flag.String("key", "", "Asymmetric key, symmetric key or HMAC key, depending on operation.")
length = flag.Int("bits", 0, "Key length. (for keypair generation and symmetric encryption)")
mac = flag.String("mac", "", "Compute Hash/Cipher-based message authentication code.")
master = flag.String("master", "Master.pem", "Master key path. (for sm9 setup)")
md = flag.String("md", "sha256", "Hash algorithm: sha256, sha3-256 or whirlpool.")
mode = flag.String("mode", "CTR", "Mode of operation: GCM, MGM, CBC, CFB8, OCB, OFB.")
modulusStr = flag.String("modulus", "", "Makwa modulus. (Makwa hash Public Parameter)")
paramset = flag.String("paramset", "A", "Elliptic curve ParamSet: A, B, C, D. (for GOST2012)")
params = flag.String("params", "", "ElGamal Public Parameters path.")
pkey = flag.String("pkey", "", "Subcommands: keygen|certgen, sign|verify|derive, text|modulus.")
priv = flag.String("prv", "Private.pem", "Private key path. (for keypair generation)")
pub = flag.String("pub", "Public.pem", "Public key path. (for keypair generation)")
pub2 = flag.String("pub2", "", "Public key 2 path. (for keypair generation)")
pwd = flag.String("pass", "", "Password/Passphrase. (for Private key PEM encryption)")
pwd2 = flag.String("passout", "", "User Password. (for SM9 User Private Key PEM encryption)")
random = flag.Int("rand", 0, "Generate random cryptographic key with given bit length.")
recover = flag.Bool("recover", false, "Recover Passphrase from Makwa hash with Private Parameters.")
recursive = flag.Bool("recursive", false, "Process directories recursively. (for DIGEST command only)")
root = flag.String("root", "", "Root CA Certificate path.")
salt = flag.String("salt", "", "Salt. (for HKDF and PBKDF2 commands)")
sig = flag.String("signature", "", "Input signature. (for VERIFY command and MAC verification)")
subj = flag.String("subj", "", "Subject: Identity. (Example: \"/CN=/OU=/O=/ST=/L=/C=/emailAddress=\")")
tcpip = flag.String("tcp", "", "Encrypted TCP/IP Transfer Protocol. [server|ip|client]")
tweakStr = flag.String("tweak", "", "Additional 128-bit parameter input. (for THREEFISH encryption)")
vector = flag.String("iv", "", "Initialization Vector. (for symmetric encryption)")
col = flag.Int("wrap", 64, "Wrap lines after N columns. (for Base64/32 encoding)")
pad = flag.Bool("nopad", false, "No padding. (for Base64 and Base32 encoding)")
version = flag.Bool("version", false, "Print version info.")
commitmentFlag = flag.String("commitment", "", "Commitment for the proof. (for Zero-Knowledge Proof ZKP)")
challengeFlag = flag.String("challenge", "", "Challenge for the proof. (for Zero-Knowledge Proof ZKP)")
responseFlag = flag.String("response", "", "Response for the proof. (for Zero-Knowledge Proof ZKP)")
candidates = flag.String("candidates", "", "List of candidates, separated by commas.")
votesFlag = flag.String("votes", "", "Comma-separated list of vote counters.")
token = flag.String("token", "", "Token containing an encrypted symmetric key.")
)
func publicKey(priv interface{}) interface{} {
switch k := priv.(type) {
case *sm2.PrivateKey:
return &k.PublicKey
case *ecdsa.PrivateKey:
return &k.PublicKey
case *ecdh.PrivateKey:
return k.Public().(*ecdh.PublicKey)
case *gost3410.PrivateKey:
return k.Public().(*gost3410.PublicKey)
case ed25519.PrivateKey:
return k.Public().(ed25519.PublicKey)
case *rsa.PrivateKey:
return &k.PublicKey
default:
return nil
}
}
var (
oidEmailAddress = []int{1, 2, 840, 113549, 1, 9, 1}
oidDomainComponent = []int{0, 9, 2342, 19200300, 100, 1, 25}
oidUserID = []int{0, 9, 2342, 19200300, 100, 1, 1}
oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
oidNSComment = []int{2, 16, 840, 1, 113730, 1, 13}
oidStepProvisioner = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 37476, 9000, 64, 1}
oidStepCertificateAuthority = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 37476, 9000, 64, 2}
oidPublicKeyElGamal = asn1.ObjectIdentifier{1, 3, 14, 7, 2, 1, 1}
//oidSignedCertificateTimestampList = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2}
)
func handleConnectionTLS(c net.Conn) {
log.Printf("Client(TLS) %v connected via secure channel.", c.RemoteAddr())
}
func handleConnectionTLCP(c net.Conn) {
log.Printf("Client(TLCP) %v connected via secure channel.", c.RemoteAddr())
}
func main() {
var pubs PubPaths
var msgs MsgsPaths
flag.Var(&pubs, "pubs", "Paths to the public keys. (can be passed multiple times)")
flag.Var(&msgs, "msgs", "Messages to be verified. (can be passed multiple times)")
flag.Parse()
if *version {
fmt.Println("EDGE Toolkit v1.5.7-beta 20 Apr 2025")
}
if len(os.Args) < 2 {
// fmt.Fprintln(os.Stderr, "Usage of", os.Args[0]+":")
// flag.PrintDefaults()
fmt.Println(`Standard Commands:
crypt digest check kdf
mac pkey rand tcp
Public Key Subcommands:
keygen check text derive
setup pkcs12 fingerprint vko
certgen crl modulus x25519
recover req randomart wrapkey
encrypt validate sign unwrapkey
decrypt x509 verify help
Public Key Algorithms:
bign/dbign eckcdsa gost2012 sm2[ph]
bip0340 ecsdsa koblitz sm9sign[ph]
bls12381[i][ph] ed25519[ph] ml-dsa sm9encrypt
bn256[i][ph] ed448[ph] ml-kem slh-dsa
ecdsa elgamal nums/nums-te x25519
ecgdsa ec-elgamal rsa (default) x448
Subjacent Elliptic Curves:
secp224r1 brainpoolp256r1 numsp384t1 GOST256 Paramset A
secp256r1 brainpoolp384r1 numsp512t1 GOST256 Paramset B
secp384r1 brainpoolp512r1 tom256 GOST256 Paramset C
secp521r1 brainpoolp256t1 tom384 GOST256 Paramset D
sect283r1 brainpoolp384t1 bls12381 GOST512 Paramset A
sect409r1 brainpoolp512t1 ed25519 GOST512 Paramset B
sect571r1 numsp256d1 pallas GOST512 Paramset C
sect283k1 numsp384d1 frp256v1 bign256v1
sect409k1 numsp512d1 secp256k1 bign384v1
sect571k1 numsp256t1 sm2p256v1 bign512v1
Stream Ciphers:
ascon (aead) grain128a rabbit spritz
chacha20 hc128 rc4 [obsolete] trivium
chacha20poly1305 hc256 salsa20 zuc128/eea128
grain (aead) kcipher2 skein zuc256/eea256
Modes of Operation:
eax (aead) siv (aead) cbc ecb
gcm (aead) mgm (aead) cfb/cfb1/cfb8 ige
ocb1/3 (aead) ccm (aead) ctr (default) ofb
Block Ciphers:
3des curupira kuznechik rc6
aes (default) e2 lea safer+
anubis gost89 loki97 seed
aria hight magenta serpent
belt idea [obsolete] magma shacal2
blowfish kalyna128_128 mars sm4
camellia kalyna128_256 misty1 threefish256
cast5 kalyna256_256 noekeon threefish512
cast256 kalyna256_512 present threefish1024
clefia kalyna512_512 rc2 [obsolete] twine
crypton khazad rc5 twofish
Key Derivation Functions:
hkdf pbkdf2 scrypt gost
argon2 blake3 lyra2re/2 help
Password Hash Functions:
argon2 bcrypt lyra2re/2 makwa
Message Athentication Code:
blake3 gost [legacy] pmac vmac
chaskey hmac poly1305 xoodyak
cmac kmac siphash zuc128/eia128
gmac mgmac skein zuc256/eia256
Message Digests:
bash224 fugue512 lsh512 sha3-224
bash256 gost94 lsh512-224 sha3-256
bash384 groestl224 lsh512-256 sha3-384
bash512 groestl256 luffa224 sha3-512
belt groestl384 luffa256 shake128
blake2b256 groestl512 luffa384 shake256
blake2b512 hamsi224 luffa512 shavite224
blake2s128 (MAC) hamsi256 md4 [obsolete] shavite256
blake2s256 hamsi384 md5 [obsolete] shavite384
blake3 hamsi512 md6-224 shavite512
bmw224 haraka256 md6-256 simd224
bmw256 haraka512 md6-384 simd256
bmw384 has160 [obsolete] md6-512 simd384
bmw512 jh224 radiogatun32 simd512
cubehash256 jh256 radiogatun64 siphash64
cubehash512 jh384 ripemd128 siphash
echo224 jh512 ripemd160 skein256
echo256 keccak256 ripemd256 skein512
echo384 keccak512 ripemd320 sm3
echo512 kupyna256 sha1 [obsolete] streebog256
esch256 kupyna384 sha224 streebog512
esch384 kupyna512 sha256 (default) tiger
fugue224 lsh224 sha384 tiger2
fugue256 lsh256 sha512 whirlpool
fugue384 lsh384 sha512-256 xoodyak`)
os.Exit(3)
}
if *crypt == "help" {
fmt.Println(`Syntax:
edgetk -crypt <enc|dec> [-cipher <cipher>] [-iv <iv>] [-key <key>] FILE
PBKDF2 Subcommand Parameters:
[...] -kdf pbkdf2 [-md <hash>] [-iter N] [-salt <salt>] -key "PASS" [...]
Example:
edgetk -crypt enc -kdf pbkdf2 -key "PASSPHRASE" -iter 32768 FILE > OUTPUT
AEAD Modes Subcommand Parameters:
[...] -mode gcm [-info "ADDITIONAL AUTHENTICATED DATA"] [...]
Example:
edgetk -crypt enc -key "HEXKEY" -mode gcm -info "AAD" FILE > OUTPUT`)
os.Exit(3)
}
if *mac == "help" {
fmt.Println(`Syntax:
edgetk -mac <method> [-md <hash>] [-cipher <ciph>] [-key <secret>] FILE
Methods:
cmac, pmac, hmac, chaskey, gost, poly1305, eia128/256, siphash, xoodyak
HMAC:
edgetk -mac hmac [-md sha256] -key <secret> FILE
edgetk -mac hmac [-md sha256] -key <secret> -signature $256bitmac FILE
echo $?
CMAC:
edgetk -mac cmac [-cipher aes] -key <secret> FILE
edgetk -mac cmac [-cipher aes] -key <secret> -signature $128bitmac FILE
echo $?`)
os.Exit(3)
}
if *kdf == "help" {
fmt.Println(`Syntax:
edgetk -kdf <method> [-bits N] [-md <hash>] [-key <secret>] [-salt <salt>]
Methods:
hkdf, pbkdf2, scrypt, argon2, lyra2re, lyra2re2, gost (streebog)
HKDF:
edgetk -kdf hkdf [-bits N] [-salt "SALT"] [-info "AAD"] [-key "IKM"]
Argon2:
edgetk -kdf argon2 [-bits N] [-salt "SALT"] [-iter N] [-key "PASSPHRASE"]
GOST:
edgetk -kdf streebog [-bits N] [-salt "SALT"] [-info "AAD"] [-key "IKM"]
Lyra2:
edgetk -kdf lyra2re [-bits N] [-salt "SALT"] [-iter N] [-key "PASSPHRASE"]
PBKDF2:
edgetk -kdf pbkdf2 [-bits N] [-salt "SALT"] [-iter N] [-key "PASSPHRASE"]
Scrypt[*]:
edgetk -kdf scrypt [-bits N] [-salt "SALT"] [-iter N] [-key "PASSPHRASE"]
[*] scrypt iter must be greater than 1 and a power of 2:
2^10 = 1.024
2^11 = 2.048
2^12 = 4.096 (Minimum Recommended)
2^13 = 8.192
2^14 = 16.384
2^15 = 32.768
2^16 = 65.536
2^17 = 131.072
2^18 = 262.144
2^19 = 524.288
2^20 = 1.048.576`)
os.Exit(3)
}
if *pkey == "help" {
fmt.Println(`Syntax:
edgetk -pkey <command> [-algorithm <alg>] [-key <private>] [-pub <public>]
[-root <cacert>] [-cert <certificate>] [-signature <sign>] [-bits N] FILE
Subcommands:
keygen, certgen, req, x509, check, pkcs12, encrypt, decrypt
derive, x25519, vko, text, modulus, randomart, sign, verify
Generate Key Pair:
edgetk -pkey keygen [-algorithm <alg>] [-prv <private>] [-pub <public>]
Generate Self-Signed Certificate:
edgetk -pkey certgen [-algorithm <alg>] [-key <priv>] [-cert <cert.crt>]
Generate Certificate Sign Request:
edgetk -pkey req [-algorithm <alg>] [-key <private>] [-cert <cert.csr>]
Sign the Certificate Sign Request:
edgetk -pkey x509 [-algorithm <alg>] [-root <cacert>] [-key <private>]
[-cert <certificate.csr>] CERTIFICATE.crt
Generate Certificate Revocation List:
edgetk -pkey crl [-algorithm <alg>] [-cert <cacert>] [-key <private>]
[-crl <old.crl>] [serials.txt] NewCRL.crl
Parse Keypair:
edgetk -pkey <text|modulus> [-pass "passphrase"] [-key <private.pem>]
edgetk -pkey <text|modulus|randomart|fingerprint> [-key <public.pem>]
Parse Certificate/CRL:
edgetk -pkey <text|modulus> [-cert <certificate.pem>]
edgetk -pkey <text> [-crl <crl.pem>]
echo $?
Check Certificate Signature:
edgetk -pkey check [-cert <certificate.pem>] [-key <capublic.pem>]
echo $?
Check CRL Authenticity:
edgetk -pkey check [-cert <cacert.pem>] [-crl <crl.pem>]
echo $?
Validate a Certificate against the CRL:
edgetk -pkey validate [-cert <certificate.pem>] [-crl <crl.pem>]
echo $?
Derive Shared Secret:
edgetk -pkey <derive|vko|x25519> [-key <privatekey>] [-pub <peerkey>]
Digital Signature:
edgetk -pkey <sign|verify> [-algorithm <alg>] [-key <private|public>]
[-md sha256] [-signature <signature>] FILE.ext
Example:
edgetk -pkey sign -key private.pem [-pass "pass"] FILE.ext > sign.txt
sign=$(cat sign.txt|awk '{print $2}')
edgetk -pkey verify -key public.pem -signature $sign FILE.ext
echo $?`)
os.Exit(3)
}
if *tcpip == "help" {
fmt.Println(`Syntax:
edgetk -tcp <server|client> [-cert <cert>] [-key <private>] [-ipport "IP"]
Examples:
edgetk -tcp ip > MyExternalIP.txt
edgetk -tcp server -cert cert.pem -key priv.pem [-ipport "8081"]
edgetk -tcp client -cert cert.pem -key priv.pem [-ipport "127.0.0.1:8081"]`)
os.Exit(3)
}
if (*pkey == "keygen") && (*alg != "sm9encrypt" && *alg != "sm9sign" && *alg != "bn256" && *alg != "bls12381" && *alg != "egphp" && *alg != "elgamalphp") && *pwd == "" {
print("Passphrase: ")
pass, _ := gopass.GetPasswdMasked()
*pwd = string(pass)
} else if (*pkey == "keygen") && (*alg != "sm9encrypt" && *alg != "sm9sign") && *pwd == "nil" {
*pwd = ""
}
if (*pkey == "setup") && *pwd == "" && strings.ToUpper(*alg) != "ELGAMAL" {
print("Passphrase: ")
pass, _ := gopass.GetPasswdMasked()
*pwd = string(pass)
} else if (*pkey == "setup") && *pwd == "nil" && strings.ToUpper(*alg) != "ELGAMAL" {
*pwd = ""
}
if *token != "" {
// Check if the file exists
if info, err := os.Stat(*token); err != nil || info.Size() == 0 {
// File does not exist → Create and save encrypted key
print("Enter a new PIN: ")
pin, _ := gopass.GetPasswdMasked()
// Encrypt the key
encryptedKey, err := encryptKey([]byte(*key), string(pin))
if err != nil {
log.Fatal("Error encrypting key:", err)
}
// Save the encrypted key to the file
err = os.WriteFile(*token, []byte(encryptedKey), 0600)
if err != nil {
log.Fatal("Error writing to token file:", err)
}
fmt.Println("Encrypted key saved successfully.")
} else {
// File exists → Read and decrypt the key
print("Enter PIN: ")
pin, err := term.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
log.Fatal("Error reading PIN:", err)
}
println()
// Read the encrypted key from the file
encryptedKeyBytes, err := os.ReadFile(*token)
if err != nil {
log.Fatal("Error reading token file:", err)
}
encryptedKey := string(encryptedKeyBytes)
// Decrypt the key
decryptedKey, err := decryptKey(encryptedKey, string(pin))
if err != nil {
log.Fatal("Error decrypting key:", err)
}
// fmt.Printf("Decrypted Key: %s\n", decryptedKey)
*key = string(decryptedKey)
}
}
if (*pkey == "keygen") && (*alg == "sm9encrypt" || *alg == "sm9sign") && *pwd == "" {
file, err := os.Open(*master)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
if IsEncryptedPEMBlock(block) {
print("MasterKey Passphrase: ")
pass, _ := gopass.GetPasswd()
*pwd = string(pass)
}
}
if (*pkey == "keygen") && (*alg == "bn256" || *alg == "bls12381") && *pwd == "" {
file, err := os.Open(*master)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
if IsEncryptedPEMBlock(block) {
print("MasterKey Passphrase: ")
pass, _ := gopass.GetPasswd()
*pwd = string(pass)
}
}
if (*pkey == "keygen") && (*alg == "sm9encrypt" || *alg == "sm9sign") && *pwd2 == "" {
print("UserKey Passphrase: ")
pass, _ := gopass.GetPasswdMasked()
*pwd2 = string(pass)
} else if (*pkey == "keygen") && (*alg == "sm9encrypt" || *alg == "sm9sign") && *pwd2 == "nil" {
*pwd2 = ""
}
if (*pkey == "keygen") && (*alg == "bn256" || *alg == "bls12381") && *pwd2 == "" {
print("UserKey Passphrase: ")
pass, _ := gopass.GetPasswdMasked()
*pwd2 = string(pass)
} else if (*pkey == "keygen") && (*alg == "bn256" || *alg == "bls12381") && *pwd2 == "nil" {
*pwd2 = ""
}
if (*pkey == "sign" || *pkey == "decrypt" || *pkey == "derive" || *pkey == "derive-scalar" || *pkey == "aggregate" || *pkey == "aggregate-proof" || *pkey == "aggregate-vote" || *pkey == "aggregate-vote-encrypted" || *pkey == "aggregate-vote-audit" || *pkey == "aggregate-vote-proof" || *pkey == "derivea" || *pkey == "unwrapkey" || *pkey == "deriveb" || *pkey == "certgen" || *pkey == "text" || *pkey == "modulus" || *tcpip == "server" || *tcpip == "client" || *pkey == "pkcs12" || *pkey == "req" || *pkey == "x509" || *pkey == "x25519" || *pkey == "x448" || *pkey == "vko" || *pkey == "crl") && (*key != "" && strings.ToUpper(*alg) != "EGPHP" && strings.ToUpper(*alg) != "ELGAMALPHP") && *pwd == "" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
if IsEncryptedPEMBlock(block) {
print("Passphrase: ")
// pass, _ := gopass.GetPasswd()
pass, err := term.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
log.Fatal("Error reading PIN:", err)
}
println()
*pwd = string(pass)
}
}
if (*tcpip == "server" || *tcpip == "client") && (*alg == "sm2") && (*key != "") && *pwd2 == "" {
file, err := os.Open(*cakey)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
if IsEncryptedPEMBlock(block) {
print("EncKey Passphrase: ")
pass, _ := gopass.GetPasswd()
*pwd2 = string(pass)
}
}
if (*pkey == "pkcs12") && *key == "" && *pwd == "" {
pfxBytes, err := os.ReadFile(*cert)
if err != nil {
log.Fatal(err)
}
_, _, err = pkcs12.Decode(pfxBytes, *pwd)
if err != nil {
print("Passphrase: ")
pass, _ := gopass.GetPasswd()
*pwd = string(pass)
}
}
var myHash func() hash.Hash
switch *md {
case "sha224":
myHash = sha256.New224
case "sha256":
myHash = sha256.New
case "sha384":
myHash = sha512.New384
case "sha512":
myHash = sha512.New
case "sha512-256":
myHash = sha512.New512_256
case "sha1":
myHash = sha1.New
case "rmd160", "ripemd160":
myHash = ripemd160.New
case "rmd128", "ripemd128":
myHash = ripemd.New128
case "rmd256", "ripemd256":
myHash = ripemd.New256
case "rmd320", "ripemd320":
myHash = ripemd.New320
case "sha3-224":
myHash = sha3.New224
case "sha3-256":
myHash = sha3.New256
case "sha3-384":
myHash = sha3.New384
case "sha3-512":
myHash = sha3.New512
case "keccak", "keccak256":
myHash = sha3.NewLegacyKeccak256
case "keccak512":
myHash = sha3.NewLegacyKeccak512
case "shake128":
myHash = func() hash.Hash {
return sha3.NewShake128()
}
case "shake256":
myHash = func() hash.Hash {
return sha3.NewShake256()
}
case "lsh224", "lsh256-224":
myHash = lsh256.New224
case "lsh", "lsh256", "lsh256-256":
myHash = lsh256.New
case "lsh512-256":
myHash = lsh512.New256
case "lsh512-224":
myHash = lsh512.New224
case "lsh384", "lsh512-384":
myHash = lsh512.New384
case "lsh512":
myHash = lsh512.New
case "has160":
myHash = has160.New
case "whirlpool":
myHash = whirlpool.New
case "blake2b256":
myHash = crypto.BLAKE2b_256.New
case "blake2b512":
myHash = crypto.BLAKE2b_512.New
case "blake2s256":
myHash = crypto.BLAKE2s_256.New
case "blake3":
myHash = func() hash.Hash {
return blake3.New()
}
case "md5":
myHash = md5.New
case "gost94":
myHash = func() hash.Hash {
return gost341194.New(&gost28147.SboxIdGostR341194CryptoProParamSet)
}
case "streebog", "streebog256":
myHash = gost34112012256.New
case "streebog512":
myHash = gost34112012512.New
case "sm3":
myHash = sm3.New
case "md4":
myHash = md4.New
case "cubehash", "cubehash512":
myHash = cubehash.New
case "cubehash256":
myHash = cubehash256.New
case "xoodyak", "xhash":
myHash = xoodyak.NewXoodyakHash
case "skein", "skein256":
myHash = func() hash.Hash {
return skein.New256(nil)
}
case "skein512":
myHash = func() hash.Hash {
return skein.New512(nil)
}
case "jh224":
myHash = jh.New224
case "jh", "jh256":
myHash = jh.New256
case "jh384":
myHash = jh.New384
case "jh512":
myHash = jh.New512
case "groestl224":
myHash = groestl.New224
case "groestl", "groestl256":
myHash = groestl.New256
case "groestl384":
myHash = groestl.New384
case "groestl512":
myHash = groestl.New512
case "tiger":
myHash = tiger.New
case "tiger2":
myHash = tiger.New2
case "kupyna256", "kupyna":
myHash = kupyna.New256
case "kupyna384":
myHash = kupyna.New384
case "kupyna512":
myHash = kupyna.New512
case "echo224":
myHash = echo.New224
case "echo", "echo256":
myHash = echo.New256
case "echo384":
myHash = echo.New384
case "echo512":
myHash = echo.New512
case "esch", "esch256":
myHash = esch.New256
case "esch384":
myHash = esch.New384
case "bmw224":
myHash = bmw.New224
case "bmw", "bmw256":
myHash = bmw.New256
case "bmw384":
myHash = bmw.New384
case "bmw512":
myHash = bmw.New512
case "hamsi224":
myHash = hamsi.New224
case "hamsi", "hamsi256":
myHash = hamsi.New256
case "hamsi384":
myHash = hamsi.New384
case "hamsi512":
myHash = hamsi.New512
case "fugue224":
myHash = fugue.New224
case "fugue", "fugue256":
myHash = fugue.New256
case "fugue384":
myHash = fugue.New384
case "fugue512":
myHash = fugue.New512
case "luffa224":
myHash = luffa.New224
case "luffa", "luffa256":
myHash = luffa.New256
case "luffa384":
myHash = luffa.New384
case "luffa512":
myHash = luffa.New512
case "shavite224":
myHash = shavite.New224
case "shavite", "shavite256":
myHash = shavite.New256
case "shavite384":
myHash = shavite.New384
case "shavite512":
myHash = shavite.New512
case "simd224":
myHash = simd.New224
case "simd", "simd256":
myHash = simd.New256
case "simd384":
myHash = simd.New384
case "simd512":
myHash = simd.New512
case "radiogatun", "radiogatun32":
myHash = radio_gatun.New32
case "radiogatun64":
myHash = radio_gatun.New64
case "md6-224":
myHash = md6.New224
case "md6", "md6-256":
myHash = md6.New256
case "md6-384":
myHash = md6.New384
case "md6-512":
myHash = md6.New512
case "belt":
myHash = belthash.New
case "bash224":
myHash = bash.New224
case "bash", "bash256":
myHash = bash.New256
case "bash384":
myHash = bash.New384
case "bash512":
myHash = bash.New512
case "ginga":
myHash = gingaHash.New
case "haraka", "haraka256", "haraka512":
case "bcrypt", "lyra2re", "lyra2re2", "argon2":
case "blake2s128":
case "siphash", "siphash64", "siphash128":
default:
log.Fatalf("Message digest type %s not recognized", *md)
}
var h hash.Hash
switch *md {
case "sha224":
h = sha256.New224()
case "sha256":
h = sha256.New()
case "sha384":
h = sha512.New384()
case "sha512-256":
h = sha512.New512_256()
case "sha512":
h = sha512.New()
case "sha1":
h = sha1.New()
case "rmd160", "ripemd160":
h = ripemd160.New()
case "rmd128", "ripemd128":
h = ripemd.New128()
case "rmd256", "ripemd256":
h = ripemd.New256()
case "rmd320", "ripemd320":
h = ripemd.New320()
case "sha3-224":
h = sha3.New224()
case "sha3-256":
h = sha3.New256()
case "sha3-384":
h = sha3.New384()
case "sha3-512":
h = sha3.New512()
case "shake128":
h = sha3.NewShake128()
case "shake256":
h = sha3.NewShake256()
case "lsh224", "lsh256-224":
h = lsh256.New224()
case "lsh", "lsh256", "lsh256-256":
h = lsh256.New()
case "lsh512-224":
h = lsh512.New224()
case "lsh512-256":
h = lsh512.New256()
case "lsh384", "lsh512-384":
h = lsh512.New384()
case "lsh512":
h = lsh512.New()
case "has160":
h = has160.New()
case "keccak", "keccak256":
h = sha3.NewLegacyKeccak256()
case "keccak512":
h = sha3.NewLegacyKeccak512()
case "whirlpool":
h = whirlpool.New()
case "blake2b256":
h, _ = blake2b.New256([]byte(*key))
case "blake2b512":
h, _ = blake2b.New512([]byte(*key))
case "blake2s128":
h, _ = blake2s.New128([]byte(*key))
case "blake2s256":
h, _ = blake2s.New256([]byte(*key))
case "blake3":
h = blake3.New()
case "md5":
h = md5.New()
case "gost94":
h = gost341194.New(&gost28147.SboxIdGostR341194CryptoProParamSet)
case "streebog", "streebog256":
h = gost34112012256.New()
case "streebog512":
h = gost34112012512.New()
case "sm3":
h = sm3.New()
case "md4":
h = md4.New()
case "siphash", "siphash128":
var xkey [16]byte
copy(xkey[:], []byte(*key))
h, _ = siphash.New128(xkey[:])
case "siphash64":
var xkey [16]byte
copy(xkey[:], []byte(*key))
h, _ = siphash.New64(xkey[:])
case "cubehash", "cubehash512":
h = cubehash.New()
case "xoodyak", "xhash":
h = xoodyak.NewXoodyakHash()
case "skein", "skein256":
h = skein.New256([]byte(*key))
case "skein512":
h = skein.New512([]byte(*key))
case "jh224":
h = jh.New224()
case "jh", "jh256":
h = jh.New256()
case "jh384":
h = jh.New384()
case "jh512":
h = jh.New512()
case "groestl224":
h = groestl.New224()
case "groestl", "groestl256":
h = groestl.New256()
case "groestl384":
h = groestl.New384()
case "groestl512":
h = groestl.New512()
case "tiger":
h = tiger.New()
case "tiger2":
h = tiger.New2()
case "kupyna256", "kupyna":
h = kupyna.New256()
case "kupyna384":
h = kupyna.New384()
case "kupyna512":
h = kupyna.New512()
case "echo224":
h = echo.New224()
case "echo", "echo256":
h = echo.New256()
case "echo384":
h = echo.New384()
case "echo512":
h = echo.New512()
case "esch", "esch256":
h = esch.New256()
case "esch384":
h = esch.New384()
case "bmw224":
h = bmw.New224()
case "bmw", "bmw256":
h = bmw.New256()
case "bmw384":
h = bmw.New384()
case "bmw512":
h = bmw.New512()
case "cubehash256":
h = cubehash256.New()
case "hamsi224":
h = hamsi.New224()
case "hamsi", "hamsi256":
h = hamsi.New256()
case "hamsi384":
h = hamsi.New384()
case "hamsi512":
h = hamsi.New512()
case "fugue224":
h = fugue.New224()
case "fugue", "fugue256":
h = fugue.New256()
case "fugue384":
h = fugue.New384()
case "fugue512":
h = fugue.New512()
case "luffa224":
h = luffa.New224()
case "luffa", "luffa256":
h = luffa.New256()
case "luffa384":
h = luffa.New384()
case "luffa512":
h = luffa.New512()
case "shavite224":
h = shavite.New224()
case "shavite", "shavite256":
h = shavite.New256()
case "shavite384":
h = shavite.New384()
case "shavite512":
h = shavite.New512()
case "simd224":
h = simd.New224()
case "simd", "simd256":
h = simd.New256()
case "simd384":
h = simd.New384()
case "simd512":
h = simd.New512()
case "radiogatun", "radiogatun32":
h = radio_gatun.New32()
case "radiogatun64":
h = radio_gatun.New64()
case "md6-224":
h = md6.New224()
case "md6", "md6-256":
h = md6.New256()
case "md6-384":
h = md6.New384()
case "md6-512":
h = md6.New512()
case "belt":
h = belthash.New()
case "bash224":
h = bash.New224()
case "bash", "bash256":
h = bash.New256()
case "bash384":
h = bash.New384()
case "bash512":
h = bash.New512()
case "ginga":
h = gingaHash.New()
case "haraka", "haraka256", "haraka512":
case "bcrypt", "lyra2re", "lyra2re2", "argon2":
default:
log.Fatalf("Message digest type %s not recognized", *md)
}
if *random != 0 {
var key []byte
var err error
key = make([]byte, *random/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Println(hex.EncodeToString(key))
os.Exit(0)
}
Files := strings.Join(flag.Args(), " ")
var inputfile io.Reader
var inputdesc string
var err error
if (Files == "-" || Files == "" || strings.Contains(Files, "*")) {
inputfile = os.Stdin
inputdesc = "stdin"
} else if *pkey != "x509" && *pkey != "req" && *pkey != "wrapkey" {
inputfile, err = os.Open(flag.Arg(0))
if err != nil {
log.Fatalf("failed opening file: %s", err)
}
inputdesc = flag.Arg(0)
}
if (strings.ToUpper(*alg) == "ELGAMALPHP" || strings.ToUpper(*alg) == "EGPHP") && flag.Arg(0) != "" {
inputfile, err = os.Open(flag.Arg(0))
if err != nil {
log.Fatalf("failed opening file: %s", err)
}
} else if (strings.ToUpper(*alg) == "ELGAMALPHP" || strings.ToUpper(*alg) == "EGPHP") && flag.Arg(0) == "" {
inputfile = os.Stdin
}
if *encode == "enc" {
// b, err := ioutil.ReadAll(os.Stdin)
b, err := ioutil.ReadAll(inputfile)
if len(b) == 0 {
os.Exit(0)
}
if err != nil {
log.Fatal(err)
}
o := make([]byte, hex.EncodedLen(len(b)))
hex.Encode(o, b)
o = append(o, '\n')
os.Stdout.Write(o)
os.Exit(0)
} else if *encode == "dec" {
var err error
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
b := strings.TrimSuffix(string(buf.Bytes()), "\r\n")
b = strings.TrimSuffix(string(b), "\n")
if !isHexDump(b) {
data, err := decodeHexDump(b)
if err != nil {
log.Fatal(err)
}
os.Stdout.Write(data)
os.Exit(0)
}
if len(b) == 0 {
os.Exit(0)
}
if len(b) < 2 {
os.Exit(0)
}
if (len(b)%2 != 0) || (err != nil) {
log.Fatal(err)
}
o := make([]byte, hex.DecodedLen(len(b)))
_, err = hex.Decode(o, []byte(b))
if err != nil {
log.Fatal(err)
}
os.Stdout.Write(o)
os.Exit(0)
} else if *encode == "dump" {
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
dump := hex.Dump(buf.Bytes())
os.Stdout.Write([]byte(dump))
os.Exit(0)
} else if *encode == "split" {
data, _ := ioutil.ReadAll(inputfile)
b := strings.TrimSuffix(string(data), "\r\n")
b = strings.TrimSuffix(b, "\n")
print(len(b)/2, " bytes ", len(b)*4, " bits\n")
splitx := SplitSubN(b, 4)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitx), "[]"), 40) {
fmt.Println(strings.ToUpper(chunk))
}
} else if *encode == "split+" {
data, _ := ioutil.ReadAll(inputfile)
b := strings.TrimSuffix(string(data), "\r\n")
b = strings.TrimSuffix(b, "\n")
print(len(b)/2, " bytes ", len(b)*4, " bits\n")
splitx := SplitSubN(b, 4)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitx), "[]"), 80) {
fmt.Println(strings.ToUpper(chunk))
}
} else if *encode == "join" {
data, _ := ioutil.ReadAll(inputfile)
join := strings.ReplaceAll(string(data), " ", "")
join = strings.ReplaceAll(join, "\r\n", "")
join = strings.ReplaceAll(join, "\n", "")
fmt.Println(strings.ToLower(join))
}
if *b85 == "enc" || *b85 == "dec" {
if *col == 0 && len(flag.Args()) > 0 {
inputFile := flag.Arg(0)
data, err := ioutil.ReadFile(inputFile)
if err != nil {
fmt.Println("Error reading the file:", err)
os.Exit(1)
}
inputData := string(data)
if *b85 == "enc" {
fmt.Print(encodeAscii85([]byte(inputData)))
} else {
decoder := ascii85.NewDecoder(strings.NewReader(inputData))
decodedData, err := ioutil.ReadAll(decoder)
if err != nil {
fmt.Println("Error decoding data:", err)
os.Exit(1)
}
fmt.Print(string(decodedData))
}
} else {
var inputData string
if len(flag.Args()) == 0 {
data, _ := ioutil.ReadAll(os.Stdin)
inputData = string(data)
} else {
inputFile := flag.Arg(0)
data, err := ioutil.ReadFile(inputFile)
if err != nil {
fmt.Println("Error reading the file:", err)
os.Exit(1)
}
inputData = string(data)
}
if *col != 0 {
if *b85 == "enc" {
printChunks(encodeAscii85([]byte(inputData)), *col)
} else {
decoder := ascii85.NewDecoder(strings.NewReader(inputData))
decodedData, err := ioutil.ReadAll(decoder)
if err != nil {
fmt.Println("Error decoding data:", err)
os.Exit(1)
}
fmt.Print(string(decodedData))
}
} else {
if *b85 == "enc" {
fmt.Print(encodeAscii85([]byte(inputData)))
} else {
decoder := ascii85.NewDecoder(strings.NewReader(inputData))
decodedData, err := ioutil.ReadAll(decoder)
if err != nil {
fmt.Println("Error decoding data:", err)
os.Exit(1)
}
fmt.Print(string(decodedData))
}
}
}
}
if *b64 == "enc" || *b64 == "dec" {
if *col == 0 && len(flag.Args()) > 0 {
inputFile := flag.Arg(0)
data, err := ioutil.ReadFile(inputFile)
if err != nil {
fmt.Println("Error reading the file:", err)
os.Exit(1)
}
inputData := string(data)
if *b64 == "enc" && *pad == false {
sEnc := base64.StdEncoding.EncodeToString([]byte(inputData))
fmt.Println(sEnc)
} else if *b64 == "enc" && *pad == true {
sEnc := base64.StdEncoding.WithPadding(-1).EncodeToString([]byte(inputData))
fmt.Println(sEnc)
}
} else {
var inputData string
if len(flag.Args()) == 0 {
data, _ := ioutil.ReadAll(os.Stdin)
inputData = string(data)
} else {
inputFile := flag.Arg(0)
data, err := ioutil.ReadFile(inputFile)
if err != nil {
fmt.Println("Error reading the file:", err)
os.Exit(1)
}
inputData = string(data)
}
if *col != 0 {
if *b64 == "enc" && *pad == false {
sEnc := base64.StdEncoding.EncodeToString([]byte(inputData))
for _, chunk := range split(sEnc, *col) {
fmt.Println(chunk)
}
} else if *b64 == "dec" && *pad == false {
sDec, _ := base64.StdEncoding.DecodeString(inputData)
os.Stdout.Write(sDec)
}
if *b64 == "enc" && *pad == true {
sEnc := base64.StdEncoding.WithPadding(-1).EncodeToString([]byte(inputData))
for _, chunk := range split(sEnc, *col) {
fmt.Println(chunk)
}
} else if *b64 == "dec" && *pad == true {
sDec, _ := base64.StdEncoding.WithPadding(-1).DecodeString(inputData)
os.Stdout.Write(sDec)
}
} else {
if *b64 == "enc" && *pad == false {
sEnc := base64.StdEncoding.EncodeToString([]byte(inputData))
fmt.Println(sEnc)
} else if *b64 == "dec" && *pad == false {
sDec, _ := base64.StdEncoding.DecodeString(inputData)
os.Stdout.Write(sDec)
}
if *b64 == "enc" && *pad == true {
sEnc := base64.StdEncoding.WithPadding(-1).EncodeToString([]byte(inputData))
fmt.Println(sEnc)
} else if *b64 == "dec" && *pad == true {
sDec, _ := base64.StdEncoding.WithPadding(-1).DecodeString(inputData)
os.Stdout.Write(sDec)
}
}
}
}
if *b32 == "enc" || *b32 == "dec" {
if *col == 0 && len(flag.Args()) > 0 {
inputFile := flag.Arg(0)
data, err := ioutil.ReadFile(inputFile)
if err != nil {
fmt.Println("Error reading the file:", err)
os.Exit(1)
}
inputData := string(data)
if *b32 == "enc" && *pad == false {
sEnc := base32.StdEncoding.EncodeToString([]byte(inputData))
fmt.Println(sEnc)
} else if *b32 == "enc" && *pad == true {
sEnc := base32.StdEncoding.WithPadding(-1).EncodeToString([]byte(inputData))
fmt.Println(sEnc)
}
} else {
var inputData string
if len(flag.Args()) == 0 {
data, _ := ioutil.ReadAll(os.Stdin)
inputData = string(data)
} else {
inputFile := flag.Arg(0)
data, err := ioutil.ReadFile(inputFile)
if err != nil {
fmt.Println("Error reading the file:", err)
os.Exit(1)
}
inputData = string(data)
}
if *col != 0 {
if *b32 == "enc" && *pad == false {
sEnc := base32.StdEncoding.EncodeToString([]byte(inputData))
for _, chunk := range split(sEnc, *col) {
fmt.Println(chunk)
}
} else if *b32 == "dec" && *pad == false {
sDec, _ := base32.StdEncoding.DecodeString(inputData)
os.Stdout.Write(sDec)
}
if *b32 == "enc" && *pad == true {
sEnc := base32.StdEncoding.WithPadding(-1).EncodeToString([]byte(inputData))
for _, chunk := range split(sEnc, *col) {
fmt.Println(chunk)
}
} else if *b32 == "dec" && *pad == true {
sDec, _ := base32.StdEncoding.WithPadding(-1).DecodeString(inputData)
os.Stdout.Write(sDec)
}
} else {
if *b32 == "enc" && *pad == false {
sEnc := base32.StdEncoding.EncodeToString([]byte(inputData))
fmt.Println(sEnc)
} else if *b32 == "dec" && *pad == false {
sDec, _ := base32.StdEncoding.DecodeString(inputData)
os.Stdout.Write(sDec)
}
if *b32 == "enc" && *pad == true {
sEnc := base32.StdEncoding.WithPadding(-1).EncodeToString([]byte(inputData))
fmt.Println(sEnc)
} else if *b32 == "dec" && *pad == true {
sDec, _ := base32.StdEncoding.WithPadding(-1).DecodeString(inputData)
os.Stdout.Write(sDec)
}
}
}
}
if (*cph == "aes" || *cph == "aria" || *cph == "mars" || *cph == "cast256" || *cph == "cast6" || *cph == "clefia" || *cph == "kalyna128_256" || *cph == "kalyna256_256" || *cph == "crypton" || *cph == "e2" || *cph == "loki97" || *cph == "grasshopper" || *cph == "kuznechik" || *cph == "magma" || *cph == "gost89" || *cph == "camellia" || *cph == "chacha20poly1305" || *cph == "chacha20" || *cph == "salsa20" || *cph == "twofish" || *cph == "lea" || *cph == "hc256" || *cph == "eea256" || *cph == "zuc256" || *cph == "skein" || *cph == "serpent" || *cph == "rc6" || *cph == "magenta" || *cph == "belt") && *pkey != "keygen" && (*length != 256 && *length != 192 && *length != 128) && *crypt != "" {
*length = 256
}
if (*cph == "shacal2") && *pkey != "keygen" && (*length != 128 && *length != 192 && *length != 256 && *length != 320 && *length != 448 && *length != 512) && *crypt != "" {
*length = 256
}
if *mac == "skein" && *length == 0 {
*length = 256
}
if *cph == "3des" && *pkey != "keygen" && *length != 192 && *crypt != "" {
*length = 192
}
if (*cph == "blowfish" || *cph == "cast5" || *cph == "idea" || *cph == "rc2" || *cph == "rc5" || *cph == "rc4" || *cph == "sm4" || *cph == "seed" || *cph == "hight" || *cph == "misty1" || *cph == "khazad" || *cph == "noekeon" || *cph == "xoodyak" || *cph == "hc128" || *cph == "eea128" || *cph == "zuc128" || *cph == "ascon" || *cph == "grain128a" || *cph == "grain128aead" || *cph == "kcipher2" || *cph == "rabbit" || *cph == "kalyna128_128") && *pkey != "keygen" && (*length != 128) && *crypt != "" {
*length = 128
}
if (*cph == "saferplus" || *cph == "safer+") && *pkey != "keygen" && (*length != 64 && *length != 128) && *crypt != "" {
*length = 128
}
if (*cph == "present" || *cph == "twine") && *pkey != "keygen" && (*length != 80 && *length != 128) && *crypt != "" {
*length = 128
}
if (*cph == "curupira") && *pkey != "keygen" && (*length != 96 && *length != 144 && *length != 192) && *crypt != "" {
*length = 96
}
if (*cph == "anubis") && *pkey != "keygen" && (*length < 128 || *length > 320) && *crypt != "" {
*length = 128
}
if (*cph == "ginga") && *pkey != "keygen" && (*length != 256) && *crypt != "" {
*length = 256
}
if (*cph == "threefish" || *cph == "threefish256") && *pkey != "keygen" && (*length != 256) && *crypt != "" {
*length = 256
}
if (*cph == "threefish512" || *cph == "kalyna256_512" || *cph == "kalyna512_512") && *pkey != "keygen" && (*length != 512) && *crypt != "" {
*length = 512
}
if (*cph == "threefish1024") && *pkey != "keygen" && (*length != 1024) && *crypt != "" {
*length = 1024
}
if (*mac == "eia256" || *mac == "zuc256") && (*length != 32 && *length != 64 && *length != 128) {
*length = 128
}
if *cph == "des" && *pkey != "keygen" && *length != 64 && *crypt != "" {
*length = 64
}
if strings.ToUpper(*alg) == "RSA" && *pkey == "keygen" && *length == 0 {
*length = 3072
}
if (strings.ToUpper(*alg) == "NUMS" || strings.ToUpper(*alg) == "NUMS-TE") && *pkey == "keygen" && *length == 0 {
*length = 256
}
if *pkey == "wrapkey" && *cph == "aes" {
*cph = ""
}
if strings.ToUpper(*alg) == "ML-KEM" && *pkey == "keygen" && *length == 0 {
*length = 768
}
if strings.ToUpper(*alg) == "ML-DSA" && *pkey == "keygen" && *length == 0 {
*length = 3072
}
if strings.ToUpper(*alg) == "MAKWA" && *length == 0 {
*length = 2048
}
if strings.ToUpper(*alg) == "MAKWA" && *iter == 1 {
*iter = 4096
}
if (strings.ToUpper(*alg) == "ELGAMAL" && *pkey != "wrapkey" && *pkey != "unwrapkey") && *length == 0 {
*length = 3072
}
if *digest && *md == "spritz" && *length == 0 {
*length = 256
}
if (*pkey == "wrapkey" || *pkey == "unwrapkey") && *length == 0 {
*length = 128
}
if (*pkey == "derivea" || *pkey == "deriveb") && *length == 0 {
*length = 128
}
if *kdf == "scrypt" && *iter == 1 {
*iter = 4096
}
if (strings.ToUpper(*md) == "ARGON2" || strings.ToUpper(*kdf) == "ARGON2" || strings.ToUpper(*kdf) == "SCRYPT" || strings.ToUpper(*kdf) == "PBKDF2" || strings.ToUpper(*kdf) == "HKDF" || strings.ToUpper(*kdf) == "BLAKE3" || strings.ToUpper(*kdf) == "LYRA2RE" || strings.ToUpper(*kdf) == "LYRA2RE2" || strings.ToUpper(*kdf) == "STREEBOG256" || strings.ToUpper(*kdf) == "STREEBOG" || strings.ToUpper(*kdf) == "GOST") && *length == 0 {
*length = 256
}
if (strings.ToUpper(*alg) == "GOST2012" || strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA" || strings.ToUpper(*alg) == "ECGDSA" || strings.ToUpper(*alg) == "ECSDSA" || strings.ToUpper(*alg) == "BIP0340" || strings.ToUpper(*alg) == "ECKCDSA" || strings.ToUpper(*alg) == "BIGN" || strings.ToUpper(*alg) == "TOM") && *pkey == "keygen" && *length == 0 && *curveFlag == "" {
*length = 256
}
if strings.ToUpper(*mac) == "VMAC" && *length == 0 {
*length = 64
}
if strings.ToUpper(*mode) == "SIV" {
*length = *length*2
}
if *kdf == "pbkdf2" {
keyRaw := pbkdf2.Key([]byte(*key), []byte(*salt), *iter, *length/8, myHash)
*key = hex.EncodeToString(keyRaw)
if *crypt == "" {
fmt.Println(*key)
os.Exit(0)
}
}
if *kdf == "scrypt" {
keyRaw, err := Scrypt([]byte(*key), []byte(*salt), *iter, 8, 1, *length/8)
if err != nil {
log.Fatal(err)
}
*key = hex.EncodeToString(keyRaw)
if *crypt == "" {
fmt.Println(*key)
os.Exit(0)
}
}
if *kdf == "argon2" {
hash := argon2.IDKey([]byte(*key), []byte(*salt), uint32(*iter), 64*1024, 4, uint32(*length/8))
*key = hex.EncodeToString(hash)
if *crypt == "" {
fmt.Println(*key)
return
}
}
if *kdf == "lyra2re" {
data := []byte(*key + *salt)
for i := 0; i < *iter; i++ {
hash, _ := lyra2re.Sum(data)
if err != nil {
log.Fatal(err)
}
data = hash
}
derivedKey := data[:*length/8]
*key = hex.EncodeToString(derivedKey)
if *crypt == "" {
fmt.Println(*key)
return
}
}
if *kdf == "lyra2re2" {
data := []byte(*key + *salt)
for i := 0; i < *iter; i++ {
hash, _ := lyra2re2.Sum(data)
if err != nil {
log.Fatal(err)
}
data = hash
}
derivedKey := data[:*length/8]
*key = hex.EncodeToString(derivedKey)
if *crypt == "" {
fmt.Println(*key)
return
}
}
if *kdf == "streebog256" || *kdf == "streebog" || *kdf == "gost" {
kdf := gost34112012256.NewKDF([]byte(*key))
derivedKey := kdf.Derive(nil, []byte(*salt), []byte(*info))
*key = hex.EncodeToString(derivedKey[:*length/8])
if *crypt == "" {
fmt.Println(*key)
os.Exit(0)
}
}
if *kdf == "blake3" {
out := make([]byte, *length/8)
blake3.DeriveKey(*info, []byte(*key), out)
*key = hex.EncodeToString(out)
if *crypt == "" {
fmt.Println(*key)
os.Exit(0)
}
}
if *crypt != "" && (*cph == "rc4") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 16)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 32 && len(key) != 16 && len(key) != 5 {
log.Fatal("Invalid key size.")
}
}
ciph, _ := rc4.NewCipher(key)
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && *cph == "spritz" {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 32)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
}
var nonce []byte
if *vector != "" {
nonce, _ = hex.DecodeString(*vector)
} else {
nonce = make([]byte, 32)
fmt.Fprintf(os.Stderr, "IV= %x\n", nonce)
}
buf := bytes.NewBuffer(nil)
var data io.Reader
// data = os.Stdin
data = inputfile
io.Copy(buf, data)
msg := buf.Bytes()
if flag.NArg() > 0 {
file, err := os.Open(flag.Arg(0))
if err != nil {
log.Fatal(err)
}
defer file.Close()
inputfile = file
} else {
inputfile = os.Stdin
}
if *crypt == "enc" {
out := spritz.EncryptWithIV(key, nonce, msg)
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
out := spritz.DecryptWithIV(key, nonce, msg)
fmt.Printf("%s", out)
os.Exit(0)
}
os.Exit(0)
}
if *digest && *md == "spritz" {
buf := bytes.NewBuffer(nil)
var data io.Reader
// data = os.Stdin
data = inputfile
io.Copy(buf, data)
msg := buf.Bytes()
out := spritz.Hash(msg, byte(*length/8))
fmt.Printf("%x\n", out)
os.Exit(0)
}
if *crypt != "" && *cph == "trivium" {
var keyHex string
keyHex = *key
var keyRaw []byte
var key = [10]byte{}
var err error
if keyHex != "" {
raw, err := hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
key = *byte10(raw)
if err != nil {
log.Fatal(err)
}
if len(key) != trivium.KeyLength {
log.Fatal(err)
}
} else {
keyRaw = make([]byte, 10)
_, err = io.ReadFull(rand.Reader, keyRaw)
if err != nil {
log.Fatal(err)
}
key = *byte10(keyRaw)
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key[:]))
}
var iv = [10]byte{}
if *vector == "" {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
} else {
raw, err := hex.DecodeString(*vector)
if err != nil {
log.Fatal(err)
}
iv = *byte10(raw)
if err != nil {
log.Fatal(err)
}
}
var trivium = trivium.NewTrivium(key, iv)
// reader := bufio.NewReader(os.Stdin)
reader := bufio.NewReader(inputfile)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var b byte
for b, err = reader.ReadByte(); err == nil; b, err = reader.ReadByte() {
kb := trivium.NextByte()
err := writer.WriteByte(b ^ kb)
if err != nil {
log.Fatalf("error writing")
}
}
if err != io.EOF {
log.Fatalf("error reading")
}
}
if *crypt != "" && *cph == "panama" {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 32)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 32 {
log.Fatal("Invalid key size.")
}
}
ciph, _ := panama.NewCipher(key)
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && *cph == "rabbit" {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 16)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 16 {
log.Fatal("Invalid key size.")
}
}
var nonce []byte
if *vector != "" {
nonce, _ = hex.DecodeString(*vector)
} else {
nonce = make([]byte, 8)
fmt.Fprintf(os.Stderr, "IV= %x\n", nonce)
}
ciph, _ := rabbitio.NewCipher(key, nonce)
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && (*cph == "kcipher2") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 16)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 16 {
log.Fatal("Invalid key size.")
}
}
var iv []byte
iv = make([]byte, 16)
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
}
ciph, _ := kcipher2.New(iv, key)
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && (*cph == "xoodyak") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 16)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 16 {
log.Fatal("Invalid key size.")
}
}
buf := bytes.NewBuffer(nil)
var data io.Reader
// data = os.Stdin
data = inputfile
io.Copy(buf, data)
msg := buf.Bytes()
aead, err := xoodyak.NewXoodyakAEAD(key)
if err != nil {
panic(err)
}
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
}
if *crypt != "" && *cph == "grain128a" {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 16)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 16 {
log.Fatal("Invalid key size.")
}
}
var nonce []byte
nonce = make([]byte, 12)
var iv []byte
iv = make([]byte, 12)
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
copy(nonce[:], iv)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
}
ciph, err := grain.NewUnauthenticated(key, iv)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && (*cph == "ascon" || *cph == "grain128aead" || *cph == "grain") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 16)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 16 {
log.Fatal("Invalid key size.")
}
}
buf := bytes.NewBuffer(nil)
var data io.Reader
// data = os.Stdin
data = inputfile
io.Copy(buf, data)
msg := buf.Bytes()
var aead cipher.AEAD
if *cph == "ascon" {
aead, err = ascon.New128a(key)
} else if (*cph == "grain128aead" || *cph == "grain") {
aead, err = grain.New(key)
}
if err != nil {
log.Fatal(err)
}
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
}
if *crypt != "" && (*cph == "chacha20poly1305") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 32)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 32 {
log.Fatal("Invalid key size.")
}
}
aead, err := chacha20poly1305.New(key)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// io.Copy(buf, os.Stdin)
io.Copy(buf, inputfile)
msg := buf.Bytes()
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
os.Exit(0)
}
if *crypt != "" && (*cph == "chacha20") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 32)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 32 {
log.Fatal("Invalid key size.")
}
}
var nonce []byte
nonce = make([]byte, 12)
var iv []byte
iv = make([]byte, 12)
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
copy(nonce[:], iv)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
}
ciph, _ := chacha20.NewUnauthenticatedCipher(key, nonce)
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && (*cph == "salsa20") {
var keyHex string
keyHex = *key
var err error
var key = [32]byte{}
var raw []byte
if keyHex == "" {
raw := make([]byte, 32)
_, err = io.ReadFull(rand.Reader, raw)
if err != nil {
log.Fatal(err)
}
key = *byte32(raw)
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key[:]))
} else {
raw, _ = hex.DecodeString(keyHex)
copy(key[:], raw)
}
var nonce []byte
nonce = make([]byte, 24)
var iv []byte
iv = make([]byte, 24)
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
copy(nonce[:], iv)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
}
buf := make([]byte, 64*1<<10)
var n int
for {
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
salsa20.XORKeyStream(buf[:n], buf[:n], nonce[:], &key)
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && (*cph == "skein") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 32)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
}
var nonce []byte
nonce = make([]byte, 32)
var iv []byte
iv = make([]byte, 32)
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
copy(nonce[:], iv)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
}
ciph := skeincipher.NewStream(key, nonce)
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && (*cph == "hc128" || *cph == "hc256") {
var keyHex string
var keyRaw []byte
var err error
keyHex = *key
var ciph cipher.Stream
if *cph == "hc256" {
var key [32]byte
if keyHex != "" {
raw, _ := hex.DecodeString(keyHex)
key = *byte32(raw)
} else {
keyRaw = make([]byte, 32)
_, err = io.ReadFull(rand.Reader, keyRaw)
if err != nil {
log.Fatal(err)
}
key = *byte32(keyRaw)
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key[:]))
}
var nonce [32]byte
var iv []byte
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
copy(nonce[:], iv)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", nonce)
}
ciph = hc256.NewCipher(&nonce, &key)
if len(key) != 32 {
log.Fatal("Invalid key size.")
}
} else if *cph == "hc128" {
var key [16]byte
var raw []byte
if keyHex != "" {
raw, _ = hex.DecodeString(keyHex)
key = *byte16(raw)
} else {
keyRaw = make([]byte, 16)
_, err = io.ReadFull(rand.Reader, keyRaw)
if err != nil {
log.Fatal(err)
}
key = *byte16(keyRaw)
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key[:]))
}
var iv []byte
var nonce [16]byte
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
copy(nonce[:], iv)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", nonce)
}
copy(key[:], raw)
ciph = hc128.NewCipher(&nonce, &key)
if len(key) != 16 {
log.Fatal("Invalid key size.")
}
}
buf := make([]byte, 128*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt == "eea256" || (*crypt != "" && *cph == "zuc256") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 32)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 32 {
log.Fatal("Invalid key size.")
}
}
var nonce []byte
if *vector != "" {
nonce, _ = hex.DecodeString(*vector)
} else {
nonce = make([]byte, 23)
fmt.Fprintf(os.Stderr, "IV= %x\n", nonce)
}
ciph, _ := zuc.NewCipher(key, nonce)
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt == "eea128" || (*crypt != "" && *cph == "zuc128") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, 16)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 16 {
log.Fatal("Invalid key size.")
}
}
var nonce []byte
if *vector != "" {
nonce, _ = hex.DecodeString(*vector)
} else {
nonce = make([]byte, 16)
fmt.Fprintf(os.Stderr, "IV= %x\n", nonce)
}
ciph, _ := zuc.NewCipher(key, nonce)
buf := make([]byte, 64*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
ciph.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *mac == "eia256" || *mac == "zuc256" {
var keyHex string
var keyRaw []byte
keyHex = *key
var err error
if keyHex == "" {
keyRaw = make([]byte, 256/8)
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(keyRaw))
} else {
keyRaw, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(keyRaw) != 32 {
log.Fatal("Invalid key size.")
}
}
var nonce []byte
if *vector != "" {
nonce, err = hex.DecodeString(*vector)
if err != nil {
log.Fatal(err)
}
} else {
nonce = make([]byte, 184/8)
fmt.Fprintln(os.Stderr, "IV=", hex.EncodeToString(nonce))
}
h, _ := zuc.NewHash256(keyRaw, nonce, *length/8)
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Printf("MAC-%s= %x\n", strings.ToUpper(*mac)+"("+inputdesc+")", h.Sum(nil))
os.Exit(0)
}
if *mac == "eia128" || *mac == "zuc128" {
var keyHex string
var keyRaw []byte
keyHex = *key
var err error
if keyHex == "" {
keyRaw = make([]byte, 128/8)
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(keyRaw))
} else {
keyRaw, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(keyRaw) != 16 {
log.Fatal("Invalid key size.")
}
}
var nonce []byte
if *vector != "" {
nonce, err = hex.DecodeString(*vector)
if err != nil {
log.Fatal(err)
}
} else {
nonce = make([]byte, 128/8)
fmt.Fprintln(os.Stderr, "IV=", hex.EncodeToString(nonce))
}
h, _ := zuc.NewHash(keyRaw, nonce)
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Printf("MAC-%s= %x\n", strings.ToUpper(*mac)+"("+inputdesc+")", h.Sum(nil))
os.Exit(0)
}
if *mac == "chaskey" {
var keyRaw []byte
if *key == "" {
keyRaw = []byte("0000000000000000")
fmt.Fprintf(os.Stderr, "Key= %s\n", keyRaw)
} else {
keyRaw = []byte(*key)
}
if len([]byte(keyRaw)) != 16 {
log.Fatal("CHASKEY secret key must have 16 bytes.")
}
xkey := [4]uint32{binary.LittleEndian.Uint32([]byte(keyRaw)[:]),
binary.LittleEndian.Uint32([]byte(keyRaw)[4:]),
binary.LittleEndian.Uint32([]byte(keyRaw)[8:]),
binary.LittleEndian.Uint32([]byte(keyRaw)[12:]),
}
var t [32]byte
h := chaskey.New(xkey)
line, _ := ioutil.ReadAll(inputfile)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.MAC(line, t[:]))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Printf("MAC-CHASKEY("+inputdesc+")= %s\n", hex.EncodeToString(h.MAC(line, t[:])))
os.Exit(0)
}
if *crypt != "" && (*cph == "blowfish" || *cph == "idea" || *cph == "cast5" || *cph == "rc2" || *cph == "rc5" || *cph == "des" || *cph == "3des" || *cph == "hight" || *cph == "misty1" || *cph == "khazad" || *cph == "present" || *cph == "twine") && (strings.ToUpper(*mode) == "EAX") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, *length/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 64 && len(key) != 56 && len(key) != 40 && len(key) != 32 && len(key) != 24 && len(key) != 20 && len(key) != 16 && len(key) != 10 && len(key) != 8 {
log.Fatal("Invalid key size.")
}
}
var ciph cipher.Block
switch *cph {
case "blowfish":
ciph, err = blowfish.NewCipher(key)
case "idea":
ciph, err = idea.NewCipher(key)
case "cast5":
ciph, err = cast5.NewCipher(key)
case "rc5":
ciph, err = rc5.New(key)
case "hight":
ciph, err = krcrypt.NewHIGHT(key)
case "rc2":
ciph, err = rc2.NewCipher(key)
case "des":
ciph, err = des.NewCipher(key)
case "3des":
ciph, err = des.NewTripleDESCipher(key)
case "misty1":
ciph, err = misty1.New(key)
case "khazad":
ciph, err = khazad.NewCipher(key)
case "present":
ciph, err = present.NewCipher(key)
case "twine":
ciph, err = twine.NewCipher(key)
default:
log.Fatalf("Cipher type %s not recognized", *cph)
}
if err != nil {
log.Fatal(err)
}
var aead cipher.AEAD
// aead, err = eax.NewEAX(ciph, 8)
aead, err = eax.NewEAXWithNonceAndTagSize(ciph, 12, 8)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// io.Copy(buf, os.Stdin)
io.Copy(buf, inputfile)
msg := buf.Bytes()
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
nonce[0] &= 0x7F
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
os.Exit(0)
}
if *crypt != "" && (*cph == "curupira" && strings.ToUpper(*mode) == "LETTERSOUP") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, *length/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 12 && len(key) != 18 && len(key) != 24 {
log.Fatal("Invalid key size. Key must be either 96, 144, or 192 bits for Curupira.")
}
}
buf := bytes.NewBuffer(nil)
var data io.Reader
// data = os.Stdin
data = inputfile
io.Copy(buf, data)
msg := buf.Bytes()
// Optional Additional Authenticated Data (AAD)
aad := []byte(*info)
// Creating a Curupira instance for encryption
cipher, err := curupira1.NewCipher(key)
if err != nil {
log.Fatal("Error creating Curupira cipher instance:", err)
}
// Creating a LetterSoup instance for encryption
aead := curupira1.NewLetterSoup(cipher)
if *crypt == "enc" {
nonce := make([]byte, 12)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
aead.SetIV(nonce)
ciphertext := make([]byte, len(msg))
aead.Encrypt(ciphertext, msg)
aead.Update(aad)
tag := aead.GetTag(nil, 96)
// Displaying the encrypted message
output := append(nonce, tag...)
output = append(output, ciphertext...)
os.Stdout.Write(output)
os.Exit(0)
}
if *crypt == "dec" {
// Extracting nonce, tag, and ciphertext from the input
nonce, tag, msg := msg[:12], msg[12:24], msg[24:]
// Set IV for decryption
aead.SetIV(nonce)
decrypted := make([]byte, len(msg))
aead.Decrypt(decrypted, msg)
// Verifying data authenticity using the same tag calculated during encryption
ciphertext := make([]byte, len(decrypted))
aead.Encrypt(ciphertext, decrypted)
aead.Update(aad)
tagEnc := aead.GetTag(nil, 96)
if bytes.Equal(tag, tagEnc) {
os.Stdout.Write(decrypted)
os.Exit(0)
} else {
log.Fatal("Error: authentication verification failed!")
}
}
}
if *crypt != "" && (*cph == "curupira") && (strings.ToUpper(*mode) == "EAX") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, *length/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 24 && len(key) != 18 && len(key) != 12 {
log.Fatal("Invalid key size.")
}
}
ciph, err := curupira1.NewCipher(key)
if err != nil {
log.Fatal(err)
}
var aead cipher.AEAD
// aead, err = eax.NewEAX(ciph, 12)
aead, err = eax.NewEAXWithNonceAndTagSize(ciph, 12, 12)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// io.Copy(buf, os.Stdin)
io.Copy(buf, inputfile)
msg := buf.Bytes()
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
nonce[0] &= 0x7F
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
os.Exit(0)
}
if *crypt != "" && (*cph == "anubis") && (strings.ToUpper(*mode) == "EAC") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, *length/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) < 16 || len(key) > 40 {
log.Fatal("Invalid key size.")
}
}
aead, err := eac.NewEAC(key)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// io.Copy(buf, os.Stdin)
io.Copy(buf, inputfile)
msg := buf.Bytes()
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
nonce[0] &= 0x7F
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
os.Exit(0)
}
if *crypt != "" && (*cph == "kalyna256_256" || *cph == "kalyna256_512" || *cph == "kalyna512_512" || *cph == "threefish" || *cph == "threefish256" || *cph == "threefish512" || *cph == "threefish1024" || *cph == "shacal2") && (strings.ToUpper(*mode) == "EAX") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, *length/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 128 && len(key) != 64 && len(key) != 32 {
log.Fatal("Invalid key size.")
}
}
var ciph cipher.Block
var tweak []byte
tweak = make([]byte, 16)
var n int
switch *cph {
case "threefish", "threefish256":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New256(key, tweak)
n = 32
case "threefish512":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New512(key, tweak)
n = 64
case "threefish1024":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New1024(key, tweak)
n = 128
case "kalyna256_256":
ciph, err = kalyna.NewCipher256_256(key)
n = 32
case "kalyna256_512":
ciph, err = kalyna.NewCipher256_512(key)
n = 32
case "kalyna512_512":
ciph, err = kalyna.NewCipher512_512(key)
n = 64
case "shacal2":
ciph, err = shacal2.NewCipher(key)
n = 32
default:
log.Fatalf("Cipher type %s not recognized", *cph)
}
if err != nil {
log.Fatal(err)
}
var aead cipher.AEAD
// aead, err = eax.NewEAX(ciph, n)
aead, err = eax.NewEAXWithNonceAndTagSize(ciph, 12, n)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// io.Copy(buf, os.Stdin)
io.Copy(buf, inputfile)
msg := buf.Bytes()
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
nonce[0] &= 0x7F
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
os.Exit(0)
}
if *crypt != "" && (*cph == "aes" || *cph == "anubis" || *cph == "ginga" || *cph == "aria" || *cph == "lea" || *cph == "seed" || *cph == "lea" || *cph == "sm4" || *cph == "camellia" || *cph == "grasshopper" || *cph == "kuznechik" || *cph == "magma" || *cph == "gost89" || *cph == "twofish" || *cph == "serpent" || *cph == "rc6" || *cph == "magenta" || *cph == "mars" || *cph == "noekeon" || *cph == "loki97" || *cph == "cast256" || *cph == "cast6" || *cph == "clefia" || *cph == "kalyna128_128" || *cph == "kalyna128_256" || *cph == "kalyna256_256" || *cph == "kalyna256_512" || *cph == "kalyna512_512" || *cph == "crypton" || *cph == "e2" || *cph == "blowfish" || *cph == "idea" || *cph == "cast5" || *cph == "rc2" || *cph == "rc5" || *cph == "des" || *cph == "3des" || *cph == "hight" || *cph == "misty1" || *cph == "khazad" || *cph == "present" || *cph == "twine" || *cph == "threefish" || *cph == "threefish256" || *cph == "threefish512" || *cph == "threefish1024" || *cph == "shacal2" || *cph == "belt" || *cph == "safer+" || *cph == "saferplus") && (strings.ToUpper(*mode) == "SIV") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, *length/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 128*2 && len(key) != 64*2 && len(key) != 80*2 && len(key) != 56*2 && len(key) != 48*2 && len(key) != 40*2 && len(key) != 32*2 && len(key) != 24*2 && len(key) != 16*2 && len(key) != 10*2 && len(key) != 8*2 {
log.Fatal("Invalid key size.")
}
}
var ciph cipher.Block
var macBlock cipher.Block
// Dividindo a chave para MAC e Block Cipher
macKey := key[:len(key)/2]
blockKey := key[len(key)/2:]
var tweak []byte
tweak = make([]byte, 16)
switch *cph {
case "aes":
ciph, err = aes.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = aes.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "twofish":
ciph, err = twofish.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = twofish.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "aria":
ciph, err = aria.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = aria.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "lea":
ciph, err = lea.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = lea.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "camellia":
ciph, err = camellia.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = camellia.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "serpent":
ciph, err = serpent.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = serpent.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "grasshopper", "kuznechik":
ciph, err = kuznechik.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = kuznechik.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "sm4":
ciph, err = sm4.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = sm4.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "seed":
ciph, err = krcrypt.NewSEED(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = krcrypt.NewSEED(macKey)
if err != nil {
log.Fatal(err)
}
case "anubis":
ciph, err = anubis.NewWithKeySize(key, len(blockKey))
if err != nil {
log.Fatal(err)
}
macBlock, err = anubis.NewWithKeySize(key, len(macKey))
if err != nil {
log.Fatal(err)
}
case "ginga":
ciph, err = ginga.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = ginga.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "rc6":
ciph, err = rc6.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = rc6.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "magenta":
ciph, err = magenta.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = magenta.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "mars":
ciph, err = mars.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = mars.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "noekeon":
ciph, err = noekeon.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = noekeon.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "loki97":
ciph, err = loki97.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = loki97.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "clefia":
ciph, err = clefia.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = clefia.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "kalyna128_128":
ciph, err = kalyna.NewCipher128_128(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = kalyna.NewCipher128_128(macKey)
if err != nil {
log.Fatal(err)
}
case "kalyna128_256":
ciph, err = kalyna.NewCipher128_256(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = kalyna.NewCipher128_256(macKey)
if err != nil {
log.Fatal(err)
}
case "kalyna256_256":
ciph, err = kalyna.NewCipher256_256(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = kalyna.NewCipher256_256(macKey)
if err != nil {
log.Fatal(err)
}
case "kalyna256_512":
ciph, err = kalyna.NewCipher256_512(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = kalyna.NewCipher256_512(macKey)
if err != nil {
log.Fatal(err)
}
case "kalyna512_512":
ciph, err = kalyna.NewCipher512_512(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = kalyna.NewCipher512_512(macKey)
if err != nil {
log.Fatal(err)
}
case "khazad":
ciph, err = khazad.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = khazad.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "cast256", "cast6":
ciph, err = cast256.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = cast256.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "crypton":
ciph, err = crypton1.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = crypton1.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "e2":
ciph, err = e2.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = e2.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "blowfish":
ciph, err = blowfish.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = blowfish.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "idea":
ciph, err = idea.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = idea.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "cast5":
ciph, err = cast5.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = cast5.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "rc5":
ciph, err = rc5.New(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = rc5.New(macKey)
if err != nil {
log.Fatal(err)
}
case "hight":
ciph, err = krcrypt.NewHIGHT(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = krcrypt.NewHIGHT(macKey)
if err != nil {
log.Fatal(err)
}
case "rc2":
ciph, err = rc2.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = rc2.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "des":
ciph, err = des.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = des.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "3des":
ciph, err = des.NewTripleDESCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = des.NewTripleDESCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "misty1":
ciph, err = misty1.New(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = misty1.New(macKey)
if err != nil {
log.Fatal(err)
}
case "present":
ciph, err = present.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = present.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "twine":
ciph, err = twine.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = twine.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "threefish", "threefish256":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New256(blockKey, tweak)
if err != nil {
log.Fatal(err)
}
macBlock, err = threefish.New256(macKey, tweak)
if err != nil {
log.Fatal(err)
}
case "threefish512":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New512(blockKey, tweak)
if err != nil {
log.Fatal(err)
}
macBlock, err = threefish.New512(macKey, tweak)
if err != nil {
log.Fatal(err)
}
case "threefish1024":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New1024(blockKey, tweak)
if err != nil {
log.Fatal(err)
}
macBlock, err = threefish.New1024(macKey, tweak)
if err != nil {
log.Fatal(err)
}
case "shacal2":
ciph, err = shacal2.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = shacal2.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "saferplus", "safer+":
ciph, err = saferplus.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = saferplus.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
case "belt":
ciph, err = belt.NewCipher(blockKey)
if err != nil {
log.Fatal(err)
}
macBlock, err = belt.NewCipher(macKey)
if err != nil {
log.Fatal(err)
}
default:
log.Fatalf("Cipher type %s not recognized", *cph)
}
// Criando a instância de SIV com PMAC
aead, err := siv.NewSiv(macBlock, ciph, 12)
if err != nil {
log.Fatalf("Error creating PMAC cipher: %s", err)
}
if err != nil {
log.Fatal(err)
}
// associatedDataBytes := []byte(*vector)
buf := bytes.NewBuffer(nil)
// io.Copy(buf, os.Stdin)
io.Copy(buf, inputfile)
msg := buf.Bytes()
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
nonce[0] &= 0x7F
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
os.Exit(0)
}
if *crypt != "" && (*cph == "aes" || *cph == "anubis" || *cph == "ginga" || *cph == "aria" || *cph == "lea" || *cph == "seed" || *cph == "lea" || *cph == "sm4" || *cph == "camellia" || *cph == "grasshopper" || *cph == "kuznechik" || *cph == "magma" || *cph == "gost89" || *cph == "twofish" || *cph == "serpent" || *cph == "rc6" || *cph == "magenta" || *cph == "khazad" || *cph == "present" || *cph == "twine" || *cph == "mars" || *cph == "noekeon" || *cph == "loki97" || *cph == "cast256" || *cph == "cast6" || *cph == "clefia" || *cph == "kalyna128_128" || *cph == "kalyna128_256" || *cph == "crypton" || *cph == "e2" || *cph == "saferplus" || *cph == "safer+" || *cph == "belt") && (strings.ToUpper(*mode) == "GCM" || strings.ToUpper(*mode) == "MGM" || strings.ToUpper(*mode) == "OCB" || strings.ToUpper(*mode) == "OCB1" || strings.ToUpper(*mode) == "OCB3" || strings.ToUpper(*mode) == "EAX" || strings.ToUpper(*mode) == "CCM") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, *length/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 64 && len(key) != 56 && len(key) != 40 && len(key) != 32 && len(key) != 24 && len(key) != 16 && len(key) != 10 {
log.Fatal("Invalid key size.")
}
}
var ciph cipher.Block
var n int
switch *cph {
case "aes":
ciph, err = aes.NewCipher(key)
n = 16
case "twofish":
ciph, err = twofish.NewCipher(key)
n = 16
case "aria":
ciph, err = aria.NewCipher(key)
n = 16
case "lea":
ciph, err = lea.NewCipher(key)
n = 16
case "camellia":
ciph, err = camellia.NewCipher(key)
n = 16
case "serpent":
ciph, err = serpent.NewCipher(key)
n = 16
case "grasshopper", "kuznechik":
ciph, err = kuznechik.NewCipher(key)
n = 16
case "sm4":
ciph, err = sm4.NewCipher(key)
n = 16
case "seed":
ciph, err = krcrypt.NewSEED(key)
n = 16
case "anubis":
ciph, err = anubis.NewWithKeySize(key, len(key))
n = 16
case "magma":
ciph = gost341264.NewCipher(key)
n = 8
case "gost89":
ciph = gost28147.NewCipher(key, &gost28147.SboxIdtc26gost28147paramZ)
n = 8
case "rc6":
ciph, err = rc6.NewCipher(key)
n = 16
case "ginga":
ciph, err = ginga.NewCipher(key)
n = 16
case "magenta":
ciph, err = magenta.NewCipher(key)
n = 16
case "khazad":
ciph, err = khazad.NewCipher(key)
n = 8
case "present":
ciph, err = present.NewCipher(key)
n = 8
case "twine":
ciph, err = twine.NewCipher(key)
n = 8
case "mars":
ciph, err = mars.NewCipher(key)
n = 16
case "noekeon":
ciph, err = noekeon.NewCipher(key)
n = 16
case "loki97":
ciph, err = loki97.NewCipher(key)
n = 16
case "clefia":
ciph, err = clefia.NewCipher(key)
n = 16
case "kalyna128_128":
ciph, err = kalyna.NewCipher128_128(key)
n = 16
case "kalyna128_256":
ciph, err = kalyna.NewCipher128_256(key)
n = 16
case "cast256", "cast6":
ciph, err = cast256.NewCipher(key)
n = 16
case "crypton":
ciph, err = crypton1.NewCipher(key)
n = 16
case "e2":
ciph, err = e2.NewCipher(key)
n = 16
case "saferplus", "safer+":
ciph, err = saferplus.NewCipher(key)
n = 8
case "belt":
ciph, err = belt.NewCipher(key)
n = 16
default:
log.Fatalf("Cipher type %s not recognized", *cph)
}
if err != nil {
log.Fatal(err)
}
var aead cipher.AEAD
modeUpper := strings.ToUpper(*mode)
switch modeUpper {
case "GCM":
aead, err = cipher.NewGCMWithTagSize(ciph, 16)
case "MGM":
aead, err = mgm.NewMGM(ciph, n)
case "OCB", "OCB1":
aead, err = ocb.NewOCB(ciph)
case "OCB3":
aead, err = ocb3.New(ciph)
case "EAX":
aead, err = eax.NewEAXWithNonceAndTagSize(ciph, 12, n)
case "CCM":
aead, err = ccm.NewCCM(ciph, 16, 12)
default:
log.Fatalf("AEAD mode %s not recognized", modeUpper)
}
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// io.Copy(buf, os.Stdin)
io.Copy(buf, inputfile)
msg := buf.Bytes()
if *crypt == "enc" {
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
nonce[0] &= 0x7F
out := aead.Seal(nonce, nonce, msg, []byte(*info))
fmt.Printf("%s", out)
os.Exit(0)
}
if *crypt == "dec" {
nonce, msg := msg[:aead.NonceSize()], msg[aead.NonceSize():]
out, err := aead.Open(nil, nonce, msg, []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out)
os.Exit(0)
}
os.Exit(0)
}
if *crypt != "" && (strings.ToUpper(*mode) == "ECB" || strings.ToUpper(*mode) == "CBC" || strings.ToUpper(*mode) == "IGE") {
var keyHex string
keyHex = *key
var err error
var key []byte
if keyHex == "" {
key = make([]byte, *length/8)
if *cph == "3des" {
key = make([]byte, 24)
}
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 128 && len(key) != 64 && len(key) != 56 && len(key) != 40 && len(key) != 32 && len(key) != 24 && len(key) != 18 && len(key) != 16 && len(key) != 12 && len(key) != 10 && len(key) != 8 {
log.Fatal("Invalid key size.")
}
}
var ciph cipher.Block
var n int
var tweak []byte
tweak = make([]byte, 16)
switch *cph {
case "aes":
ciph, err = aes.NewCipher(key)
n = 16
case "twofish":
ciph, err = twofish.NewCipher(key)
n = 16
case "aria":
ciph, err = aria.NewCipher(key)
n = 16
case "lea":
ciph, err = lea.NewCipher(key)
n = 16
case "camellia":
ciph, err = camellia.NewCipher(key)
n = 16
case "serpent":
ciph, err = serpent.NewCipher(key)
n = 16
case "grasshopper", "kuznechik":
ciph, err = kuznechik.NewCipher(key)
n = 16
case "sm4":
ciph, err = sm4.NewCipher(key)
n = 16
case "seed":
ciph, err = krcrypt.NewSEED(key)
n = 16
case "hight":
ciph, err = krcrypt.NewHIGHT(key)
n = 8
case "anubis":
ciph, err = anubis.NewWithKeySize(key, len(key))
n = 16
case "magma":
ciph = gost341264.NewCipher(key)
n = 8
case "gost89":
ciph = gost28147.NewCipher(key, &gost28147.SboxIdtc26gost28147paramZ)
n = 8
case "3des":
ciph, err = des.NewTripleDESCipher(key)
n = 8
case "des":
ciph, err = des.NewCipher(key)
n = 8
case "rc2":
ciph, err = rc2.NewCipher(key)
n = 8
case "rc5":
ciph, err = rc5.New(key)
n = 8
case "rc6":
ciph, err = rc6.NewCipher(key)
n = 16
case "ginga":
ciph, err = ginga.NewCipher(key)
n = 16
case "magenta":
ciph, err = magenta.NewCipher(key)
n = 16
case "idea":
ciph, _ = idea.NewCipher(key)
n = 8
case "blowfish":
ciph, err = blowfish.NewCipher(key)
n = 8
case "cast5":
ciph, err = cast5.NewCipher(key)
n = 8
case "misty1":
ciph, err = misty1.New(key)
n = 8
case "threefish256", "threefish":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New256(key, tweak)
n = 32
case "threefish512":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New512(key, tweak)
n = 64
case "threefish1024":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New1024(key, tweak)
n = 128
case "khazad":
ciph, err = khazad.NewCipher(key)
n = 8
case "present":
ciph, err = present.NewCipher(key)
n = 8
case "twine":
ciph, err = twine.NewCipher(key)
n = 8
case "mars":
ciph, err = mars.NewCipher(key)
n = 16
case "noekeon":
ciph, err = noekeon.NewCipher(key)
n = 16
case "loki97":
ciph, err = loki97.NewCipher(key)
n = 16
case "clefia":
ciph, err = clefia.NewCipher(key)
n = 16
case "kalyna128_128":
ciph, err = kalyna.NewCipher128_128(key)
n = 16
case "kalyna128_256":
ciph, err = kalyna.NewCipher128_256(key)
n = 16
case "kalyna256_256":
ciph, err = kalyna.NewCipher256_256(key)
n = 32
case "kalyna256_512":
ciph, err = kalyna.NewCipher256_512(key)
n = 32
case "kalyna512_512":
ciph, err = kalyna.NewCipher512_512(key)
n = 64
case "cast256", "cast6":
ciph, err = cast256.NewCipher(key)
n = 16
case "crypton":
ciph, err = crypton1.NewCipher(key)
n = 16
case "e2":
ciph, err = e2.NewCipher(key)
n = 16
case "curupira":
ciph, err = curupira1.NewCipher(key)
n = 12
case "shacal2":
ciph, err = shacal2.NewCipher(key)
n = 32
case "saferplus", "safer+":
ciph, err = saferplus.NewCipher(key)
n = 8
case "belt":
ciph, err = belt.NewCipher(key)
n = 16
default:
log.Fatalf("Cipher type %s not recognized", *cph)
}
if err != nil {
log.Fatal(err)
}
var iv []byte
if strings.ToUpper(*mode) == "CBC" || strings.ToUpper(*mode) == "ECB" {
iv = make([]byte, n)
} else {
iv = make([]byte, n*2)
}
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
} else if strings.ToUpper(*mode) == "CBC" || strings.ToUpper(*mode) == "IGE" {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
}
if err != nil {
log.Fatal(err)
}
if *crypt == "enc" {
buf := bytes.NewBuffer(nil)
io.Copy(buf, inputfile)
plaintext := buf.Bytes()
plaintext = PKCS7Padding(plaintext)
ciphertext := make([]byte, len(plaintext))
var blockmode cipher.BlockMode
switch strings.ToUpper(*mode) {
case "ECB":
blockmode = ecb.NewECBEncrypter(ciph)
case "CBC":
blockmode = cipher.NewCBCEncrypter(ciph, iv)
case "IGE":
blockmode = ige.NewIGEEncrypter(ciph, iv)
default:
log.Fatalf("Mode %s not recognized", *mode)
}
blockmode.CryptBlocks(ciphertext, plaintext)
fmt.Printf("%s", ciphertext)
} else if *crypt == "dec" {
buf := bytes.NewBuffer(nil)
io.Copy(buf, inputfile)
ciphertext := buf.Bytes()
plaintext := make([]byte, len(ciphertext))
var blockmode cipher.BlockMode
switch strings.ToUpper(*mode) {
case "ECB":
blockmode = ecb.NewECBDecrypter(ciph)
case "CBC":
blockmode = cipher.NewCBCDecrypter(ciph, iv)
case "IGE":
blockmode = ige.NewIGEDecrypter(ciph, iv)
default:
log.Fatalf("Mode %s not recognized", *mode)
}
blockmode.CryptBlocks(plaintext, ciphertext)
plaintext = PKCS7UnPadding(plaintext)
fmt.Printf("%s", plaintext)
}
os.Exit(0)
}
if *crypt != "" && (*cph == "aes" || *cph == "aria" || *cph == "lea" || *cph == "camellia" || *cph == "magma" || *cph == "grasshopper" || *cph == "kuznechik" || *cph == "gost89" || *cph == "twofish" || *cph == "serpent" || *cph == "rc6" || *cph == "ginga" || *cph == "magenta" || *cph == "threefish" || *cph == "threefish256" || *cph == "threefish512" || *cph == "threefish1024" || *cph == "mars" || *cph == "noekeon" || *cph == "loki97" || *cph == "cast256" || *cph == "cast6" || *cph == "clefia" || *cph == "kalyna128_128" || *cph == "kalyna128_256" || *cph == "kalyna256_256" || *cph == "kalyna256_512" || *cph == "kalyna512_512" || *cph == "crypton" || *cph == "e2" || *cph == "shacal2" || *cph == "saferplus" || *cph == "safer+" || *cph == "belt") {
var keyHex string
keyHex = *key
var err error
var key []byte
if keyHex == "" {
key = make([]byte, *length/8)
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
// if len(key) != 56 && len(key) != 40 && len(key) != 32 && len(key) != 24 && len(key) != 16 {
if len(key) != 128 && len(key) != 64 && len(key) != 56 && len(key) != 40 && len(key) != 32 && len(key) != 24 && len(key) != 16 {
log.Fatal("Invalid key size.")
}
}
var ciph cipher.Block
var iv []byte
var tweak []byte
tweak = make([]byte, 16)
switch *cph {
case "aes":
ciph, err = aes.NewCipher(key)
iv = make([]byte, 16)
case "twofish":
ciph, err = twofish.NewCipher(key)
iv = make([]byte, 16)
case "aria":
ciph, err = aria.NewCipher(key)
iv = make([]byte, 16)
case "lea":
ciph, err = lea.NewCipher(key)
iv = make([]byte, 16)
case "camellia":
ciph, err = camellia.NewCipher(key)
iv = make([]byte, 16)
case "serpent":
ciph, err = serpent.NewCipher(key)
iv = make([]byte, 16)
case "rc6":
ciph, err = rc6.NewCipher(key)
iv = make([]byte, 16)
case "ginga":
ciph, err = ginga.NewCipher(key)
iv = make([]byte, 16)
case "magenta":
ciph, err = magenta.NewCipher(key)
iv = make([]byte, 16)
case "magma":
ciph = gost341264.NewCipher(key)
iv = make([]byte, 8)
case "gost89":
ciph = gost28147.NewCipher(key, &gost28147.SboxIdtc26gost28147paramZ)
iv = make([]byte, 8)
case "grasshopper", "kuznechik":
ciph, err = kuznechik.NewCipher(key)
iv = make([]byte, 16)
case "threefish256", "threefish":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New256(key, tweak)
iv = make([]byte, 32)
case "threefish512":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New512(key, tweak)
iv = make([]byte, 64)
case "threefish1024":
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
ciph, err = threefish.New1024(key, tweak)
iv = make([]byte, 128)
case "mars":
ciph, err = mars.NewCipher(key)
iv = make([]byte, 16)
case "noekeon":
ciph, err = noekeon.NewCipher(key)
iv = make([]byte, 16)
case "loki97":
ciph, err = loki97.NewCipher(key)
iv = make([]byte, 16)
case "clefia":
ciph, err = clefia.NewCipher(key)
iv = make([]byte, 16)
case "kalyna128_128":
ciph, err = kalyna.NewCipher128_128(key)
iv = make([]byte, 16)
case "kalyna128_256":
ciph, err = kalyna.NewCipher128_256(key)
iv = make([]byte, 16)
case "kalyna256_256":
ciph, err = kalyna.NewCipher256_256(key)
iv = make([]byte, 32)
case "kalyna256_512":
ciph, err = kalyna.NewCipher256_512(key)
iv = make([]byte, 32)
case "kalyna512_512":
ciph, err = kalyna.NewCipher512_512(key)
iv = make([]byte, 64)
case "cast256", "cast6":
ciph, err = cast256.NewCipher(key)
iv = make([]byte, 16)
case "crypton":
ciph, err = crypton1.NewCipher(key)
iv = make([]byte, 16)
case "e2":
ciph, err = e2.NewCipher(key)
iv = make([]byte, 16)
case "shacal2":
ciph, err = shacal2.NewCipher(key)
iv = make([]byte, 32)
case "saferplus", "safer+":
ciph, err = saferplus.NewCipher(key)
iv = make([]byte, 8)
case "belt":
ciph, err = belt.NewCipher(key)
iv = make([]byte, 16)
default:
log.Fatalf("Cipher type %s not recognized", *cph)
}
if err != nil {
log.Fatal(err)
}
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
}
var stream cipher.Stream
modeUpper := strings.ToUpper(*mode)
switch {
case modeUpper == "CTR":
stream = cipher.NewCTR(ciph, iv)
case modeUpper == "OFB":
stream = cipher.NewOFB(ciph, iv)
case *crypt == "enc" && modeUpper == "CFB1":
stream = CFB1.NewCFB1Encrypt(ciph, iv)
case *crypt == "dec" && modeUpper == "CFB1":
stream = CFB1.NewCFB1Decrypt(ciph, iv)
case *crypt == "enc" && modeUpper == "CFB8":
stream = CFB8.NewCFB8Encrypt(ciph, iv)
case *crypt == "dec" && modeUpper == "CFB8":
stream = CFB8.NewCFB8Decrypt(ciph, iv)
case *crypt == "enc" && modeUpper == "CFB":
stream = cipher.NewCFBEncrypter(ciph, iv)
case *crypt == "dec" && modeUpper == "CFB":
stream = cipher.NewCFBDecrypter(ciph, iv)
default:
log.Fatalf("Mode %s not recognized", *mode)
}
buf := make([]byte, 128*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
stream.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *crypt != "" && (*cph == "blowfish" || *cph == "idea" || *cph == "cast5" || *cph == "rc2" || *cph == "rc5" || *cph == "sm4" || *cph == "des" || *cph == "3des" || *cph == "seed" || *cph == "hight" || *cph == "misty1" || *cph == "anubis" || *cph == "khazad" || *cph == "present" || *cph == "twine" || *cph == "curupira") {
var keyHex string
keyHex = *key
var key []byte
var err error
if keyHex == "" {
key = make([]byte, *length/8)
if *cph == "3des" {
key = make([]byte, 24)
}
_, err = io.ReadFull(rand.Reader, key)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Key=", hex.EncodeToString(key))
} else {
key, err = hex.DecodeString(keyHex)
if err != nil {
log.Fatal(err)
}
if len(key) != 32 && len(key) != 40 && len(key) != 16 && len(key) != 10 && len(key) != 24 && len(key) != 18 && len(key) != 12 && len(key) != 10 && len(key) != 8 {
log.Fatal("Invalid key size.")
}
}
var ciph cipher.Block
var iv []byte
switch *cph {
case "blowfish":
ciph, err = blowfish.NewCipher(key)
iv = make([]byte, 8)
case "idea":
ciph, err = idea.NewCipher(key)
iv = make([]byte, 8)
case "cast5":
ciph, err = cast5.NewCipher(key)
iv = make([]byte, 8)
case "rc5":
ciph, err = rc5.New(key)
iv = make([]byte, 8)
case "sm4":
ciph, err = sm4.NewCipher(key)
iv = make([]byte, 16)
case "seed":
ciph, err = krcrypt.NewSEED(key)
iv = make([]byte, 16)
case "hight":
ciph, err = krcrypt.NewHIGHT(key)
iv = make([]byte, 8)
case "anubis":
ciph, err = anubis.NewWithKeySize(key, len(key))
iv = make([]byte, 16)
case "rc2":
ciph, err = rc2.NewCipher(key)
iv = make([]byte, 8)
case "des":
ciph, err = des.NewCipher(key)
iv = make([]byte, 8)
case "3des":
ciph, err = des.NewTripleDESCipher(key)
iv = make([]byte, 8)
case "misty1":
ciph, err = misty1.New(key)
iv = make([]byte, 8)
case "khazad":
ciph, err = khazad.NewCipher(key)
iv = make([]byte, 8)
case "present":
ciph, err = present.NewCipher(key)
iv = make([]byte, 8)
case "twine":
ciph, err = twine.NewCipher(key)
iv = make([]byte, 8)
case "curupira":
ciph, err = curupira1.NewCipher(key)
iv = make([]byte, 12)
default:
log.Fatalf("Cipher type %s not recognized", *cph)
}
if err != nil {
log.Fatal(err)
}
if *vector != "" {
iv, _ = hex.DecodeString(*vector)
} else {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
}
var stream cipher.Stream
modeUpper := strings.ToUpper(*mode)
switch {
case modeUpper == "CTR":
stream = cipher.NewCTR(ciph, iv)
case modeUpper == "OFB":
stream = cipher.NewOFB(ciph, iv)
case *crypt == "enc" && modeUpper == "CFB1":
stream = CFB1.NewCFB1Encrypt(ciph, iv)
case *crypt == "dec" && modeUpper == "CFB1":
stream = CFB1.NewCFB1Decrypt(ciph, iv)
case *crypt == "enc" && modeUpper == "CFB8":
stream = CFB8.NewCFB8Encrypt(ciph, iv)
case *crypt == "dec" && modeUpper == "CFB8":
stream = CFB8.NewCFB8Decrypt(ciph, iv)
case *crypt == "enc" && modeUpper == "CFB":
stream = cipher.NewCFBEncrypter(ciph, iv)
case *crypt == "dec" && modeUpper == "CFB":
stream = cipher.NewCFBDecrypter(ciph, iv)
default:
log.Fatalf("Mode %s not recognized", *mode)
}
buf := make([]byte, 128*1<<10)
var n int
for {
// n, err = os.Stdin.Read(buf)
n, err = inputfile.Read(buf)
if err != nil && err != io.EOF {
log.Fatal(err)
}
stream.XORKeyStream(buf[:n], buf[:n])
if _, err := os.Stdout.Write(buf[:n]); err != nil {
log.Fatal(err)
}
if err == io.EOF {
break
}
}
os.Exit(0)
}
if *digest && (*md == "bcrypt") && !*check {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(*key), *iter)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(hashedPassword))
os.Exit(0)
}
if *md == "bcrypt" && *check {
hashedPassword, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
err = bcrypt.CompareHashAndPassword(hashedPassword, []byte(*key))
if err != nil {
log.Fatal(err)
}
fmt.Println("Verify: true")
os.Exit(0)
}
if *digest && *md == "argon2" && !*check {
hash := argon2.IDKey([]byte(*key), []byte(*salt), uint32(*iter), 64*1024, 4, uint32(*length/8))
fmt.Println(hex.EncodeToString(hash))
os.Exit(0)
}
if *md == "argon2" && *check {
hashedPassword, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
hashedPasswordString := strings.TrimSpace(string(hashedPassword))
computedHash := argon2.IDKey([]byte(*key), []byte(*salt), uint32(*iter), 64*1024, 4, uint32(*length/8))
computedHashString := hex.EncodeToString(computedHash)
if computedHashString == hashedPasswordString {
fmt.Println("Verify: true")
} else {
fmt.Println("Verify: false")
os.Exit(1)
}
os.Exit(0)
}
if *digest && *md == "lyra2re" && !*check {
passwordBytes := []byte(*key + *salt)
hash, err := lyra2re.Sum(passwordBytes)
if err != nil {
log.Fatal(err)
}
fmt.Println(hex.EncodeToString(hash))
os.Exit(0)
}
if *md == "lyra2re" && *check {
passwordBytes := []byte(*key + *salt)
hash, err := lyra2re.Sum(passwordBytes)
if err != nil {
log.Fatal(err)
}
computedHashString := hex.EncodeToString(hash)
hashedPassword, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
hashedPasswordString := strings.TrimSpace(string(hashedPassword))
if computedHashString == hashedPasswordString {
fmt.Println("Verify: true")
} else {
fmt.Println("Verify: false")
os.Exit(1)
}
os.Exit(0)
}
if *digest && *md == "lyra2re2" && !*check {
passwordBytes := []byte(*key + *salt)
hash, err := lyra2re2.Sum(passwordBytes)
if err != nil {
log.Fatal(err)
}
fmt.Println(hex.EncodeToString(hash))
os.Exit(0)
}
if *md == "lyra2re2" && *check {
passwordBytes := []byte(*key + *salt)
hash, err := lyra2re2.Sum(passwordBytes)
if err != nil {
log.Fatal(err)
}
computedHashString := hex.EncodeToString(hash)
hashedPassword, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
hashedPasswordString := strings.TrimSpace(string(hashedPassword))
if computedHashString == hashedPasswordString {
fmt.Println("Verify: true")
} else {
fmt.Println("Verify: false")
os.Exit(1)
}
os.Exit(0)
}
if *digest && *alg == "makwa" && !*check {
var params makwa.PublicParameters
bits := *length
privateParams, err := makwa.GenerateParameters(bits)
if err != nil {
log.Fatal(err)
}
params.N = privateParams.N
params.Hash = myHash
fmt.Printf("Modulus= %x\n", params.N)
fmt.Printf("FactorP= %x\n", privateParams.P)
fmt.Printf("FactorQ= %x\n", privateParams.Q)
digest, err := makwa.Hash(params, []byte(*key), []byte(*salt), *iter, false, 0)
if err != nil {
log.Fatal(err)
}
fmt.Println("Digest=", digest)
os.Exit(0)
}
if *alg == "makwa" && *check {
var params makwa.PublicParameters
hashedPassword, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
hashedPasswordString := strings.TrimSpace(string(hashedPassword))
modulus := new(big.Int)
_, success := modulus.SetString(*modulusStr, 16)
if !success {
log.Fatal("Failed to parse modulus")
}
params.N = modulus
params.Hash = myHash
// fmt.Printf("Modulus= %x\n", params.N)
digest := &makwa.Digest{}
err = digest.UnmarshalText([]byte(hashedPasswordString))
if err != nil {
log.Fatal(err)
}
isValid := makwa.CheckPassword(params, digest, []byte(*key))
if isValid == nil {
fmt.Println("Verified: true")
os.Exit(0)
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
}
if *recover {
hashedPassword, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
hashedPasswordString := strings.TrimSpace(string(hashedPassword))
modulus := new(big.Int)
_, success := modulus.SetString(*modulusStr, 16)
if !success {
log.Fatal("Failed to parse modulus")
}
factor1 := new(big.Int)
factor1, success = factor1.SetString(*factorPStr, 16)
if !success {
log.Fatal("Failed to parse factor1")
}
factor2 := new(big.Int)
factor2, success = factor2.SetString(*factorQStr, 16)
if !success {
log.Fatal("Failed to parse factor2")
}
digest := &makwa.Digest{}
err = digest.UnmarshalText([]byte(hashedPasswordString))
if err != nil {
log.Fatal(err)
}
params := makwa.PrivateParameters{
PublicParameters: makwa.PublicParameters{
N: modulus,
Hash: myHash,
},
P: factor1,
Q: factor2,
}
originalKey, err := makwa.Recover(params, digest)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", originalKey)
os.Exit(0)
}
if *digest && (*md == "haraka" || *md == "haraka256") {
xkey := new([32]byte)
gkey := new([32]byte)
b, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
if len(b) * 8 > 256 {
fmt.Fprintf(os.Stderr, "Alert: The plain text exceeds 256 bits!\n")
}
copy(xkey[:], b)
haraka.Haraka256(gkey, xkey)
fmt.Printf("%x\n", gkey[:])
os.Exit(0)
}
if *digest && *md == "haraka512" {
xkey := new([64]byte)
gkey := new([32]byte)
b, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
if len(b) * 8 > 512 {
fmt.Fprintf(os.Stderr, "Alert: The plain text exceeds 512 bits!\n")
}
copy(xkey[:], b)
haraka.Haraka512(gkey, xkey)
fmt.Printf("%x\n", gkey[:])
os.Exit(0)
}
if *digest && (Files == "-" || Files == "") {
h.Reset()
io.Copy(h, os.Stdin)
fmt.Println(hex.EncodeToString(h.Sum(nil)), "(stdin)")
os.Exit(0)
}
if *digest && !*recursive {
for _, wildcard := range flag.Args() {
files, err := filepath.Glob(wildcard)
if err != nil {
log.Fatal(err)
}
for _, match := range files {
h.Reset()
f, err := os.Open(match)
if err != nil {
log.Fatal(err)
}
file, err := os.Stat(match)
if err != nil {
log.Fatal(err)
}
if !file.IsDir() {
if _, err := io.Copy(h, f); err != nil {
log.Fatal(err)
}
fmt.Println(hex.EncodeToString(h.Sum(nil)), "*"+f.Name())
}
f.Close()
}
}
os.Exit(0)
}
if *digest && *recursive {
err := filepath.Walk(filepath.Dir(Files),
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
file, err := os.Stat(path)
if err != nil {
log.Fatal(err)
}
if !file.IsDir() {
for _, match := range flag.Args() {
filename := filepath.Base(path)
pattern := filepath.Base(match)
matched, err := filepath.Match(pattern, filename)
if err != nil {
log.Fatal(err)
}
if matched {
h.Reset()
f, err := os.Open(path)
if err != nil {
log.Fatal(err)
}
if _, err := io.Copy(h, f); err != nil {
log.Fatal(err)
}
f.Close()
fmt.Println(hex.EncodeToString(h.Sum(nil)), "*"+f.Name())
}
}
}
return nil
})
if err != nil {
log.Println(err)
}
}
if *check {
scanner := bufio.NewScanner(inputfile)
scanner.Split(bufio.ScanLines)
var txtlines []string
for scanner.Scan() {
txtlines = append(txtlines, scanner.Text())
}
var exit int
for _, eachline := range txtlines {
lines := strings.Split(string(eachline), " *")
if strings.Contains(string(eachline), " *") {
h.Reset()
_, err := os.Stat(lines[1])
if err == nil {
f, err := os.Open(lines[1])
if err != nil {
log.Fatal(err)
}
io.Copy(h, f)
if hex.EncodeToString(h.Sum(nil)) == lines[0] {
fmt.Println(lines[1]+"\t", "OK")
} else {
fmt.Println(lines[1]+"\t", "FAILED")
exit = 1
}
} else {
fmt.Println(lines[1]+"\t", "Not found!")
exit = 1
}
}
}
os.Exit(exit)
}
if *mac == "gost" {
var keyRaw []byte
if *key == "" {
keyRaw = []byte("00000000000000000000000000000000")
fmt.Fprintf(os.Stderr, "Key= %s\n", keyRaw)
} else {
keyRaw = []byte(*key)
}
if len(keyRaw) != 256/8 {
fmt.Println("Secret key must have 128-bit.")
os.Exit(1)
}
var iv [8]byte
if *vector == "" {
fmt.Fprintf(os.Stderr, "IV= %x\n", iv)
} else {
raw, err := hex.DecodeString(*vector)
if err != nil {
log.Fatal(err)
}
iv = *byte8(raw)
if err != nil {
log.Fatal(err)
}
}
c := gost28147.NewCipher([]byte(keyRaw), &gost28147.SboxIdtc26gost28147paramZ)
h, _ := c.NewMAC(8, iv[:])
// io.Copy(h, os.Stdin)
io.Copy(h, inputfile)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("MAC-GOST("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "poly1305" {
var keyx [32]byte
copy(keyx[:], []byte(*key))
h := poly1305.New(&keyx)
// io.Copy(h, os.Stdin)
io.Copy(h, inputfile)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("MAC-POLY1305("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "siphash" {
var xkey [16]byte
copy(xkey[:], []byte(*key))
h, _ := siphash.New128(xkey[:])
// io.Copy(h, os.Stdin)
io.Copy(h, inputfile)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("MAC-SIPHASH("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "siphash64" {
var xkey [16]byte
copy(xkey[:], []byte(*key))
h, _ := siphash.New64(xkey[:])
// io.Copy(h, os.Stdin)
io.Copy(h, inputfile)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("MAC-SIPHASH("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "skein" {
var err error
h := skeincipher.NewMAC(uint64(*length/8), []byte(*key))
// if _, err = io.Copy(h, os.Stdin); err != nil {
if _, err = io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("MAC-SKEIN("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "blake3" {
h, err = blake3.NewKeyed([]byte(*key))
if err != nil {
log.Fatal(err)
}
// if _, err = io.Copy(h, os.Stdin); err != nil {
if _, err = io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("MAC-BLAKE3("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "hmac" && *md == "haraka" {
key := []byte(*key)
b, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
if len(b) * 8 > 512 {
fmt.Fprintf(os.Stderr, "Alert: The plain text exceeds 512 bits!\n")
}
if len(key) > 64 {
log.Fatal("Key length exceeds 64 bytes")
}
if len(key) < 32 {
padKey := make([]byte, 32)
copy(padKey, key)
key = padKey
}
innerPad := make([]byte, 32)
outerPad := make([]byte, 32)
for i := 0; i < 32; i++ {
innerPad[i] = key[i] ^ 0x36
outerPad[i] = key[i] ^ 0x5C
}
var innerHashInput [64]byte
copy(innerHashInput[:], innerPad)
copy(innerHashInput[0:], b)
var innerHash [32]byte
haraka.Haraka512(&innerHash, &innerHashInput)
var outerInput [64]byte
copy(outerInput[:32], outerPad)
copy(outerInput[32:], innerHash[:])
var outerHash [32]byte
haraka.Haraka512(&outerHash, &outerInput)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(outerHash[:])
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("HMAC-HARAKA("+inputdesc+")=", hex.EncodeToString(outerHash[:]))
os.Exit(0)
}
if *mac == "hmac" {
var err error
h := hmac.New(myHash, []byte(*key))
// if _, err = io.Copy(h, os.Stdin); err != nil {
if _, err = io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("HMAC-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *md == "sha256" && *mac == "kmac" {
*md = "kupyna256"
}
if *mac == "kmac" {
var err error
var h hash.Hash
if *md == "kupyna256" || *md == "kupyna" {
h, err = kupyna.NewKmac256([]byte(*key))
} else if *md == "kupyna384" {
h, err = kupyna.NewKmac384([]byte(*key))
} else if *md == "kupyna512" {
h, err = kupyna.NewKmac512([]byte(*key))
}
if err != nil {
log.Fatal(err)
}
// if _, err = io.Copy(h, os.Stdin); err != nil {
if _, err = io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("KMAC-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "cmac" {
var c cipher.Block
var err error
switch *cph {
case "blowfish":
c, err = blowfish.NewCipher([]byte(*key))
case "idea":
c, err = idea.NewCipher([]byte(*key))
case "cast5":
c, err = cast5.NewCipher([]byte(*key))
case "rc5":
c, err = rc5.New([]byte(*key))
case "sm4":
c, err = sm4.NewCipher([]byte(*key))
case "seed":
c, err = krcrypt.NewSEED([]byte(*key))
case "hight":
c, err = krcrypt.NewHIGHT([]byte(*key))
case "rc2":
c, err = rc2.NewCipher([]byte(*key))
case "des":
c, err = des.NewCipher([]byte(*key))
case "3des":
c, err = des.NewTripleDESCipher([]byte(*key))
case "aes":
c, err = aes.NewCipher([]byte(*key))
case "twofish":
c, err = twofish.NewCipher([]byte(*key))
case "aria":
c, err = aria.NewCipher([]byte(*key))
case "lea":
c, err = lea.NewCipher([]byte(*key))
case "camellia":
c, err = camellia.NewCipher([]byte(*key))
case "serpent":
c, err = serpent.NewCipher([]byte(*key))
case "rc6":
c, err = rc6.NewCipher([]byte(*key))
case "ginga":
c, err = ginga.NewCipher([]byte(*key))
case "magenta":
c, err = magenta.NewCipher([]byte(*key))
case "misty1":
c, err = misty1.New([]byte(*key))
case "magma":
if len(*key) != 32 {
log.Fatal("MAGMA invalid key size ", len(*key))
}
c = gost341264.NewCipher([]byte(*key))
case "grasshopper", "kuznechik":
if len(*key) != 32 {
log.Fatal("KUZNECHIK: invalid key size ", len(*key))
}
c, err = kuznechik.NewCipher([]byte(*key))
case "gost89":
if len(*key) != 32 {
log.Fatal("GOST89: invalid key size ", len(*key))
}
c = gost28147.NewCipher([]byte(*key), &gost28147.SboxIdtc26gost28147paramZ)
case "anubis":
if len(*key) != 16 && len(*key) != 24 && len(*key) != 32 && len(*key) != 40 {
log.Fatal("ANUBIS: invalid key size ", len(*key))
}
c, err = anubis.NewWithKeySize([]byte(*key), len(*key))
case "khazad":
c, err = khazad.NewCipher([]byte(*key))
case "mars":
c, err = mars.NewCipher([]byte(*key))
case "noekeon":
c, err = noekeon.NewCipher([]byte(*key))
case "loki97":
c, err = loki97.NewCipher([]byte(*key))
case "clefia":
c, err = clefia.NewCipher([]byte(*key))
case "kalyna128_128":
c, err = kalyna.NewCipher128_128([]byte(*key))
case "kalyna128_256":
c, err = kalyna.NewCipher128_256([]byte(*key))
case "cast256", "cast6":
c, err = cast256.NewCipher([]byte(*key))
case "e2":
c, err = e2.NewCipher([]byte(*key))
case "crypton":
c, err = crypton1.NewCipher([]byte(*key))
case "present":
c, err = present.NewCipher([]byte(*key))
case "twine":
c, err = twine.NewCipher([]byte(*key))
case "saferplus", "safer+":
c, err = saferplus.NewCipher([]byte(*key))
case "belt":
c, err = belt.NewCipher([]byte(*key))
default:
log.Fatalf("Unsupported cipher type: %s", *cph)
}
if err != nil {
log.Fatal(err)
}
h, _ := cmac.New(c)
// io.Copy(h, os.Stdin)
io.Copy(h, inputfile)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("CMAC-"+strings.ToUpper(*cph)+"("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "pmac" {
var c cipher.Block
var err error
switch *cph {
case "blowfish":
c, err = blowfish.NewCipher([]byte(*key))
case "idea":
c, err = idea.NewCipher([]byte(*key))
case "cast5":
c, err = cast5.NewCipher([]byte(*key))
case "rc5":
c, err = rc5.New([]byte(*key))
case "sm4":
c, err = sm4.NewCipher([]byte(*key))
case "seed":
c, err = krcrypt.NewSEED([]byte(*key))
case "hight":
c, err = krcrypt.NewHIGHT([]byte(*key))
case "rc2":
c, err = rc2.NewCipher([]byte(*key))
case "des":
c, err = des.NewCipher([]byte(*key))
case "3des":
c, err = des.NewTripleDESCipher([]byte(*key))
case "aes":
c, err = aes.NewCipher([]byte(*key))
case "twofish":
c, err = twofish.NewCipher([]byte(*key))
case "aria":
c, err = aria.NewCipher([]byte(*key))
case "lea":
c, err = lea.NewCipher([]byte(*key))
case "camellia":
c, err = camellia.NewCipher([]byte(*key))
case "serpent":
c, err = serpent.NewCipher([]byte(*key))
case "rc6":
c, err = rc6.NewCipher([]byte(*key))
case "ginga":
c, err = ginga.NewCipher([]byte(*key))
case "magenta":
c, err = magenta.NewCipher([]byte(*key))
case "misty1":
c, err = misty1.New([]byte(*key))
case "magma":
if len(*key) != 32 {
log.Fatal("MAGMA invalid key size ", len(*key))
}
c = gost341264.NewCipher([]byte(*key))
case "grasshopper", "kuznechik":
if len(*key) != 32 {
log.Fatal("KUZNECHIK: invalid key size ", len(*key))
}
c, err = kuznechik.NewCipher([]byte(*key))
case "gost89":
if len(*key) != 32 {
log.Fatal("GOST89: invalid key size ", len(*key))
}
c = gost28147.NewCipher([]byte(*key), &gost28147.SboxIdtc26gost28147paramZ)
case "anubis":
if len(*key) != 16 && len(*key) != 24 && len(*key) != 32 && len(*key) != 40 {
log.Fatal("ANUBIS: invalid key size ", len(*key))
}
c, err = anubis.NewWithKeySize([]byte(*key), len(*key))
case "threefish256", "threefish":
var tweak []byte
tweak = make([]byte, 16)
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
c, err = threefish.New256([]byte(*key), tweak)
case "threefish512":
var tweak []byte
tweak = make([]byte, 16)
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
c, err = threefish.New512([]byte(*key), tweak)
case "threefish1024":
var tweak []byte
tweak = make([]byte, 16)
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
c, err = threefish.New1024([]byte(*key), tweak)
case "khazad":
c, err = khazad.NewCipher([]byte(*key))
case "mars":
c, err = mars.NewCipher([]byte(*key))
case "noekeon":
c, err = noekeon.NewCipher([]byte(*key))
case "loki97":
c, err = loki97.NewCipher([]byte(*key))
case "clefia":
c, err = clefia.NewCipher([]byte(*key))
case "kalyna128_128":
c, err = kalyna.NewCipher128_128([]byte(*key))
case "kalyna128_256":
c, err = kalyna.NewCipher128_256([]byte(*key))
case "kalyna256_256":
c, err = kalyna.NewCipher256_256([]byte(*key))
case "kalyna256_512":
c, err = kalyna.NewCipher256_512([]byte(*key))
case "kalyna512_512":
c, err = kalyna.NewCipher512_512([]byte(*key))
case "cast256", "cast6":
c, err = cast256.NewCipher([]byte(*key))
case "e2":
c, err = e2.NewCipher([]byte(*key))
case "crypton":
c, err = crypton1.NewCipher([]byte(*key))
case "present":
c, err = present.NewCipher([]byte(*key))
case "twine":
c, err = twine.NewCipher([]byte(*key))
case "shacal2":
c, err = shacal2.NewCipher([]byte(*key))
case "saferplus", "safer+":
c, err = saferplus.NewCipher([]byte(*key))
case "belt":
c, err = belt.NewCipher([]byte(*key))
default:
log.Fatalf("Unsupported cipher type: %s", *cph)
}
if err != nil {
log.Fatal(err)
}
h, err := pmac.New(c)
if err != nil {
log.Fatal(err)
}
// io.Copy(h, os.Stdin)
io.Copy(h, inputfile)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum(nil))
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("PMAC-"+strings.ToUpper(*cph)+"("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *mac == "gmac" {
var c cipher.Block
var err error
key := []byte(*key)
switch *cph {
case "sm4":
c, err = sm4.NewCipher(key)
case "seed":
c, err = krcrypt.NewSEED(key)
case "aes":
c, err = aes.NewCipher(key)
case "twofish":
c, err = twofish.NewCipher(key)
case "aria":
c, err = aria.NewCipher(key)
case "lea":
c, err = lea.NewCipher(key)
case "camellia":
c, err = camellia.NewCipher(key)
case "serpent":
c, err = serpent.NewCipher(key)
case "rc6":
c, err = rc6.NewCipher(key)
case "ginga":
c, err = ginga.NewCipher(key)
case "magenta":
c, err = magenta.NewCipher(key)
case "grasshopper", "kuznechik":
c, err = kuznechik.NewCipher(key)
case "anubis":
c, err = anubis.NewWithKeySize(key, len(key))
case "mars":
c, err = mars.NewCipher(key)
case "noekeon":
c, err = noekeon.NewCipher(key)
case "loki97":
c, err = loki97.NewCipher(key)
case "clefia":
c, err = clefia.NewCipher(key)
case "kalyna128_128":
c, err = kalyna.NewCipher128_128(key)
case "kalyna128_256":
c, err = kalyna.NewCipher128_256(key)
case "cast256", "cast6":
c, err = cast256.NewCipher(key)
case "e2":
c, err = e2.NewCipher(key)
case "crypton":
c, err = crypton1.NewCipher(key)
case "saferplus", "safer+":
c, err = saferplus.NewCipher(key)
case "belt":
c, err = belt.NewCipher(key)
default:
log.Fatalf("Unsupported cipher type: %s", *cph)
}
if err != nil {
log.Fatal(err)
}
message, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
if *vector == "" || len(*vector) != 256/8 {
log.Fatal("Invalid IV size. GMAC nonce must be the same length of the block.")
}
var nonce []byte
nonce, err = hex.DecodeString(*vector)
if err != nil {
log.Fatal(err)
}
h, err := gmac.New(c, nonce, message)
if err != nil {
log.Fatal(err)
}
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h)
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("GMAC-"+strings.ToUpper(*cph)+"("+inputdesc+")=", hex.EncodeToString(h))
os.Exit(0)
}
if *mac == "mgmac" {
var c cipher.Block
var err error
key := []byte(*key)
var n int
switch *cph {
case "sm4":
c, err = sm4.NewCipher(key)
n = 16
case "seed":
c, err = krcrypt.NewSEED(key)
n = 16
case "aes":
c, err = aes.NewCipher(key)
n = 16
case "twofish":
c, err = twofish.NewCipher(key)
n = 16
case "aria":
c, err = aria.NewCipher(key)
n = 16
case "lea":
c, err = lea.NewCipher(key)
n = 16
case "camellia":
c, err = camellia.NewCipher(key)
n = 16
case "serpent":
c, err = serpent.NewCipher(key)
n = 16
case "rc6":
c, err = rc6.NewCipher(key)
n = 16
case "ginga":
c, err = ginga.NewCipher(key)
n = 16
case "magenta":
c, err = magenta.NewCipher(key)
n = 16
case "magma":
c = gost341264.NewCipher(key)
n = 8
case "gost89":
c = gost28147.NewCipher(key, &gost28147.SboxIdtc26gost28147paramZ)
n = 8
case "grasshopper", "kuznechik":
c, err = kuznechik.NewCipher(key)
n = 16
case "anubis":
c, err = anubis.NewWithKeySize(key, len(key))
n = 16
case "blowfish":
c, err = blowfish.NewCipher(key)
n = 8
case "idea":
c, err = idea.NewCipher(key)
n = 8
case "cast5":
c, err = cast5.NewCipher(key)
n = 8
case "rc5":
c, err = rc5.New(key)
n = 8
case "hight":
c, err = krcrypt.NewHIGHT(key)
n = 8
case "rc2":
c, err = rc2.NewCipher(key)
n = 8
case "des":
c, err = des.NewCipher(key)
n = 8
case "3des":
c, err = des.NewTripleDESCipher(key)
n = 8
case "khazad":
c, err = khazad.NewCipher(key)
n = 8
case "present":
c, err = present.NewCipher(key)
n = 8
case "twine":
c, err = twine.NewCipher(key)
n = 8
case "kalyna128_128":
c, err = kalyna.NewCipher128_128(key)
n = 16
case "kalyna128_256":
c, err = kalyna.NewCipher128_256(key)
n = 16
case "cast256", "cast6":
c, err = cast256.NewCipher(key)
n = 16
case "e2":
c, err = e2.NewCipher(key)
n = 16
case "crypton":
c, err = crypton1.NewCipher(key)
n = 16
case "saferplus", "safer+":
c, err = saferplus.NewCipher(key)
n = 8
case "belt":
c, err = belt.NewCipher(key)
n = 16
default:
log.Fatalf("Unsupported cipher type: %s", *cph)
}
if err != nil {
log.Fatal(err)
}
message, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
if *vector == "" || (len(*vector) != 256/8 && len(*vector) != 128/8) {
log.Fatal("Invalid IV size. MGMAC nonce must be the same length of the block.")
}
var nonce []byte
nonce, err = hex.DecodeString(*vector)
if err != nil {
log.Fatal(err)
}
nonce[0] &= 0x7F
h, err := NewMGMAC(c, n, nonce, message)
if err != nil {
log.Fatal(err)
}
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h)
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("MGMAC-"+strings.ToUpper(*cph)+"("+inputdesc+")=", hex.EncodeToString(h))
os.Exit(0)
}
if *mac == "vmac" {
var c cipher.Block
var err error
switch *cph {
case "blowfish":
c, err = blowfish.NewCipher([]byte(*key))
case "idea":
c, err = idea.NewCipher([]byte(*key))
case "cast5":
c, err = cast5.NewCipher([]byte(*key))
case "rc5":
c, err = rc5.New([]byte(*key))
case "sm4":
c, err = sm4.NewCipher([]byte(*key))
case "seed":
c, err = krcrypt.NewSEED([]byte(*key))
case "hight":
c, err = krcrypt.NewHIGHT([]byte(*key))
case "rc2":
c, err = rc2.NewCipher([]byte(*key))
case "des":
c, err = des.NewCipher([]byte(*key))
case "3des":
c, err = des.NewTripleDESCipher([]byte(*key))
case "aes":
c, err = aes.NewCipher([]byte(*key))
case "twofish":
c, err = twofish.NewCipher([]byte(*key))
case "aria":
c, err = aria.NewCipher([]byte(*key))
case "lea":
c, err = lea.NewCipher([]byte(*key))
case "camellia":
c, err = camellia.NewCipher([]byte(*key))
case "serpent":
c, err = serpent.NewCipher([]byte(*key))
case "rc6":
c, err = rc6.NewCipher([]byte(*key))
case "ginga":
c, err = ginga.NewCipher([]byte(*key))
case "magenta":
c, err = magenta.NewCipher([]byte(*key))
case "misty1":
c, err = misty1.New([]byte(*key))
case "magma":
if len(*key) != 32 {
log.Fatal("MAGMA invalid key size ", len(*key))
}
c = gost341264.NewCipher([]byte(*key))
case "grasshopper", "kuznechik":
if len(*key) != 32 {
log.Fatal("KUZNECHIK: invalid key size ", len(*key))
}
c, err = kuznechik.NewCipher([]byte(*key))
case "gost89":
if len(*key) != 32 {
log.Fatal("GOST89: invalid key size ", len(*key))
}
c = gost28147.NewCipher([]byte(*key), &gost28147.SboxIdtc26gost28147paramZ)
case "anubis":
if len(*key) != 16 && len(*key) != 24 && len(*key) != 32 && len(*key) != 40 {
log.Fatal("ANUBIS: invalid key size ", len(*key))
}
c, err = anubis.NewWithKeySize([]byte(*key), len(*key))
case "threefish256", "threefish":
var tweak []byte
tweak = make([]byte, 16)
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
c, err = threefish.New256([]byte(*key), tweak)
case "threefish512":
var tweak []byte
tweak = make([]byte, 16)
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
c, err = threefish.New512([]byte(*key), tweak)
case "threefish1024":
var tweak []byte
tweak = make([]byte, 16)
if *tweakStr != "" {
tweak = []byte(*tweakStr)
}
c, err = threefish.New1024([]byte(*key), tweak)
case "khazad":
c, err = khazad.NewCipher([]byte(*key))
case "mars":
c, err = mars.NewCipher([]byte(*key))
case "noekeon":
c, err = noekeon.NewCipher([]byte(*key))
case "loki97":
c, err = loki97.NewCipher([]byte(*key))
case "clefia":
c, err = clefia.NewCipher([]byte(*key))
case "kalyna128_128":
c, err = kalyna.NewCipher128_128([]byte(*key))
case "kalyna128_256":
c, err = kalyna.NewCipher128_256([]byte(*key))
case "kalyna256_256":
c, err = kalyna.NewCipher256_256([]byte(*key))
case "kalyna256_512":
c, err = kalyna.NewCipher256_512([]byte(*key))
case "kalyna512_512":
c, err = kalyna.NewCipher512_512([]byte(*key))
case "cast256", "cast6":
c, err = cast256.NewCipher([]byte(*key))
case "e2":
c, err = e2.NewCipher([]byte(*key))
case "crypton":
c, err = crypton1.NewCipher([]byte(*key))
case "present":
c, err = present.NewCipher([]byte(*key))
case "twine":
c, err = twine.NewCipher([]byte(*key))
case "curupira":
c, err = curupira1.NewCipher([]byte(*key))
case "shacal2":
c, err = shacal2.NewCipher([]byte(*key))
case "saferplus", "safer+":
c, err = saferplus.NewCipher([]byte(*key))
case "belt":
c, err = belt.NewCipher([]byte(*key))
default:
log.Fatalf("Unsupported cipher type: %s", *cph)
}
if err != nil {
log.Fatal(err)
}
if *vector == "" {
log.Fatal("Invalid IV size. VMAC nonce must be from 1 to block length -1.")
}
nonce, err := hex.DecodeString(*vector)
if err != nil {
log.Fatal(err)
}
h, err := vmac.New(c, []byte(*key), nonce, *length/8)
if err != nil {
log.Fatal(err)
}
// io.Copy(h, os.Stdin)
io.Copy(h, inputfile)
var verify bool
if *sig != "" {
mac := hex.EncodeToString(h.Sum())
if mac != *sig {
verify = false
fmt.Println(verify)
os.Exit(1)
} else {
verify = true
fmt.Println(verify)
os.Exit(0)
}
}
fmt.Println("VMAC-"+strings.ToUpper(*cph)+"("+inputdesc+")=", hex.EncodeToString(h.Sum()))
os.Exit(0)
}
if *mac == "xmac" || *mac == "xoodyak" {
var err error
var file io.Reader
// file = os.Stdin
file = inputfile
h := xoodyak.NewXoodyakMac([]byte(*key))
if _, err = io.Copy(h, file); err != nil {
log.Fatal(err)
}
fmt.Println("MAC-XOODYAK("+inputdesc+")=", hex.EncodeToString(h.Sum(nil)))
os.Exit(0)
}
if *kdf == "hkdf" {
hash, err := Hkdf([]byte(*key), []byte(*salt), []byte(*info))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%x\n", hash[:*length/8])
}
// Check if *pkey is one of the specified values
if strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA" && (*pkey == "sign" || *pkey == "verify" || *pkey == "derive" || *pkey == "encrypt" || *pkey == "decrypt") {
if data, err := ioutil.ReadFile(*key); err == nil {
if block, _ := pem.Decode(data); block != nil {
if strings.Contains(block.Type, "NUMS") {
*alg = "NUMS"
} else if strings.Contains(block.Type, "KOBLITZ") {
*alg = "KOBLITZ"
} else if strings.Contains(block.Type, "ANSSI") {
*alg = "ANSSI"
} else if strings.Contains(block.Type, "TOM") {
*alg = "TOM"
}
}
}
}
// var privatekey *ecdsa.PrivateKey
var pubkey ecdsa.PublicKey
var public *ecdsa.PublicKey
// var err error
var pubkeyCurve elliptic.Curve
if *pkey == "keygen" && *curveFlag == "sect283k1" {
pubkeyCurve = nist.K283()
} else if *pkey == "keygen" && *length == 283 || *curveFlag == "sect283r1" {
pubkeyCurve = nist.B283()
} else if *pkey == "keygen" && *curveFlag == "sect409k1" {
pubkeyCurve = nist.K409()
} else if *pkey == "keygen" && *length == 409 || *curveFlag == "sect409r1" {
pubkeyCurve = nist.B409()
} else if *pkey == "keygen" && *curveFlag == "sect571k1" {
pubkeyCurve = nist.K571()
} else if *pkey == "keygen" && *length == 571 || *curveFlag == "sect571r1" {
pubkeyCurve = nist.B571()
} else if *pkey == "keygen" && *curveFlag == "brainpoolp256r1" {
pubkeyCurve = brainpool.P256r1()
} else if *pkey == "keygen" && *curveFlag == "brainpoolp256t1" {
pubkeyCurve = brainpool.P256t1()
} else if *pkey == "keygen" && *curveFlag == "brainpoolp384r1" {
pubkeyCurve = brainpool.P384r1()
} else if *pkey == "keygen" && *curveFlag == "brainpoolp384t1" {
pubkeyCurve = brainpool.P384t1()
} else if *pkey == "keygen" && *curveFlag == "brainpoolp512r1" {
pubkeyCurve = brainpool.P512r1()
} else if *pkey == "keygen" && *curveFlag == "brainpoolp512t1" {
pubkeyCurve = brainpool.P512t1()
} else if *pkey == "keygen" && *curveFlag == "secp256k1" {
pubkeyCurve = secp256k1.S256()
} else if *pkey == "keygen" && *curveFlag == "frp256v1" {
pubkeyCurve = frp256v1.P256()
} else if *pkey == "keygen" && *length == 224 || *curveFlag == "secp224r1" {
pubkeyCurve = elliptic.P224()
} else if *pkey == "keygen" && *length == 384 || *curveFlag == "secp384r1" {
pubkeyCurve = elliptic.P384()
} else if *pkey == "keygen" && *length == 521 || *curveFlag == "secp521r1" {
pubkeyCurve = elliptic.P521()
} else if *pkey == "keygen" && *length == 256 || *curveFlag == "secp256r1" {
pubkeyCurve = elliptic.P256()
} else if *pkey == "keygen" && *curveFlag == "numsp256d1" {
pubkeyCurve = nums.P256d1()
} else if *pkey == "keygen" && *curveFlag == "numsp256t1" {
pubkeyCurve = nums.P256t1()
} else if *pkey == "keygen" && *curveFlag == "numsp384d1" {
pubkeyCurve = nums.P384d1()
} else if *pkey == "keygen" && *curveFlag == "numsp384t1" {
pubkeyCurve = nums.P384t1()
} else if *pkey == "keygen" && *curveFlag == "numsp512d1" {
pubkeyCurve = nums.P512d1()
} else if *pkey == "keygen" && *curveFlag == "numsp512t1" {
pubkeyCurve = nums.P512t1()
} else if *pkey == "keygen" && *curveFlag == "tom256" {
pubkeyCurve = tom.P256()
} else if *pkey == "keygen" && *curveFlag == "tom384" {
pubkeyCurve = tom.P384()
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") && (*length == 224 || *length == 256 || *length == 384 || *length == 521 || *curveFlag == "secp224r1" || *curveFlag == "secp384r1" || *curveFlag == "secp521r1" || *curveFlag == "secp256r1") && *curveFlag != "frp256v1" && *curveFlag != "secp256k1" && *curveFlag != "numsp256t1" && *curveFlag != "numsp384t1" && *curveFlag != "numsp512t1" && *curveFlag != "numsp256d1" && *curveFlag != "numsp384d1" && *curveFlag != "numsp512d1" && *curveFlag != "tom256" && *curveFlag != "tom384" {
var privatekey *ecdsa.PrivateKey
if *key != "" {
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodePrivateKey(file)
if err != nil {
log.Fatal(err)
}
} else {
privatekey, err = ecdsa.GenerateKey(pubkeyCurve, rand.Reader)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
pubkey = privatekey.PublicKey
pripem, _ := EncodePrivateKey(privatekey)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodePublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "encrypt" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") {
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
public, err = DecodePublicKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
ciphertxt, err := public.EncryptAsn1([]byte(scanner), rand.Reader)
if err != nil {
log.Fatal(err)
}
// fmt.Printf("%x\n", ciphertxt)
fmt.Printf("%s", ciphertxt)
os.Exit(0)
}
if *pkey == "decrypt" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") {
var privatekey *ecdsa.PrivateKey
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
privatekey, err = DecodePrivateKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
// str, _ := hex.DecodeString(string(scanner))
str := string(scanner)
plaintxt, err := privatekey.DecryptAsn1([]byte(str))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", plaintxt)
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "ECKCDSA") && ((*length == 224 || *length == 256 || *length == 384 || *length == 521 || *length == 283 || *length == 409 || *length == 571) || (*curveFlag == "secp224r1" || *curveFlag == "secp384r1" || *curveFlag == "secp521r1" || *curveFlag == "secp256r1" || *curveFlag == "sect283r1" || *curveFlag == "sect409r1" || *curveFlag == "sect571r1" || *curveFlag == "sect283k1" || *curveFlag == "sect409k1" || *curveFlag == "sect571k1")) {
privateKey, err := eckcdsa.GenerateKey(pubkeyCurve, rand.Reader)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pubkey := privateKey.PublicKey
pripem, _ := EncodeECKCDSAPrivateKey(privateKey)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeECKCDSAPublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "ECGDSA") && ((*length == 224 || *length == 256 || *length == 384 || *length == 512 || *length == 521) || (*curveFlag == "secp224r1" || *curveFlag == "secp384r1" || *curveFlag == "secp521r1" || *curveFlag == "secp256r1" || *curveFlag != "frp256v1" || *curveFlag != "secp256k1" || *curveFlag == "brainpoolp256r1" || *curveFlag == "brainpoolp384r1" || *curveFlag == "brainpoolp512r1" || *curveFlag == "brainpoolp256t1" || *curveFlag == "brainpoolp384t1" || *curveFlag == "brainpoolp512t1" || *curveFlag == "numsp256t1" || *curveFlag == "numsp384t1" || *curveFlag == "numsp512t1" || *curveFlag == "numsp256d1" || *curveFlag == "numsp384d1" || *curveFlag == "numsp512d1" || *curveFlag == "tom256" || *curveFlag == "tom384" || *curveFlag == "sect283r1" || *curveFlag == "sect409r1" || *curveFlag == "sect571r1" || *curveFlag == "sect283k1" || *curveFlag == "sect409k1" || *curveFlag == "sect571k1")) {
privateKey, err := ecgdsa.GenerateKey(rand.Reader, pubkeyCurve)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pubkey := privateKey.PublicKey
pripem, _ := EncodeECGDSAPrivateKey(privateKey)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeECGDSAPublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "ECSDSA") && ((*length == 224 || *length == 256 || *length == 384 || *length == 512 || *length == 521) || (*curveFlag == "secp224r1" || *curveFlag == "secp384r1" || *curveFlag == "secp521r1" || *curveFlag == "secp256r1" || *curveFlag != "frp256v1" || *curveFlag != "secp256k1" || *curveFlag == "brainpoolp256r1" || *curveFlag == "brainpoolp384r1" || *curveFlag == "brainpoolp512r1" || *curveFlag == "brainpoolp256t1" || *curveFlag == "brainpoolp384t1" || *curveFlag == "brainpoolp512t1" || *curveFlag == "numsp256t1" || *curveFlag == "numsp384t1" || *curveFlag == "numsp512t1" || *curveFlag == "numsp256d1" || *curveFlag == "numsp384d1" || *curveFlag == "numsp512d1" || *curveFlag == "tom256" || *curveFlag == "tom384" || *curveFlag == "sect283r1" || *curveFlag == "sect409r1" || *curveFlag == "sect571r1" || *curveFlag == "sect283k1" || *curveFlag == "sect409k1" || *curveFlag == "sect571k1")) {
privateKey, err := ecsdsa.GenerateKey(rand.Reader, pubkeyCurve)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pubkey := privateKey.PublicKey
pripem, _ := EncodeECSDSAPrivateKey(privateKey)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeECSDSAPublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "BIP0340") && ((*length == 224 || *length == 256 || *length == 384 || *length == 512 || *length == 521) || (*curveFlag == "secp224r1" || *curveFlag == "secp384r1" || *curveFlag == "secp521r1" || *curveFlag == "secp256r1" || *curveFlag != "frp256v1" || *curveFlag != "secp256k1" || *curveFlag == "brainpoolp256r1" || *curveFlag == "brainpoolp384r1" || *curveFlag == "brainpoolp512r1" || *curveFlag == "brainpoolp256t1" || *curveFlag == "brainpoolp384t1" || *curveFlag == "brainpoolp512t1" || *curveFlag == "numsp256t1" || *curveFlag == "numsp384t1" || *curveFlag == "numsp512t1" || *curveFlag == "numsp256d1" || *curveFlag == "numsp384d1" || *curveFlag == "numsp512d1" || *curveFlag == "tom256" || *curveFlag == "tom384" || *curveFlag == "sect283r1" || *curveFlag == "sect409r1" || *curveFlag == "sect571r1" || *curveFlag == "sect283k1" || *curveFlag == "sect409k1" || *curveFlag == "sect571k1")) {
privateKey, err := bip0340.GenerateKey(rand.Reader, pubkeyCurve)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pubkey := privateKey.PublicKey
pripem, _ := EncodeBIP0340PrivateKey(privateKey)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeBIP0340PublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "keygen" && strings.ToUpper(*alg) == "ANSSI" || (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") && *curveFlag == "frp256v1" {
privateKey, err := ecdsa.GenerateKey(frp256v1.P256(), rand.Reader)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pk := frp256v1.NewPrivateKey(privateKey)
pubkey := pk.PublicKey
pripem, _ := EncodeANSSIPrivateKey(pk)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeANSSIPublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "encrypt" && (strings.ToUpper(*alg) == "ANSSI") {
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
public, err := DecodeANSSIPublicKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
ciphertxt, err := public.ToECDSA().EncryptAsn1([]byte(scanner), rand.Reader)
if err != nil {
log.Fatal(err)
}
// fmt.Printf("%x\n", ciphertxt)
fmt.Printf("%s", ciphertxt)
os.Exit(0)
}
if *pkey == "decrypt" && (strings.ToUpper(*alg) == "ANSSI") {
var privatekey *frp256v1.PrivateKey
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
privatekey, err = DecodeANSSIPrivateKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
// str, _ := hex.DecodeString(string(scanner))
str := string(scanner)
plaintxt, err := privatekey.ToECDSAPrivateKey().DecryptAsn1([]byte(str))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", plaintxt)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "ANSSI") {
var privatekey *frp256v1.PrivateKey
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeANSSIPrivateKey(file)
if err != nil {
log.Fatal(err)
}
signature, err := ecdsa.SignASN1(rand.Reader, privatekey.ToECDSAPrivateKey(), h.Sum(nil))
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "ANSSI") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
public, err := DecodeANSSIPublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, _ := hex.DecodeString(*sig)
verifystatus := ecdsa.VerifyASN1(public.ToECDSA(), h.Sum(nil), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "derive" && strings.ToUpper(*alg) == "ANSSI" {
var privatekey *frp256v1.PrivateKey
file, err := ioutil.ReadFile(*pub)
if err != nil {
log.Fatal(err)
}
public, err := DecodeANSSIPublicKey(file)
if err != nil {
log.Fatal(err)
}
file2, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
privatekey, err = DecodeANSSIPrivateKey(file2)
if err != nil {
log.Fatal(err)
}
sharedKey, err := frp256v1.ECDH(privatekey.ToECDSAPrivateKey(), public.ToECDSA())
if err != nil {
log.Fatal("Error computing shared key:", err)
}
fmt.Printf("%x\n", sharedKey)
os.Exit(0)
}
if *pkey == "derive" && strings.ToUpper(*alg) == "BIP0340" {
var privatekey *bip0340.PrivateKey
file, err := ioutil.ReadFile(*pub)
if err != nil {
log.Fatal(err)
}
public, err := DecodeBIP0340PublicKey(file)
if err != nil {
log.Fatal(err)
}
file2, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
privatekey, err = DecodeBIP0340PrivateKey(file2)
if err != nil {
log.Fatal(err)
}
b, _ := public.Curve.ScalarMult(public.X, public.Y, privatekey.D.Bytes())
fmt.Printf("%x\n", b.Bytes())
os.Exit(0)
}
if *pkey == "derive" && strings.ToUpper(*alg) == "ECSDSA" {
var privatekey *ecsdsa.PrivateKey
file, err := ioutil.ReadFile(*pub)
if err != nil {
log.Fatal(err)
}
public, err := DecodeECSDSAPublicKey(file)
if err != nil {
log.Fatal(err)
}
file2, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
privatekey, err = DecodeECSDSAPrivateKey(file2)
if err != nil {
log.Fatal(err)
}
b, _ := public.Curve.ScalarMult(public.X, public.Y, privatekey.D.Bytes())
fmt.Printf("%x\n", b.Bytes())
os.Exit(0)
}
if *pkey == "keygen" && strings.ToUpper(*alg) == "KOBLITZ" || (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") && *curveFlag == "secp256k1" {
privateKey, err := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pk := secp256k1.NewPrivateKey(privateKey)
pubkey := pk.PublicKey
pripem, _ := EncodeKOBLITZPrivateKey(pk)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeKOBLITZPublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "encrypt" && (strings.ToUpper(*alg) == "KOBLITZ") {
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
public, err := DecodeKOBLITZPublicKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
ciphertxt, err := public.ToECDSA().EncryptAsn1([]byte(scanner), rand.Reader)
if err != nil {
log.Fatal(err)
}
// fmt.Printf("%x\n", ciphertxt)
fmt.Printf("%s", ciphertxt)
os.Exit(0)
}
if *pkey == "decrypt" && (strings.ToUpper(*alg) == "KOBLITZ") {
var privatekey *secp256k1.PrivateKey
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
privatekey, err = DecodeKOBLITZPrivateKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
// str, _ := hex.DecodeString(string(scanner))
str := string(scanner)
plaintxt, err := privatekey.ToECDSAPrivateKey().DecryptAsn1([]byte(str))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", plaintxt)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "KOBLITZ") {
var privatekey *secp256k1.PrivateKey
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeKOBLITZPrivateKey(file)
if err != nil {
log.Fatal(err)
}
signature, err := ecdsa.SignASN1(rand.Reader, privatekey.ToECDSAPrivateKey(), h.Sum(nil))
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "KOBLITZ") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
public, err := DecodeKOBLITZPublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, _ := hex.DecodeString(*sig)
verifystatus := ecdsa.VerifyASN1(public.ToECDSA(), h.Sum(nil), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "derive" && strings.ToUpper(*alg) == "KOBLITZ" {
var privatekey *secp256k1.PrivateKey
file, err := ioutil.ReadFile(*pub)
if err != nil {
log.Fatal(err)
}
public, err := DecodeKOBLITZPublicKey(file)
if err != nil {
log.Fatal(err)
}
file2, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
privatekey, err = DecodeKOBLITZPrivateKey(file2)
if err != nil {
log.Fatal(err)
}
sharedKey, err := secp256k1.ECDH(privatekey.ToECDSAPrivateKey(), public.ToECDSA())
if err != nil {
log.Fatal("Error computing shared key:", err)
}
fmt.Printf("%x\n", sharedKey)
os.Exit(0)
}
if *pkey == "keygen" && strings.ToUpper(*alg) == "TOM" || ((strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") && *curveFlag == "tom256" || *curveFlag == "tom384") {
var curve elliptic.Curve
if *length == 256 || *curveFlag == "tom256" {
curve = tom.P256()
} else if *length == 384 || *curveFlag == "tom384" {
curve = tom.P384()
}
privateKey, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pk := tom.NewPrivateKey(privateKey)
pubkey := pk.PublicKey
pripem, _ := EncodeTomPrivateKey(pk)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeTomPublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "encrypt" && (strings.ToUpper(*alg) == "TOM") {
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
public, err := DecodeTomPublicKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
ciphertxt, err := public.ToECDSA().EncryptAsn1([]byte(scanner), rand.Reader)
if err != nil {
log.Fatal(err)
}
// fmt.Printf("%x\n", ciphertxt)
fmt.Printf("%s", ciphertxt)
os.Exit(0)
}
if *pkey == "decrypt" && (strings.ToUpper(*alg) == "TOM") {
var privatekey *tom.PrivateKey
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
privatekey, err = DecodeTomPrivateKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
// str, _ := hex.DecodeString(string(scanner))
str := string(scanner)
plaintxt, err := privatekey.ToECDSAPrivateKey().DecryptAsn1([]byte(str))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", plaintxt)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "TOM") {
var privatekey *tom.PrivateKey
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeTomPrivateKey(file)
if err != nil {
log.Fatal(err)
}
signature, err := ecdsa.SignASN1(rand.Reader, privatekey.ToECDSAPrivateKey(), h.Sum(nil))
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "TOM") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
public, err := DecodeTomPublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, _ := hex.DecodeString(*sig)
verifystatus := ecdsa.VerifyASN1(public.ToECDSA(), h.Sum(nil), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "derive" && strings.ToUpper(*alg) == "TOM" {
var privatekey *tom.PrivateKey
file, err := ioutil.ReadFile(*pub)
if err != nil {
log.Fatal(err)
}
public, err := DecodeTomPublicKey(file)
if err != nil {
log.Fatal(err)
}
file2, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
privatekey, err = DecodeTomPrivateKey(file2)
if err != nil {
log.Fatal(err)
}
sharedKey, err := tom.ECDH(privatekey.ToECDSAPrivateKey(), public.ToECDSA())
if err != nil {
log.Fatal("Error computing shared key:", err)
}
fmt.Printf("%x\n", sharedKey)
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "BIGN") && (*length == 256 || *length == 384 || *length == 512) {
var BignCurve elliptic.Curve
if *length == 256 {
BignCurve = bigncurves.P256v1()
} else if *length == 384 {
BignCurve = bigncurves.P384v1()
} else if *length == 512 {
BignCurve = bigncurves.P512v1()
}
privateKey, err := bign.GenerateKey(rand.Reader, BignCurve)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pubkey := privateKey.PublicKey
pripem, _ := EncodeBIGNPrivateKey(privateKey)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeBIGNPublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "SM2") {
var privatekey *sm2.PrivateKey
if *key != "" {
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeSM2PrivateKey(file)
if err != nil {
log.Fatal(err)
}
} else {
privatekey, err = sm2.GenerateKey(rand.Reader)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
pubkey = privatekey.PublicKey
pripem, _ := EncodeSM2PrivateKey(privatekey)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodePublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(block)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "encrypt" && (strings.ToUpper(*alg) == "SM2") {
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
public, err = DecodePublicKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
ciphertxt, err := sm2.EncryptASN1(rand.Reader, public, []byte(scanner))
if err != nil {
log.Fatal(err)
}
// fmt.Printf("%x\n", ciphertxt)
fmt.Printf("%s", ciphertxt)
os.Exit(0)
}
if *pkey == "decrypt" && (strings.ToUpper(*alg) == "SM2") {
var privatekey *sm2.PrivateKey
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
privatekey, err = DecodeSM2PrivateKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
// str, _ := hex.DecodeString(string(scanner))
str := string(scanner)
plaintxt, err := sm2.Decrypt(privatekey, []byte(str))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", plaintxt)
os.Exit(0)
}
if *pkey == "keygen" && ((strings.ToUpper(*alg) == "NUMS" || strings.ToUpper(*alg) == "NUMS-TE") && (*length == 256 || *length == 384 || *length == 512)) || ((strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") && (*curveFlag == "numsp256d1" || *curveFlag == "numsp384d1" || *curveFlag == "numsp512d1" || *curveFlag == "numsp256t1" || *curveFlag == "numsp384t1" || *curveFlag == "numsp512t1")) {
var curve elliptic.Curve
if (strings.ToUpper(*alg) == "NUMS" || strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") && (*curveFlag == "numsp256d1" || *curveFlag == "numsp384d1" || *curveFlag == "numsp512d1") {
if *length == 256 || *curveFlag == "numsp256d1" {
curve = nums.P256d1()
} else if *length == 384 || *curveFlag == "numsp384d1" {
curve = nums.P384d1()
} else if *length == 512 || *curveFlag == "numsp512d1" {
curve = nums.P512d1()
}
} else if strings.ToUpper(*alg) == "NUMS-TE" || ((strings.ToUpper(*alg) == "NUMS" ||strings.ToUpper(*alg) == "NUMS-TE" || strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") && (*curveFlag == "numsp256t1" || *curveFlag == "numsp384t1" || *curveFlag == "numsp512t1")) {
if *length == 256 || *curveFlag == "numsp256t1" {
curve = nums.P256t1()
} else if *length == 384 || *curveFlag == "numsp384t1" {
curve = nums.P384t1()
} else if *length == 512 || *curveFlag == "numsp512t1" {
curve = nums.P512t1()
}
}
privateKey, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
log.Fatal("Error generating private key:", err)
}
pk := nums.NewPrivateKey(privateKey)
pubkey := pk.PublicKey
pripem, _ := EncodeNUMSPrivateKey(pk)
ioutil.WriteFile(*priv, pripem, 0644)
pubpem, _ := EncodeNUMSPublicKey(&pubkey)
ioutil.WriteFile(*pub, pubpem, 0644)
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pubpem)
if block == nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
keySize := pk.PublicKey.Curve.Params().BitSize
switch keySize {
case 256:
fmt.Println("NUMS (256-bit)")
case 384:
fmt.Println("NUMS (384-bit)")
case 512:
fmt.Println("NUMS (512-bit)")
default:
fmt.Printf("Unknown key size: %d bits\n", keySize)
}
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "encrypt" && (strings.ToUpper(*alg) == "NUMS") {
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
public, err := DecodeNUMSPublicKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
ciphertxt, err := public.ToECDSA().EncryptAsn1([]byte(scanner), rand.Reader)
if err != nil {
log.Fatal(err)
}
// fmt.Printf("%x\n", ciphertxt)
fmt.Printf("%s", ciphertxt)
os.Exit(0)
}
if *pkey == "decrypt" && (strings.ToUpper(*alg) == "NUMS") {
var privatekey *nums.PrivateKey
file, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
privatekey, err = DecodeNUMSPrivateKey(file)
if err != nil {
log.Fatal(err)
}
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
scanner := string(buf.Bytes())
// str, _ := hex.DecodeString(string(scanner))
str := string(scanner)
plaintxt, err := privatekey.ToECDSAPrivateKey().DecryptAsn1([]byte(str))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", plaintxt)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "NUMS") {
var privatekey *nums.PrivateKey
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeNUMSPrivateKey(file)
if err != nil {
log.Fatal(err)
}
signature, err := ecdsa.SignASN1(rand.Reader, privatekey.ToECDSAPrivateKey(), h.Sum(nil))
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "NUMS") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
public, err := DecodeNUMSPublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, _ := hex.DecodeString(*sig)
verifystatus := ecdsa.VerifyASN1(public.ToECDSA(), h.Sum(nil), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "derive" && strings.ToUpper(*alg) == "NUMS" {
var privatekey *nums.PrivateKey
file, err := ioutil.ReadFile(*pub)
if err != nil {
log.Fatal(err)
}
public, err := DecodeNUMSPublicKey(file)
if err != nil {
log.Fatal(err)
}
file2, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
privatekey, err = DecodeNUMSPrivateKey(file2)
if err != nil {
log.Fatal(err)
}
sharedKey, err := nums.ECDH(privatekey.ToECDSAPrivateKey(), public.ToECDSA())
if err != nil {
log.Fatal("Error computing shared key:", err)
}
fmt.Printf("%x\n", sharedKey)
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "ED25519") {
var privatekey ed25519.PrivateKey
var public ed25519.PublicKey
public, privatekey, err = ed25519.GenerateKey(rand.Reader)
if err != nil {
log.Fatal(err)
}
privateStream, err := x509.MarshalPKCS8PrivateKey(privatekey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PRIVATE KEY",
Bytes: privateStream,
}
file, err := os.Create(*priv)
if err != nil {
log.Fatal(err)
}
if *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
publicStream, err := x509.MarshalPKIXPublicKey(public)
if err != nil {
log.Fatal(err)
}
pubblock := &pem.Block{
Type: "PUBLIC KEY",
Bytes: publicStream,
}
pubfile, err := os.Create(*pub)
if err != nil {
log.Fatal(err)
}
err = pem.Encode(pubfile, pubblock)
if err != nil {
log.Fatal(err)
}
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(pubblock)
randomArt := randomart.FromString(string(buf))
println(randomArt)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "ED448") {
var privatekey ed448.PrivateKey
var public ed448.PublicKey
public, privatekey, err = ed448.GenerateKey(rand.Reader)
if err != nil {
log.Fatal(err)
}
privateStream, err := ed448.MarshalPrivateKey(privatekey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "ED448 PRIVATE KEY",
Bytes: privateStream,
}
file, err := os.Create(*priv)
if err != nil {
log.Fatal(err)
}
if *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
publicStream, err := ed448.MarshalPublicKey(public)
if err != nil {
log.Fatal(err)
}
pubblock := &pem.Block{
Type: "ED448 PUBLIC KEY",
Bytes: publicStream,
}
pubfile, err := os.Create(*pub)
if err != nil {
log.Fatal(err)
}
err = pem.Encode(pubfile, pubblock)
if err != nil {
log.Fatal(err)
}
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(pubblock)
randomArt := randomart.FromString(string(buf))
println(randomArt)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "ED448PH") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "ED448 PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = ed448.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
edKey := privKey
signature := ed448.Sign(edKey, h.Sum(nil))
fmt.Println("ED448PH-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "ED448PH") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
publicInterface, err := ed448.ParsePublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface
sig, _ := hex.DecodeString(*sig)
verifystatus := ed448.Verify(publicKey, h.Sum(nil), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "ED448") {
data := bytes.NewBuffer(nil)
if _, err := io.Copy(data, inputfile); err != nil {
log.Fatal(err)
}
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "ED448 PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = ed448.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
edKey := privKey
signature := ed448.Sign(edKey, data.Bytes())
fmt.Println("PureED448("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "ED448") {
data := bytes.NewBuffer(nil)
if _, err := io.Copy(data, inputfile); err != nil {
log.Fatal(err)
}
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
publicInterface, err := ed448.ParsePublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface
sig, _ := hex.DecodeString(*sig)
verifystatus := ed448.Verify(publicKey, data.Bytes(), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "setup" && (strings.ToUpper(*alg) == "SM9SIGN") {
// var masterkey *sm9.SignMasterPrivateKey
// var public *sm9.SignMasterPublicKey
masterKey, err := sm9.GenerateSignMasterKey(rand.Reader)
if err != nil {
fmt.Println("Error generating SM9 master key:", err)
return
}
masterKeyBytes, err := smx509.MarshalPKCS8PrivateKey(masterKey)
if err != nil {
fmt.Println("Error marshaling master key:", err)
return
}
block := &pem.Block{
Type: "SM9 SIGN MASTER KEY",
Bytes: masterKeyBytes,
}
file, err := os.Create(*master)
if err != nil {
log.Fatal(err)
}
if *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
pubKey, err := masterKey.Public().MarshalASN1()
if err != nil {
fmt.Println("Error marshaling master key:", err)
return
}
pubblock := &pem.Block{
Type: "SM9 SIGN PUBLIC KEY",
Bytes: pubKey,
}
pubfile, err := os.Create(*pub)
if err != nil {
log.Fatal(err)
}
err = pem.Encode(pubfile, pubblock)
if err != nil {
log.Fatal(err)
}
absPrivPath, err := filepath.Abs(*master)
if err != nil {
log.Fatal("Failed to get absolute path for master key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Master key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
// printKeyDetails(pubblock)
fmt.Fprintln(os.Stderr, "SM9 Sign Master Public Key (256-bit)")
randomArt := randomart.FromString(string(buf))
println(randomArt)
}
if *pkey == "setup" && (strings.ToUpper(*alg) == "SM9ENCRYPT") {
// var masterkey *sm9.SignMasterPrivateKey
// var public *sm9.SignMasterPublicKey
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
if err != nil {
fmt.Println("Error generating SM9 master key:", err)
return
}
masterKeyBytes, err := smx509.MarshalPKCS8PrivateKey(masterKey)
if err != nil {
fmt.Println("Error marshaling master key:", err)
return
}
block := &pem.Block{
Type: "SM9 ENC MASTER KEY",
Bytes: masterKeyBytes,
}
file, err := os.Create(*master)
if err != nil {
log.Fatal(err)
}
if *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
pubKey, err := masterKey.Public().MarshalASN1()
if err != nil {
fmt.Println("Error marshaling master key:", err)
return
}
pubblock := &pem.Block{
Type: "SM9 ENC PUBLIC KEY",
Bytes: pubKey,
}
pubfile, err := os.Create(*pub)
if err != nil {
log.Fatal(err)
}
err = pem.Encode(pubfile, pubblock)
if err != nil {
log.Fatal(err)
}
absPrivPath, err := filepath.Abs(*master)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Master key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
// printKeyDetails(pubblock)
fmt.Fprintln(os.Stderr, "SM9 Encrypt Master Public Key (256-bit)")
randomArt := randomart.FromString(string(buf))
println(randomArt)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "SM9ENCRYPT") {
var privPEM []byte
file, err := os.Open(*master)
if err != nil {
log.Fatal(err)
}
fileinfo, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, fileinfo.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
parsedKey, _ := smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
var masterKey *sm9.EncryptMasterPrivateKey
switch key := parsedKey.(type) {
case *sm9.EncryptMasterPrivateKey:
masterKey = key
default:
log.Fatal("Invalid private key type. Expected sm9.EncryptMasterPrivateKey.")
}
userKey, err := masterKey.GenerateUserKey([]byte(*id), byte(*hierarchy))
if err != nil {
fmt.Println("Error generating SM9 user key:", err)
return
}
privKeyBytes, err = smx509.MarshalPKCS8PrivateKey(userKey)
if err != nil {
log.Fatal(err)
}
block = &pem.Block{
Type: "SM9 ENC PRIVATE KEY",
Bytes: privKeyBytes,
}
file, err = os.Create(*priv)
if err != nil {
log.Fatal(err)
}
if *pwd2 != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd2), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
}
if *pkey == "encrypt" && (strings.ToUpper(*alg) == "SM9ENCRYPT") {
fileContent, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Erro ao ler o arquivo:", err)
return
}
block, _ := pem.Decode(fileContent)
if block == nil {
fmt.Println("Failed to decode PEM block containing the public key.")
return
}
pubKey := new(sm9.EncryptMasterPublicKey)
err = pubKey.UnmarshalASN1(block.Bytes)
if err != nil {
fmt.Println("Error parsing public key with UnmarshalASN1:", err)
return
}
plaintext, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading input file:", err)
os.Exit(1)
}
ciphertext, err := sm9.EncryptASN1(rand.Reader, pubKey, []byte(*id), byte(*hierarchy), plaintext, sm9.DefaultEncrypterOpts)
if err != nil {
fmt.Println("Error encrypting the message:", err)
return
}
fmt.Printf("%s", ciphertext)
}
if *pkey == "decrypt" && (strings.ToUpper(*alg) == "SM9ENCRYPT") {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
fileinfo, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, fileinfo.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
encryptPrivateKey, ok := privKey.(*sm9.EncryptPrivateKey)
if !ok {
fmt.Println("Invalid private key type. Expected sm9.EncryptPrivateKey.")
os.Exit(1)
}
ciphertext, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading input file:", err)
os.Exit(1)
}
decryptedText, err := encryptPrivateKey.DecryptASN1([]byte(*id), ciphertext)
if err != nil {
fmt.Println("Error decrypting the message:", err)
return
}
fmt.Printf("%s", decryptedText)
}
if *pkey == "wrapkey" && (strings.ToUpper(*alg) == "SM9ENCRYPT") {
fileContent, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Erro ao ler o arquivo:", err)
return
}
block, _ := pem.Decode(fileContent)
if block == nil {
fmt.Println("Failed to decode PEM block containing the public key.")
return
}
pubKey := new(sm9.EncryptMasterPublicKey)
err = pubKey.UnmarshalASN1(block.Bytes)
if err != nil {
fmt.Println("Error parsing public key with UnmarshalASN1:", err)
return
}
keyPackage, err := pubKey.WrapKeyASN1(rand.Reader, []byte(*id), byte(*hierarchy), *length/8)
if err != nil {
log.Fatal(err)
}
key, cipher, err := sm9.UnmarshalSM9KeyPackage(keyPackage)
if err != nil {
log.Fatal(err)
}
cipherMarshaled := cipher.Marshal()
fmt.Printf("Cipher= %x\n", cipherMarshaled)
fmt.Printf("Shared= %x\n", key)
}
if *pkey == "unwrapkey" && (strings.ToUpper(*alg) == "SM9ENCRYPT") {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
fileinfo, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, fileinfo.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
encryptPrivateKey, ok := privKey.(*sm9.EncryptPrivateKey)
if !ok {
fmt.Println("Invalid private key type. Expected sm9.EncryptPrivateKey.")
os.Exit(1)
}
cipherHexString := strings.Replace(*cph, "\r\n", "", -1)
cipherHexString = strings.Replace(string(cipherHexString), "\n", "", -1)
cipherHexString = strings.Replace(string(cipherHexString), " ", "", -1)
cipherMarshaled, err := hex.DecodeString(cipherHexString)
if err != nil {
log.Fatal(err)
}
var cipher bn256.G1
_, err = cipher.Unmarshal(cipherMarshaled)
if err != nil {
log.Fatal(err)
}
key, err := sm9.UnwrapKey(encryptPrivateKey, []byte(*id), &cipher, *length/8)
if err != nil {
os.Exit(1)
}
fmt.Printf("Shared= %x\n", key)
}
// if (*pkey == "derivea" || *pkey == "deriveb") && (strings.ToUpper(*alg) == "SM9ENCRYPT") {
if (*pkey == "derivea" || *pkey == "deriveb") {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
fileinfo, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, fileinfo.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
encryptPrivateKey, ok := privKey.(*sm9.EncryptPrivateKey)
if !ok {
fmt.Println("Invalid private key type. Expected sm9.EncryptPrivateKey.")
os.Exit(1)
}
if *pkey == "derivea" {
// deriveA
aExchange := sm9.NewKeyExchange(encryptPrivateKey, []byte(*id), []byte(*id2), *length/8, true)
defer func() {
aExchange.Destroy()
}()
rA, err := aExchange.InitKeyExchange(rand.Reader, byte(*hierarchy))
if err != nil {
log.Fatal("Error during key exchange A: ", err)
}
fmt.Println("rA=", hex.EncodeToString(rA.Marshal()))
// Read rB and signB from stdin
var rB, signB string
fmt.Print("Enter rB: ")
fmt.Scanln(&rB)
fmt.Print("Enter signB: ")
fmt.Scanln(&signB)
rBBytes, err := hex.DecodeString(rB)
if err != nil {
log.Fatal("Error decoding rB: ", err)
}
signBBytes, err := hex.DecodeString(signB)
if err != nil {
log.Fatal("Error decoding signB: ", err)
}
// A5 - A8
var g1RB bn256.G1
_, err = g1RB.Unmarshal(rBBytes)
if err != nil {
log.Fatal("Error unmarshalling rB:", err)
}
key1, _, err := aExchange.ConfirmResponder(&g1RB, signBBytes)
if err != nil {
log.Fatal("Error during confirmation A: ", err)
}
fmt.Println("Shared=", hex.EncodeToString(key1))
} else if *pkey == "deriveb" {
// deriveB
// Read rA from stdin
var rA string
fmt.Print("Enter rA: ")
fmt.Scanln(&rA)
rABytes, err := hex.DecodeString(rA)
if err != nil {
log.Fatal("Error decoding rA:", err)
}
bExchange := sm9.NewKeyExchange(encryptPrivateKey, []byte(*id), []byte(*id2), *length/8, true)
defer func() {
bExchange.Destroy()
}()
// B1 - B7
var g1RA bn256.G1
_, err = g1RA.Unmarshal(rABytes)
if err != nil {
log.Fatal("Error unmarshalling rA: ", err)
}
rB, sigB, err := bExchange.RepondKeyExchange(rand.Reader, byte(*hierarchy), &g1RA)
if err != nil {
log.Fatal("Error during key exchange B: ", err)
}
// B8
key2, err := bExchange.ConfirmInitiator(nil)
if err != nil {
log.Fatal("Error during confirmation B: ", err)
}
fmt.Println("rB=", hex.EncodeToString(rB.Marshal()))
fmt.Println("signB=", hex.EncodeToString(sigB))
fmt.Println("Shared=", hex.EncodeToString(key2))
}
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "SM9SIGN") {
var privPEM []byte
file, err := os.Open(*master)
if err != nil {
log.Fatal(err)
}
fileinfo, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, fileinfo.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
parsedKey, _ := smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
var masterKey *sm9.SignMasterPrivateKey
switch key := parsedKey.(type) {
case *sm9.SignMasterPrivateKey:
masterKey = key
default:
log.Fatal("Invalid private key type. Expected sm9.SignMasterPrivateKey.")
}
userKey, err := masterKey.GenerateUserKey([]byte(*id), byte(*hierarchy))
if err != nil {
fmt.Println("Error generating SM9 user key:", err)
return
}
privKeyBytes, err = smx509.MarshalPKCS8PrivateKey(userKey)
if err != nil {
log.Fatal(err)
}
block = &pem.Block{
Type: "SM9 SIGN PRIVATE KEY",
Bytes: privKeyBytes,
}
file, err = os.Create(*priv)
if err != nil {
log.Fatal(err)
}
if *pwd2 != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd2), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "SM9SIGN" || strings.ToUpper(*alg) == "SM9SIGNPH") {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
signPrivateKey, ok := privKey.(*sm9.SignPrivateKey)
if !ok {
fmt.Println("Invalid private key type. Expected sm9.SignPrivateKey.")
os.Exit(1)
}
/*
hashed, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading input file:", err)
os.Exit(1)
}
*/
var hashed []byte
if strings.ToUpper(*alg) == "SM9SIGN" {
hashed, err = ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading input file:", err)
os.Exit(1)
}
} else {
var h hash.Hash
h = myHash()
_, err = io.Copy(h, inputfile)
if err != nil {
fmt.Println("Error hashing input file:", err)
os.Exit(1)
}
hashed = h.Sum(nil)
}
signature, err := sm9.SignASN1(rand.Reader, signPrivateKey, hashed)
if err != nil {
fmt.Println("Error signing the message:", err)
os.Exit(1)
}
if strings.ToUpper(*alg) == "SM9SIGN" {
fmt.Printf("PureSM9(%s)= %x\n", inputdesc, signature)
} else {
fmt.Printf("SM9-"+strings.ToUpper(*md)+"(%s)= %x\n", inputdesc, signature)
}
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "SM9SIGN" || strings.ToUpper(*alg) == "SM9SIGNPH") {
fileContent, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Erro ao ler o arquivo:", err)
return
}
block, _ := pem.Decode(fileContent)
if block == nil {
fmt.Println("Failed to decode PEM block containing the public key.")
return
}
pubKey := new(sm9.SignMasterPublicKey)
err = pubKey.UnmarshalASN1(block.Bytes)
if err != nil {
fmt.Println("Error parsing public key with UnmarshalASN1:", err)
return
}
/*
hashed, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading input file:", err)
os.Exit(1)
}
*/
var hashed []byte
if strings.ToUpper(*alg) == "SM9SIGN" {
hashed, err = ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading input file:", err)
os.Exit(1)
}
} else {
var h hash.Hash
h = myHash()
_, err = io.Copy(h, inputfile)
if err != nil {
fmt.Println("Error hashing input file:", err)
os.Exit(1)
}
hashed = h.Sum(nil)
}
signature, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding hex signature:", err)
os.Exit(1)
}
if sm9.VerifyASN1(pubKey, []byte(*id), byte(*hierarchy), hashed, signature) {
fmt.Println("Verified: true")
os.Exit(0)
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
}
// if *pkey == "sign" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA" || strings.ToUpper(*alg) == "SM2") {
if *pkey == "sign" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") {
var privatekey *ecdsa.PrivateKey
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodePrivateKey(file)
if err != nil {
log.Fatal(err)
}
signature, err := ecdsa.SignASN1(rand.Reader, privatekey, h.Sum(nil))
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
// if *pkey == "verify" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA" || strings.ToUpper(*alg) == "SM2") {
if *pkey == "verify" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
public, err = DecodePublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
verifystatus := ecdsa.VerifyASN1(public, h.Sum(nil), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "ECKCDSA") {
var privatekey *eckcdsa.PrivateKey
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeECKCDSAPrivateKey(file)
if err != nil {
log.Fatal(err)
}
// signature, err := eckcdsa.SignASN1(rand.Reader, privatekey, myHash(), h.Sum(nil))
signature, err := eckcdsa.SignASN1(rand.Reader, privatekey, myHash(), input)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "ECKCDSA") {
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
publica, err := DecodeECKCDSAPublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
// verifystatus := eckcdsa.VerifyASN1(publica, myHash(), h.Sum(nil), sig)
verifystatus := eckcdsa.VerifyASN1(publica, myHash(), input, sig)
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "ECGDSA") {
var privatekey *ecgdsa.PrivateKey
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeECGDSAPrivateKey(file)
if err != nil {
log.Fatal(err)
}
opts := &ecgdsa.SignerOpts{
Hash: myHash,
}
// signature, err := privatekey.Sign(rand.Reader, h.Sum(nil), opts)
signature, err := privatekey.Sign(rand.Reader, input, opts)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "ECGDSA") {
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
opts := &ecgdsa.SignerOpts{
Hash: myHash,
}
publica, err := DecodeECGDSAPublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
// verifystatus, err := publica.Verify(h.Sum(nil), sig, opts)
verifystatus, err := publica.Verify(input, sig, opts)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "ECSDSA") {
var privatekey *ecsdsa.PrivateKey
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeECSDSAPrivateKey(file)
if err != nil {
log.Fatal(err)
}
opts := &ecsdsa.SignerOpts{
Hash: myHash,
}
// signature, err := privatekey.Sign(rand.Reader, h.Sum(nil), opts)
signature, err := privatekey.Sign(rand.Reader, input, opts)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "ECSDSA") {
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
opts := &ecsdsa.SignerOpts{
Hash: myHash,
}
publica, err := DecodeECSDSAPublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
// verifystatus, err := publica.Verify(h.Sum(nil), sig, opts)
verifystatus, err := publica.Verify(input, sig, opts)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "BIP0340") {
var privatekey *bip0340.PrivateKey
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeBIP0340PrivateKey(file)
if err != nil {
log.Fatal(err)
}
opts := &bip0340.SignerOpts{
Hash: myHash,
}
// signature, err := privatekey.Sign(rand.Reader, h.Sum(nil), opts)
signature, err := privatekey.Sign(rand.Reader, input, opts)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "BIP0340") {
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
opts := &bip0340.SignerOpts{
Hash: myHash,
}
publica, err := DecodeBIP0340PublicKey(file)
if err != nil {
log.Fatal(err)
}
sig, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
// verifystatus, err := publica.Verify(h.Sum(nil), sig, opts)
verifystatus, err := publica.Verify(input, sig, opts)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "BIGN") {
var privatekey *bign.PrivateKey
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeBIGNPrivateKey(file)
if err != nil {
log.Fatal(err)
}
adata := bign.MakeAdata([]byte(*id), []byte(*info))
// signature, err := bign.Sign(rand.Reader, privatekey, myHash, h.Sum(nil), adata)
signature, err := bign.Sign(rand.Reader, privatekey, myHash, input, adata)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "DBIGN") {
var privatekey *bign.PrivateKey
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeBIGNPrivateKey(file)
if err != nil {
log.Fatal(err)
}
adata := bign.MakeAdata([]byte(*id), []byte(*info))
// signature, err := bign.Sign(rand.Reader, privatekey, myHash, h.Sum(nil), adata)
signature, err := bign.Sign(nil, privatekey, myHash, input, adata)
if err != nil {
log.Fatal(err)
}
fmt.Println(strings.ToUpper(*alg)+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "BIGN") {
// var h hash.Hash
// h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
// if _, err := io.Copy(h, inputfile); err != nil {
// log.Fatal(err)
// }
input, err := ioutil.ReadAll(inputfile)
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
publica, err := DecodeBIGNPublicKey(file)
if err != nil {
log.Fatal(err)
}
adata := bign.MakeAdata([]byte(*id), []byte(*info))
sig, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
// verifystatus := bign.Verify(publica, myHash, h.Sum(nil), adata, sig)
verifystatus := bign.Verify(publica, myHash, input, adata, sig)
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "SM2") {
var privatekey *sm2.PrivateKey
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeSM2PrivateKey(file)
if err != nil {
log.Fatal(err)
}
inputBytes, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
signature, err := privatekey.Sign(rand.Reader, inputBytes, sm2.DefaultSM2SignerOpts)
if err != nil {
log.Fatal(err)
}
fmt.Println("PureSM2("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "SM2") {
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
public, err = DecodePublicKey(file)
if err != nil {
log.Fatal(err)
}
inputBytes, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatal(err)
}
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
verifystatus := sm2.VerifyASN1WithSM2(public, nil, inputBytes, sigBytes)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "SM2PH") {
var privatekey *sm2.PrivateKey
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
privatekey, err = DecodeSM2PrivateKey(file)
if err != nil {
log.Fatal(err)
}
signature, err := privatekey.Sign(rand.Reader, h.Sum(nil), sm2.DefaultSM2SignerOpts)
if err != nil {
log.Fatal(err)
}
fmt.Println("SM2"+"-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "SM2PH") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
public, err = DecodePublicKey(file)
if err != nil {
log.Fatal(err)
}
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
verifystatus := sm2.VerifyASN1WithSM2(public, nil, h.Sum(nil), sigBytes)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "ED25519PH") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
edKey := privKey.(ed25519.PrivateKey)
signature := ed25519.Sign(edKey, h.Sum(nil))
fmt.Println("ED25519PH-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "ED25519PH") {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
publicInterface, err := smx509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface.(ed25519.PublicKey)
sig, _ := hex.DecodeString(*sig)
verifystatus := ed25519.Verify(publicKey, h.Sum(nil), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "sign" && (strings.ToUpper(*alg) == "ED25519") {
data := bytes.NewBuffer(nil)
if _, err := io.Copy(data, inputfile); err != nil {
log.Fatal(err)
}
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
edKey := privKey.(ed25519.PrivateKey)
signature := ed25519.Sign(edKey, data.Bytes())
fmt.Println("PureED25519("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && (strings.ToUpper(*alg) == "ED25519") {
data := bytes.NewBuffer(nil)
if _, err := io.Copy(data, inputfile); err != nil {
log.Fatal(err)
}
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
publicInterface, err := smx509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface.(ed25519.PublicKey)
sig, _ := hex.DecodeString(*sig)
verifystatus := ed25519.Verify(publicKey, data.Bytes(), sig)
if verifystatus == true {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(0)
} else {
fmt.Printf("Verified: %v\n", verifystatus)
os.Exit(1)
}
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "X25519") {
var privateKey *ecdh.PrivateKey
privateKey, err = ecdh.X25519().GenerateKey(rand.Reader)
if err != nil {
log.Fatal(err)
}
publicKey := privateKey.Public()
privateKey, err := ecdh.X25519().NewPrivateKey(privateKey.Bytes())
if err != nil {
log.Fatal(err)
}
privateStream, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "X25519 PRIVATE KEY",
Bytes: privateStream,
}
file, err := os.Create(*priv)
if err != nil {
log.Fatal(err)
}
if *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
publicStream, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
pubblock := &pem.Block{
Type: "PUBLIC KEY",
Bytes: publicStream,
}
pubfile, err := os.Create(*pub)
if err != nil {
log.Fatal(err)
}
err = pem.Encode(pubfile, pubblock)
if err != nil {
log.Fatal(err)
}
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(pubblock)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if (*pkey == "derive" && strings.ToUpper(*alg) == "X25519") || strings.ToUpper(*pkey) == "X25519" {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "X25519 PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = x509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
XKey := privKey.(*ecdh.PrivateKey)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
block, _ = pem.Decode(buf)
publicInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface.(*ecdh.PublicKey)
var secret []byte
secret, err = XKey.ECDH(publicKey)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%x\n", secret[:])
os.Exit(0)
}
if *pkey == "keygen" && (strings.ToUpper(*alg) == "X448") {
var privateKey x448.PrivateKey
publicKey, privateKey, err := x448.GenerateKey(nil)
if err != nil {
log.Fatal(err)
}
privateStream, err := x448.MarshalPrivateKey(privateKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "X448 PRIVATE KEY",
Bytes: privateStream,
}
file, err := os.Create(*priv)
if err != nil {
log.Fatal(err)
}
if *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
publicStream, err := x448.MarshalPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
pubblock := &pem.Block{
Type: "X448 PUBLIC KEY",
Bytes: publicStream,
}
pubfile, err := os.Create(*pub)
if err != nil {
log.Fatal(err)
}
err = pem.Encode(pubfile, pubblock)
if err != nil {
log.Fatal(err)
}
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(pubblock)
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if (*pkey == "derive" && strings.ToUpper(*alg) == "X448" || strings.ToUpper(*pkey) == "X448") {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "X448 PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = x448.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
XKey := privKey
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
block, _ = pem.Decode(buf)
publicInterface, err := x448.ParsePublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface
var secret []byte
secret, err = x448.X448(XKey[:56], publicKey)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%x\n", secret[:])
os.Exit(0)
}
if *pkey == "derive" && strings.ToUpper(*alg) == "BIGN" {
var privatekey *bign.PrivateKey
file, err := ioutil.ReadFile(*pub)
if err != nil {
log.Fatal(err)
}
publica, err := DecodeBIGNPublicKey(file)
if err != nil {
log.Fatal(err)
}
file2, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
privatekey, err = DecodeBIGNPrivateKey(file2)
if err != nil {
log.Fatal(err)
}
b, _ := publica.Curve.ScalarMult(publica.X, publica.Y, privatekey.D.Bytes())
fmt.Printf("%x\n", b.Bytes())
os.Exit(0)
}
// Check if *pkey is one of the specified values
if *pkey == "randomart" || *pkey == "text" || *pkey == "fingerprint" || *pkey == "certgen" || *pkey == "req" || *pkey == "x509" || *pkey == "crl" || *pkey == "sign" || *pkey == "aggregate" || *pkey == "aggregate-proof" || *pkey == "aggregate-signatures" || *pkey == "verify-aggregate" || *pkey == "aggregate-vote" || *pkey == "aggregate-vote-encrypted" || *pkey == "aggregate-vote-audit" || *pkey == "aggregate-vote-proof" || *pkey == "verify-aggregate-vote" || *pkey == "verify-aggregate-vote" || *pkey == "verify-proof" || *pkey == "blind" || *pkey == "unblind" || *pkey == "count" || *pkey == "input" || *pkey == "count-total" || *pkey == "add" || *pkey == "sum" || *pkey == "hash" || *pkey == "derive" || *pkey == "encrypt" || *pkey == "decrypt" || *pkey == "verify" || *pkey == "check" || *pkey == "validate" || *pkey == "wrapkey" || *pkey == "unwrapkey" || *tcpip == "server" || *tcpip == "client" {
if *pkey == "unblind" || *pkey == "blind" || *pkey == "hash" || *pkey == "count" || *pkey == "count-total" || *pkey == "input" || *pkey == "add" || *pkey == "sum" || *pkey == "aggregate-signatures" {
*alg = "BLS12381"
}
if strings.ToUpper(*alg) != "BN256PH" && strings.ToUpper(*alg) != "BLS12381PH" {
// Check the key
if data, err := ioutil.ReadFile(*key); err == nil {
if block, _ := pem.Decode(data); block != nil {
if strings.Contains(block.Type, "SLH-DSA") {
*alg = "SLH-DSA"
} else if strings.Contains(block.Type, "ML-KEM") {
*alg = "ML-KEM"
} else if strings.Contains(block.Type, "ML-DSA") {
*alg = "ML-DSA"
} else if strings.Contains(block.Type, "BN256I") {
*alg = "BN256I"
} else if strings.Contains(block.Type, "BN256") {
*alg = "BN256"
} else if strings.Contains(block.Type, "BLS12381I") {
*alg = "BLS12381I"
} else if strings.Contains(block.Type, "BLS12381") {
*alg = "BLS12381"
}
}
}
// Check the CRL
if data, err := ioutil.ReadFile(*crl); err == nil {
if block, _ := pem.Decode(data); block != nil {
if strings.Contains(block.Type, "SLH-DSA") {
*alg = "SLH-DSA"
} else if strings.Contains(block.Type, "ML-DSA") {
*alg = "ML-DSA"
} else if strings.Contains(block.Type, "BN256I") {
*alg = "BN256I"
} else if strings.Contains(block.Type, "BN256") {
*alg = "BN256"
} else if strings.Contains(block.Type, "BLS12381I") {
*alg = "BLS12381I"
} else if strings.Contains(block.Type, "BLS12381") {
*alg = "BLS12381"
}
}
}
if *pkey != "certgen" && *pkey != "req" {
// Check the Cert
if data, err := ioutil.ReadFile(*cert); err == nil {
if block, _ := pem.Decode(data); block != nil {
if strings.Contains(block.Type, "SLH-DSA") {
*alg = "SLH-DSA"
} else if strings.Contains(block.Type, "ML-DSA") {
*alg = "ML-DSA"
} else if strings.Contains(block.Type, "BN256I") {
*alg = "BN256I"
} else if strings.Contains(block.Type, "BN256") {
*alg = "BN256"
} else if strings.Contains(block.Type, "BLS12381I") {
*alg = "BLS12381I"
} else if strings.Contains(block.Type, "BLS12381") {
*alg = "BLS12381"
}
}
}
}
}
}
if *pkey == "derive" && strings.ToUpper(*alg) != "GOST2012" && strings.ToUpper(*alg) != "BN256" && strings.ToUpper(*alg) != "BN256I" && strings.ToUpper(*alg) != "BLS12381" && strings.ToUpper(*alg) != "BLS12381I" {
var privatekey *ecdsa.PrivateKey
file, err := ioutil.ReadFile(*pub)
if err != nil {
log.Fatal(err)
}
public, err = DecodePublicKey(file)
if err != nil {
log.Fatal(err)
}
file2, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
os.Exit(1)
}
privatekey, err = DecodePrivateKey(file2)
if err != nil {
log.Fatal(err)
}
b, _ := public.Curve.ScalarMult(public.X, public.Y, privatekey.D.Bytes())
fmt.Printf("%x\n", b.Bytes())
os.Exit(0)
}
if *pkey == "keygen" && strings.ToUpper(*alg) == "GOST2012" {
var gost341012PrivRaw []byte
var curve *gost3410.Curve
if *length == 256 && (*paramset == "A" || *paramset == "B" || *paramset == "C" || *paramset == "D") {
if strings.ToUpper(*paramset) == "A" {
curve = gost3410.CurveIdtc26gost341012256paramSetA()
} else if *length == 256 && strings.ToUpper(*paramset) == "B" {
curve = gost3410.CurveIdtc26gost341012256paramSetB()
} else if *length == 256 && strings.ToUpper(*paramset) == "C" {
curve = gost3410.CurveIdtc26gost341012256paramSetC()
} else if *length == 256 && strings.ToUpper(*paramset) == "D" {
curve = gost3410.CurveIdtc26gost341012256paramSetD()
}
gost341012PrivRaw = make([]byte, 32)
} else if *length == 512 && (*paramset == "A" || *paramset == "B" || *paramset == "C") {
if strings.ToUpper(*paramset) == "A" {
curve = gost3410.CurveIdtc26gost341012512paramSetA()
} else if strings.ToUpper(*paramset) == "B" {
curve = gost3410.CurveIdtc26gost341012512paramSetB()
} else if strings.ToUpper(*paramset) == "C" {
curve = gost3410.CurveIdtc26gost341012512paramSetC()
}
gost341012PrivRaw = make([]byte, 64)
}
if _, err = io.ReadFull(rand.Reader, gost341012PrivRaw); err != nil {
log.Fatalf("Failed to read random for GOST private key: %s", err)
}
gost341012256Priv, err := gost3410.NewPrivateKey(
curve,
gost341012PrivRaw,
)
if err != nil {
log.Fatalf("Failed to create GOST private key: %s", err)
}
gost341012256Pub := gost341012256Priv.Public()
privateStream, err := x509.MarshalPKCS8PrivateKey(gost341012256Priv)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "GOST PRIVATE KEY",
Bytes: privateStream,
}
file, err := os.Create(*priv)
if err != nil {
log.Fatal(err)
}
if *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
log.Fatal(err)
}
}
publicStream, err := x509.MarshalPKIXPublicKey(gost341012256Pub)
if err != nil {
log.Fatal(err)
}
pubblock := &pem.Block{
Type: "PUBLIC KEY",
Bytes: publicStream,
}
pubfile, err := os.Create(*pub)
if err != nil {
log.Fatal(err)
}
err = pem.Encode(pubfile, pubblock)
if err != nil {
log.Fatal(err)
}
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprintGOST(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(pubblock)
randomArt := randomart.FromString(string(buf))
println(randomArt)
}
if (*pkey == "derive" && strings.ToUpper(*alg) == "GOST2012") || strings.ToUpper(*pkey) == "VKO" {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Println(err)
}
info, err := file.Stat()
if err != nil {
log.Println(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = x509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Println(err)
}
privateKey := privKey.(*gost3410.PrivateKey)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
block, _ = pem.Decode(buf)
publicInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface.(*gost3410.PublicKey)
var shared []byte
if *length == 512 {
shared, err = privateKey.KEK2012512(publicKey, big.NewInt(1))
} else {
shared, err = privateKey.KEK2012256(publicKey, big.NewInt(1))
}
if err != nil {
log.Fatal(err)
}
fmt.Println(hex.EncodeToString(shared))
}
if *pkey == "sign" && strings.ToUpper(*alg) == "GOST2012" {
var privPEM []byte
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := os.Open(*key)
if err != nil {
log.Println(err)
}
info, err := file.Stat()
if err != nil {
log.Println(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = x509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Println(err)
}
gostKey := privKey.(*gost3410.PrivateKey)
signature, err := gostKey.Sign(rand.Reader, h.Sum(nil), nil)
if err != nil {
log.Fatal(err)
}
// fmt.Println("(stdin)=", hex.EncodeToString(signature))
fmt.Println("GOST2012-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
}
if *pkey == "verify" && strings.ToUpper(*alg) == "GOST2012" {
var h hash.Hash
h = myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(h, inputfile); err != nil {
log.Fatal(err)
}
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
publicInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface.(*gost3410.PublicKey)
inputsig, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
isValid, err := publicKey.VerifyDigest(h.Sum(nil), inputsig)
if err != nil {
log.Fatal(err)
}
if !isValid {
fmt.Println("Verified: false")
os.Exit(1)
}
fmt.Println("Verified: true")
os.Exit(0)
}
var PEM string
var b []byte
if (*pkey == "text" || *pkey == "modulus" || *pkey == "check" || *pkey == "randomart" || *pkey == "fingerprint" || *pkey == "info") && *crl == "" && *params == "" {
if *key != "" {
b, err = ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
} else if *key == "" {
b, err = ioutil.ReadFile(*cert)
if err != nil {
log.Fatal(err)
}
}
s := string(b)
if strings.Contains(s, "PRIVATE") {
PEM = "Private"
} else if strings.Contains(s, "MASTER") {
PEM = "Master"
} else if strings.Contains(s, "PUBLIC") {
PEM = "Public"
} else if strings.Contains(s, "CERTIFICATE REQUEST") {
PEM = "CertificateRequest"
} else if strings.Contains(s, "CERTIFICATE") {
PEM = "Certificate"
}
if strings.Contains(s, "RSA PRIVATE") {
*alg = "RSA"
} else if strings.Contains(s, "EC PRIVATE") {
*alg = "EC"
} else if strings.Contains(s, "GOST PRIVATE") {
*alg = "GOST2012"
} else if strings.Contains(s, "X25519 PRIVATE") {
*alg = "X25519"
} else if strings.Contains(s, "SM9 ENC") {
*alg = "SM9ENCRYPT"
} else if strings.Contains(s, "SM9 SIGN") {
*alg = "SM9SIGN"
} else if strings.Contains(s, "SLH-DSA") {
*alg = "SLH-DSA"
} else if strings.Contains(s, "BN256I") {
*alg = "BN256I"
} else if strings.Contains(s, "BN256") {
*alg = "BN256"
} else if strings.Contains(s, "BLS12381I") {
*alg = "BLS12381I"
} else if strings.Contains(s, "BLS12381") {
*alg = "BLS12381"
} else if strings.Contains(s, "EC-ELGAMAL") {
*alg = "EC-ELGAMAL"
} else if strings.Contains(s, "ELGAMAL") {
*alg = "ELGAMAL"
} else if strings.Contains(s, "ML-KEM") {
*alg = "ML-KEM"
} else if strings.Contains(s, "ML-DSA") {
*alg = "ML-DSA"
} else if strings.Contains(s, "NUMS") {
*alg = "NUMS"
} else if strings.Contains(s, "ANSSI") {
*alg = "ANSSI"
} else if strings.Contains(s, "KOBLITZ") {
*alg = "KOBLITZ"
} else if strings.Contains(s, "TOM") {
*alg = "TOM"
} else if strings.Contains(s, "BIGN") {
*alg = "BIGN"
} else if strings.Contains(s, "ECKCDSA PRIVATE") {
*alg = "ECKCDSA"
} else if strings.Contains(s, "ECGDSA PRIVATE") {
*alg = "ECGDSA"
} else if strings.Contains(s, "ECSDSA PRIVATE") {
*alg = "ECSDSA"
} else if strings.Contains(s, "BIP0340 PRIVATE") {
*alg = "BIP0340"
} else if strings.Contains(s, "ED448 PRIVATE") {
*alg = "ED448"
} else if strings.Contains(s, "X448 PRIVATE") {
*alg = "X448"
} else if strings.Contains(s, "PRIVATE") {
*alg = "ED25519"
}
}
if strings.ToUpper(*alg) == "SLH-DSA" && *pkey == "keygen" {
generateKeyPair(*priv, *pub)
}
if strings.ToUpper(*alg) == "SLH-DSA" && *pkey == "sign" {
signMessage(inputfile, *key)
}
if strings.ToUpper(*alg) == "SLH-DSA" && *pkey == "verify" {
verifySignature(inputfile, *key, *sig)
}
if *pkey == "modulus" && strings.ToUpper(*alg) == "SLH-DSA" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
defer file.Close()
pemData, err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pemData)
if block == nil {
log.Fatal("failed to parse PEM block containing the key")
}
isPrivateKey := block.Type == "SLH-DSA SECRET KEY"
// loadedKeyBytes, err := loadPEMKey(*key, *pwd)
loadedKeyBytes, err := readKeyFromPEM(*key, isPrivateKey)
if err != nil {
log.Fatal(err)
}
if err := printKeyParams(loadedKeyBytes, isPrivateKey); err != nil {
log.Fatal(err)
}
}
if *pkey == "text" && strings.ToUpper(*alg) == "SLH-DSA" && *key != "" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
defer file.Close()
pemData, err := ioutil.ReadAll(file)
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(pemData)
if block == nil {
log.Fatal("failed to parse PEM block containing the key")
}
isPrivateKey := block.Type == "SLH-DSA SECRET KEY"
// loadedKeyBytes, err := loadPEMKey(*key, *pwd)
loadedKeyBytes, err := readKeyFromPEM(*key, isPrivateKey)
if err != nil {
log.Fatal(err)
}
if err := printKeyParamsFull(loadedKeyBytes, isPrivateKey); err != nil {
log.Fatal(err)
}
}
if *pkey == "randomart" && strings.ToUpper(*alg) == "SLH-DSA" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
println("SLH-DSA (256-bit)")
randomArt := randomart.FromString(string(buf))
println(randomArt)
os.Exit(0)
}
if *pkey == "fingerprint" && strings.ToUpper(*alg) == "SLH-DSA" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint= ")
println(fingerprint)
os.Exit(0)
}
var validity string
if (strings.ToUpper(*alg) == "ML-DSA" || strings.ToUpper(*alg) == "SLH-DSA" || strings.ToUpper(*alg) == "BN256I" || strings.ToUpper(*alg) == "BLS12381I") && (*pkey == "certgen" || *pkey == "req" || *pkey == "x509" || *pkey == "crl") {
if *pkey == "certgen" || *pkey == "req" {
if *subj == "" {
println("You are about to be asked to enter information \nthat will be incorporated into your certificate.")
scanner := bufio.NewScanner(os.Stdin)
print("Common Name: ")
scanner.Scan()
name = scanner.Text()
print("Country Name (2 letter code) [AU]: ")
scanner.Scan()
country = scanner.Text()
print("State or Province Name (full name) [Some-State]: ")
scanner.Scan()
province = scanner.Text()
print("Locality Name (eg, city): ")
scanner.Scan()
locality = scanner.Text()
print("Organization Name (eg, company) [Internet Widgits Pty Ltd]: ")
scanner.Scan()
organization = scanner.Text()
print("Organizational Unit Name (eg, section): ")
scanner.Scan()
organizationunit = scanner.Text()
print("Email Address []: ")
scanner.Scan()
email = scanner.Text()
print("StreetAddress: ")
scanner.Scan()
street = scanner.Text()
print("PostalCode: ")
scanner.Scan()
postalcode = scanner.Text()
print("SerialNumber: ")
scanner.Scan()
number = scanner.Text()
} else {
name, number, country, province, locality, organization, organizationunit, street, email, postalcode, err = parseSubjectString(*subj)
if err != nil {
log.Fatal(err)
}
}
}
if *pkey == "certgen" || *pkey == "x509" || *pkey == "crl" {
// Check if the 'days' flag was provided
if *days > 0 {
// If provided, use the value from the flag
validity = fmt.Sprintf("%d", *days)
} else {
// Otherwise, prompt the user for input
fmt.Print("Validity (in Days): ")
fmt.Scanln(&validity)
}
}
}
if (*pkey == "certgen" || *pkey == "x509" || *pkey == "req" || *pkey == "check" || *pkey == "text" || *pkey == "crl" || *pkey == "validate") && strings.ToUpper(*alg) == "SLH-DSA" {
if *pkey == "certgen" {
// Load public key
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
ca := NewCA(sk, pk, validity)
// subject := pkix.Name{CommonName: *subj}
subject := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
certificate, err := ca.IssueCertificate(subject, email, pk, sk, true, validity)
if err != nil {
fmt.Println("Error issuing certificate:", err)
return
}
err = SaveCertificateToPEM(certificate, *cert)
if err != nil {
fmt.Println("Error saving certificate:", err)
return
}
fmt.Println("Certificate issued and saved successfully.")
os.Exit(0)
} else if *pkey == "text" && *key == "" && *crl != "" {
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
log.Fatalf("Erro ao ler o CRL: %v", err)
}
PrintCRLInfo(crl)
os.Exit(0)
}
if *pkey == "fingerprint" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fingerprint := calculateFingerprint(keyBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && *key != "" {
pubFile, err := os.Open(*key)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
fmt.Printf("SLH-DSA 256-bit\n")
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
} else if *pkey == "check" && *crl == "" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Erro ao ler o certificado:", err)
return
}
err = VerifyCertificate(certificate, pk)
if err != nil {
fmt.Println("Verified: false", err)
os.Exit(1)
} else {
fmt.Println("Verified: true")
os.Exit(0)
}
} else if *pkey == "text" && *cert != "" {
// Load certificate
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
// Try loading as CSR
csr, err := ReadCSRFromPEM(*cert)
if err != nil {
fmt.Println("Error loading certificate or CSR:", err)
return
}
// Print CSR info
PrintInfo(csr)
} else {
// Print certificate info
PrintInfo(certificate)
}
os.Exit(0)
} else if *pkey == "req" {
caPrivateKey, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
// Create a new CSR
// subject := pkix.Name{CommonName: *subj}
subject := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
publicKey, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
csr, err := CreateCSR(subject, email, publicKey, caPrivateKey)
if err != nil {
log.Fatalf("Failed to create CSR: %v", err)
}
// Save CSR to PEM
err = SaveCSRToPEM(csr, *cert)
if err != nil {
log.Fatalf("Failed to save CSR: %v", err)
}
fmt.Println("CSR created and saved to", *cert)
os.Exit(0)
} else if *pkey == "x509" {
caPrivateKey, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
caCert, err := ReadCertificateFromPEM(*root)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Read CSR from PEM
csr, err := ReadCSRFromPEM(*cert)
if err != nil {
log.Fatalf("Failed to read CSR: %v", err)
}
// Create CA instance
ca := &CA{
PrivateKey: caPrivateKey,
Certificate: *caCert,
}
// Sign the CSR with the CA's private key
signedCert, err := SignCSR(csr, ca, caPrivateKey, validity)
if err != nil {
log.Fatalf("Failed to sign CSR: %v", err)
}
var outputFilename string
if flag.Arg(0) == "" {
outputFilename = "stdout"
} else {
outputFilename = flag.Arg(0)
}
// Save signed certificate to PEM
err = SaveCertificateToPEM(signedCert, outputFilename)
if err != nil {
log.Fatalf("Failed to save certificate: %v", err)
}
fmt.Fprintf(os.Stderr, "Certificate signed and saved to %s\n", outputFilename)
os.Exit(0)
} else if *pkey == "crl" {
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading public key:", err)
return
}
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading private key:", err)
return
}
cert, err := ReadCertificateFromPEM(*cert)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Create CA
ca := NewCA(sk, pk, validity)
// Create a CRL
crl, err := NewCRL(ca, *crl, validity)
if err != nil {
fmt.Println("Error generating CRL:", err)
return
}
// Read revoked serial numbers from the text file
revokedSerials, err := readRevokedSerials(flag.Arg(0))
if err != nil {
fmt.Printf("Error reading revoked serial numbers: %v\n", err)
return
}
// Revoke each serial number from the list
for _, serial := range revokedSerials {
crl.RevokeCertificate(serial)
}
// Sign the CRL
if err := crl.Sign(ca, cert); err != nil {
fmt.Printf("Error signing CRL: %v\n", err)
return
}
// Save the CRL to a specified output file or standard output
var outputFile string
if len(flag.Args()) > 0 {
outputFile = flag.Arg(1)
}
if err := SaveCRLToPEM(crl, outputFile); err != nil {
fmt.Printf("Error saving CRL: %v\n", err)
return
}
fmt.Println("CRL generated and saved successfully.")
os.Exit(0)
} else if *pkey == "validate" {
// Load the certificate to validate
certToValidate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Printf("Error reading certificate: %v\n", err)
return
}
readCRL, err := ReadCRLFromPEM(*crl)
if err != nil {
fmt.Printf("Error reading CRL: %v\n", err)
return
}
// Check if the certificate was revoked
if readCRL.IsRevoked(certToValidate.SerialNumber) {
fmt.Println("The certificate has been revoked")
os.Exit(1)
} else {
fmt.Println("The certificate is not revoked")
os.Exit(0)
}
} else if *pkey == "check" && *crl != "" {
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Error reading certificate:", err)
return
}
// Load the CRL
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
fmt.Printf("Error reading CRL: %v\n", err)
os.Exit(1)
}
// Verify the CRL against the CA's public key
if err := CheckCRL(crl, certificate.PublicKey); err != nil {
fmt.Println("Verified: false", err)
// fmt.Printf("%v\n", err)
os.Exit(3)
}
fmt.Println("Verified: true")
os.Exit(0)
}
}
if (strings.ToUpper(*alg) == "ELGAMALPHP" || strings.ToUpper(*alg) == "EGPHP") && (*pkey == "keygen" || *pkey == "setup" || *pkey == "wrapkey" || *pkey == "unwrapkey" || *pkey == "sign" || *pkey == "verify") {
// Key generation mode
if *pkey == "keygen" {
if *priv == "" || *pub == "" {
log.Fatal("You must specify -prv and -pub to save the keys")
}
prv, pubkey, err := elgamalphp.GenerateKeys()
if err != nil {
log.Fatalf("Error generating keys: %v", err)
}
// Save private key in PEM format
privASN1 := PrivateKeyASN1{P: prv.P, G: prv.G, X: prv.X}
privDER, err := asn1.Marshal(privASN1)
if err != nil {
log.Fatalf("Error encoding private key: %v", err)
}
err = savePEM(*priv, "ELGAMAL PRIVATE KEY", privDER)
if err != nil {
log.Fatalf("Error saving private key: %v", err)
}
// Save public key in PEM format
pubASN1 := PublicKeyASN1{P: pubkey.P, G: pubkey.G, Y: pubkey.Y}
pubDER, err := asn1.Marshal(pubASN1)
if err != nil {
log.Fatalf("Error encoding public key: %v", err)
}
err = savePEM(*pub, "ELGAMAL PUBLIC KEY", pubDER)
if err != nil {
log.Fatalf("Error saving public key: %v", err)
}
// Output paths of saved keys
privPath, err := filepath.Abs(*priv)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
os.Exit(1)
}
fmt.Printf("Private Key saved to: %s\n", privPath)
pubPath, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key:", err)
os.Exit(1)
}
fmt.Printf("Public Key saved to: %s\n", pubPath)
fingerprint := calculateFingerprint(pubkey.Y.Bytes())
fmt.Println("Fingerprint=", fingerprint)
primeBitLength := pubkey.P.BitLen()
fmt.Fprintf(os.Stderr, "ElGamal (%d-bits)\n", primeBitLength)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
randomArt := randomart.FromString(string(buf))
fmt.Println(randomArt)
return
}
// Verify operation mode
if *key == "" {
log.Fatal("You must specify a key file with -key")
}
stdinBytes, err := io.ReadAll(inputfile)
if err != nil {
log.Fatalf("Error reading stdin: %v", err)
}
switch {
case *pkey == "unwrapkey":
// Decryption mode - load private key from PEM
privDER, err := readPEM(*key)
if err != nil {
log.Fatalf("Error reading private key: %v", err)
}
var privASN1 PrivateKeyASN1
_, err = asn1.Unmarshal(privDER, &privASN1)
if err != nil {
log.Fatalf("Error decoding private key: %v", err)
}
priv := &elgamalphp.PrivateKey{P: privASN1.P, G: privASN1.G, X: privASN1.X}
hexStr := strings.ReplaceAll(strings.TrimSpace(string(stdinBytes)), "\n", "")
encData, err := hex.DecodeString(hexStr)
if err != nil {
log.Fatalf("Error decoding signature: %v", err)
}
// Decode ciphertext from ASN.1 DER
var cipher CiphertextPHP
_, err = asn1.Unmarshal(encData, &cipher)
if err != nil {
log.Fatalf("Error decoding ciphertext: %v", err)
}
msg, err := elgamalphp.Decrypt(priv, cipher.C1, cipher.C2)
if err != nil {
log.Fatalf("Error decrypting: %v", err)
}
os.Stdout.Write(msg)
case *pkey == "sign":
// Signature mode - load private key from PEM
privDER, err := readPEM(*key)
if err != nil {
log.Fatalf("Error reading private key: %v", err)
}
var privASN1 PrivateKeyASN1
_, err = asn1.Unmarshal(privDER, &privASN1)
if err != nil {
log.Fatalf("Error decoding private key: %v", err)
}
priv := &elgamalphp.PrivateKey{P: privASN1.P, G: privASN1.G, X: privASN1.X}
hash := hashMessage(stdinBytes)
r, s, err := elgamalphp.Sign(priv, hash)
if err != nil {
log.Fatalf("Error signing: %v", err)
}
// Encode signature in ASN.1 DER format
signature := Signature{R: r, S: s}
sigDER, err := asn1.Marshal(signature)
if err != nil {
log.Fatalf("Error encoding signature: %v", err)
}
fmt.Println(hex.EncodeToString(sigDER))
case *pkey == "verify":
// Verification mode - load public key from PEM
pubDER, err := readPEM(*key)
if err != nil {
log.Fatalf("Error reading public key: %v", err)
}
var pubASN1 PublicKeyASN1
_, err = asn1.Unmarshal(pubDER, &pubASN1)
if err != nil {
log.Fatalf("Error decoding public key: %v", err)
}
pub := &elgamalphp.PublicKey{P: pubASN1.P, G: pubASN1.G, Y: pubASN1.Y}
signData, err := hex.DecodeString(*sig)
if err != nil {
log.Fatalf("Error decoding signature: %v", err)
}
var signature Signature
_, err = asn1.Unmarshal(signData, &signature)
if err != nil {
log.Fatalf("Error decoding signature: %v", err)
}
hash := hashMessage(stdinBytes)
valid, err := elgamalphp.Verify(pub, hash, signature.R, signature.S)
if err != nil {
log.Fatalf("Verification error: %v", err)
}
if valid {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
default:
// Default encryption mode - load public key from PEM
pubDER, err := readPEM(*key)
if err != nil {
log.Fatalf("Error reading public key: %v", err)
}
var pubASN1 PublicKeyASN1
_, err = asn1.Unmarshal(pubDER, &pubASN1)
if err != nil {
log.Fatalf("Error decoding public key: %v", err)
}
pub := &elgamalphp.PublicKey{P: pubASN1.P, G: pubASN1.G, Y: pubASN1.Y}
c1, c2, err := elgamalphp.Encrypt(pub, stdinBytes)
if err != nil {
log.Fatalf("Error encrypting: %v", err)
}
// Encode ciphertext in ASN.1 DER format
cipher := CiphertextPHP{C1: c1, C2: c2}
cipherDER, err := asn1.Marshal(cipher)
if err != nil {
log.Fatalf("Error encoding ciphertext: %v", err)
}
fmt.Println(hex.EncodeToString(cipherDER))
}
}
if (strings.ToUpper(*alg) == "ELGAMAL" || strings.ToUpper(*alg) == "EG" && strings.ToUpper(*alg) != "EC-ELGAMAL" || *params != "") && (*pkey == "keygen" || *pkey == "setup" || *pkey == "wrapkey" || *pkey == "unwrapkey" || *pkey == "text" || *pkey == "modulus" || *pkey == "sign" || *pkey == "verify") {
if *pkey == "setup" {
setParams, err := generateElGamalParams()
if err != nil {
log.Fatal(err)
}
err = saveElGamalParamsToPEM(*params, setParams)
if err != nil {
log.Fatal("Error saving ElGamal parameters to PEM file:", err)
return
}
os.Exit(0)
}
var blockType string
if *key != "" {
pemData, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Error decoding PEM block")
os.Exit(1)
}
blockType = block.Type
}
if *pkey == "text" && *key != "" && blockType == "ELGAMAL PRIVATE KEY" {
// Primeiro lê os dados PEM brutos
data, err := os.ReadFile(*key)
if err != nil {
fmt.Println("Error reading private key file:", err)
return
}
// Decodifica o bloco PEM
block, _ := pem.Decode(data)
if block == nil {
fmt.Println("Failed to decode PEM block")
return
}
// Tenta decodificar primeiro como PrivateKeyASN1
var privASN1 PrivateKeyASN1
if _, err := asn1.Unmarshal(block.Bytes, &privASN1); err == nil {
// Se decodificou com sucesso como ASN1, converte para PrivateKey
priv := &PrivateKey{
PublicKey: PublicKey{
P: privASN1.P,
G: privASN1.G,
Y: new(big.Int).Exp(privASN1.G, privASN1.X, privASN1.P),
},
X: privASN1.X,
}
publicKey := new(big.Int).Exp(privASN1.G, privASN1.X, privASN1.P)
// Exibe o conteúdo PEM original
fmt.Print(string(data))
xval := new(big.Int).Set(priv.X)
fmt.Println("PrivateKey(x):")
x := fmt.Sprintf("%x", xval)
splitz := SplitSubN(x, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Prime(p):")
p := fmt.Sprintf("%x", priv.P)
splitz = SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Generator(g in the range [2, p-2]):")
g := fmt.Sprintf("%x", priv.G)
splitz = SplitSubN(g, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("PublicKey(Y = g^x mod p):")
pub := fmt.Sprintf("%x", publicKey)
splitz = SplitSubN(pub, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
os.Exit(0)
}
// Se não conseguiu decodificar como ASN1, tenta como PrivateKey original
priv, err := readPrivateKeyFromPEM(*key)
if err != nil {
fmt.Println("Error reading private key:", err)
return
}
privPEM := &PrivateKey{
PublicKey: PublicKey{
G: priv.G,
P: priv.P,
Y: priv.Y,
},
X: priv.X,
}
privBytes, err := encodePrivateKeyPEM(privPEM)
if err != nil {
log.Fatal(err)
}
pemBlock := &pem.Block{
Type: "ELGAMAL PRIVATE KEY",
Bytes: privBytes,
}
publicKey := setup(priv.X, priv.G, priv.P)
pemData := pem.EncodeToMemory(pemBlock)
fmt.Print(string(pemData))
xval := new(big.Int).Set(priv.X)
fmt.Println("PrivateKey(x):")
x := fmt.Sprintf("%x", xval)
splitz := SplitSubN(x, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Prime(p):")
p := fmt.Sprintf("%x", priv.P)
splitz = SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Generator(g in the range [2, p-2]):")
g := fmt.Sprintf("%x", priv.G)
splitz = SplitSubN(g, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("PublicKey(Y = g^x mod p):")
pub := fmt.Sprintf("%x", publicKey)
splitz = SplitSubN(pub, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
os.Exit(0)
}
if *pkey == "text" && *key != "" && blockType == "ELGAMAL PUBLIC KEY" {
// Primeiro lê os dados PEM brutos
pemData, err := os.ReadFile(*key)
if err != nil {
fmt.Println("Error reading public key file:", err)
os.Exit(1)
}
// Decodifica o bloco PEM
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Failed to decode PEM block")
os.Exit(1)
}
// Tenta decodificar primeiro como PublicKeyASN1
var pubASN1 PublicKeyASN1
if _, err := asn1.Unmarshal(block.Bytes, &pubASN1); err == nil {
// Se decodificou com sucesso como ASN1, converte para PublicKey
publicKeyVal := &PublicKey{
P: pubASN1.P,
G: pubASN1.G,
Y: pubASN1.Y,
}
// Exibe o conteúdo PEM original
fmt.Print(string(pemData))
fmt.Println("Public Key Parameters:")
fmt.Println("Prime(p):")
p := fmt.Sprintf("%x", publicKeyVal.P)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Generator(g):")
g := fmt.Sprintf("%x", publicKeyVal.G)
splitz = SplitSubN(g, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("PublicKey(Y):")
y := fmt.Sprintf("%x", publicKeyVal.Y)
splitz = SplitSubN(y, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
return
}
// Se não conseguiu decodificar como ASN1, tenta como PublicKey original
publicKeyVal, err := readPublicKeyFromPEM(*key)
if err != nil {
fmt.Println("Error: Invalid public key value")
os.Exit(1)
}
// Exibe o conteúdo PEM original
fmt.Print(string(pemData))
fmt.Println("Public Key Parameters:")
fmt.Println("Prime(p):")
p := fmt.Sprintf("%x", publicKeyVal.P)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Generator(g):")
g := fmt.Sprintf("%x", publicKeyVal.G)
splitz = SplitSubN(g, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("PublicKey(Y):")
y := fmt.Sprintf("%x", publicKeyVal.Y)
splitz = SplitSubN(y, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
return
}
if *pkey == "modulus" && blockType == "ELGAMAL PRIVATE KEY" {
// Primeiro tenta ler como ASN1
data, err := os.ReadFile(*key)
if err != nil {
fmt.Println("Error reading private key file:", err)
os.Exit(1)
}
block, _ := pem.Decode(data)
if block == nil {
fmt.Println("Failed to decode PEM block")
os.Exit(1)
}
var privASN1 PrivateKeyASN1
if _, err := asn1.Unmarshal(block.Bytes, &privASN1); err == nil {
// Formato ASN1 - calcula Y = g^x mod p
y := new(big.Int).Exp(privASN1.G, privASN1.X, privASN1.P)
fmt.Printf("Y=%X\n", y)
return
}
// Se não for ASN1, tenta o formato antigo
privKey, err := readPrivateKeyFromPEM(*key)
if err != nil {
fmt.Println("Error reading private key:", err)
os.Exit(1)
}
publicKey := setup(privKey.X, privKey.G, privKey.P)
fmt.Printf("Y=%X\n", publicKey)
return
}
if *pkey == "modulus" && blockType == "ELGAMAL PUBLIC KEY" {
// Primeiro tenta ler como ASN1
data, err := os.ReadFile(*key)
if err != nil {
fmt.Println("Error reading public key file:", err)
os.Exit(1)
}
block, _ := pem.Decode(data)
if block == nil {
fmt.Println("Failed to decode PEM block")
os.Exit(1)
}
var pubASN1 PublicKeyASN1
if _, err := asn1.Unmarshal(block.Bytes, &pubASN1); err == nil {
// Formato ASN1 - pega Y diretamente
fmt.Printf("Y=%X\n", pubASN1.Y)
return
}
// Se não for ASN1, tenta o formato antigo
publicKey, err := readPublicKeyFromPEM(*key)
if err != nil {
fmt.Println("Error reading public key:", err)
os.Exit(1)
}
fmt.Printf("Y=%X\n", publicKey.Y)
return
}
if *pkey == "wrapkey" {
publicKeyVal, err := readPublicKeyFromPEM(*key)
if err != nil {
fmt.Println("Error: Invalid public key value")
os.Exit(1)
}
// Assuming readParams is of type ElGamalParams
pub := &PublicKey{
G: publicKeyVal.G,
P: publicKeyVal.P,
Y: publicKeyVal.Y,
}
messageBytes := make([]byte, *length/8)
_, err = rand.Read(messageBytes)
if err != nil {
fmt.Println("Error generating random key:", err)
os.Exit(1)
}
c, err := EncryptASN1(rand.Reader, pub, messageBytes)
if err != nil {
fmt.Println("Error encrypting message:", err)
os.Exit(1)
}
fmt.Printf("Cipher= %x\n", c)
fmt.Printf("Shared= %x\n", messageBytes)
os.Exit(0)
}
if *pkey == "unwrapkey" {
if *key == "" {
fmt.Println("Error: Private key file not provided for unwrapping.")
os.Exit(1)
}
priv, err := readPrivateKeyFromPEM(*key)
if err != nil {
fmt.Println("Error reading private key:", err)
os.Exit(1)
}
ciphertext, err := hex.DecodeString(*cph)
if err != nil {
fmt.Println("Erro ao decodificar a cifra hexadecimal:", err)
return
}
message, err := DecryptASN1(priv, ciphertext)
if err != nil {
fmt.Println("Error decrypting message:", err)
os.Exit(1)
}
fmt.Printf("Shared= %x\n", message)
}
if *pkey == "text" {
readParams, err := readElGamalParamsFromPEM(*params)
if err != nil {
fmt.Println("Error reading ElGamal parameters from PEM file:", err)
os.Exit(1)
}
pemData, err := ioutil.ReadFile(*params)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
fmt.Print(string(pemData))
fmt.Println("ElGamal Parameters:")
fmt.Println("Prime(p):")
p := fmt.Sprintf("%x", readParams.P)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Generator(g):")
g := fmt.Sprintf("%x", readParams.G)
splitz = SplitSubN(g, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
os.Exit(0)
}
if *pkey == "keygen" {
var xval *big.Int
var path string
readParams, err := readElGamalParamsFromPEM(*params)
if err != nil {
log.Fatal("Error reading ElGamal parameters from PEM file:", err)
os.Exit(1)
}
if *key == "" {
xval, err = generateRandomX(readParams.P)
if err != nil {
log.Fatal("Error generating x:", err)
os.Exit(1)
}
path, err = filepath.Abs(*priv)
if err != nil {
log.Fatal(err)
}
y := setup(xval, readParams.G, readParams.P)
privateKey := &PrivateKey{
PublicKey: PublicKey{
G: readParams.G,
P: readParams.P,
Y: y,
},
X: xval,
}
if err := savePrivateKeyToPEM(*priv, privateKey); err != nil {
log.Fatal("Error saving private key:", err)
os.Exit(1)
}
fmt.Fprintf(os.Stderr, "Private Key saved to: %s\n", path)
} else {
priva, err := readPrivateKeyFromPEM(*key)
if err != nil {
log.Fatal("Error reading private key:", err)
os.Exit(1)
}
xval = new(big.Int).Set(priva.X)
path, err = filepath.Abs(*priv)
if err != nil {
log.Fatal(err)
}
y := setup(xval, readParams.G, readParams.P)
privateKey := &PrivateKey{
PublicKey: PublicKey{
G: readParams.G,
P: readParams.P,
Y: y,
},
X: xval,
}
if err := savePrivateKeyToPEM(*priv, privateKey); err != nil {
log.Fatal("Error saving private key:", err)
os.Exit(1)
}
fmt.Fprintf(os.Stderr, "Private Key saved to: %s\n", path)
}
publicKey := setup(xval, readParams.G, readParams.P)
path, err = filepath.Abs(*pub)
if err != nil {
log.Fatal(err)
}
fmt.Fprintf(os.Stderr, "Public Key saved to: %s\n", path)
if err := savePublicKeyToPEM(*pub, &PublicKey{Y: publicKey, G: readParams.G, P: readParams.P}); err != nil {
log.Fatal("Error saving public key:", err)
os.Exit(1)
}
// Fingerprint calculation and printing
fingerprint := calculateFingerprint(publicKey.Bytes())
fmt.Fprintf(os.Stderr, "Fingerprint: %s\n", fingerprint)
// Randomart calculation and printing
primeBitLength := readParams.P.BitLen()
fmt.Fprintf(os.Stderr, "ElGamal (%d-bits)\n", primeBitLength)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
randomArt := randomart.FromString(string(buf))
fmt.Fprintln(os.Stderr, randomArt)
return
}
if *pkey == "sign" {
priv, err := readPrivateKeyFromPEM(*key)
if err != nil {
fmt.Println("Error reading private key:", err)
os.Exit(1)
}
hash := myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(hash, inputfile); err != nil {
log.Fatal(err)
}
if err != nil {
fmt.Println("Error hashing message:", err)
os.Exit(1)
}
hashBytes := hash.Sum(nil)
sign, err := SignASN1(rand.Reader, priv, hashBytes)
if err != nil {
log.Fatal("Error signing message:", err)
os.Exit(1)
}
fmt.Printf("EG-%s(%s)= %x\n", strings.ToUpper(*md), inputdesc, sign)
}
if *pkey == "verify" {
if *key == "" {
fmt.Println("Error: Public key file not provided for verification.")
os.Exit(3)
}
publicKeyVal, err := readPublicKeyFromPEM(*key)
if err != nil {
fmt.Println("Error: Invalid public key value")
os.Exit(1)
}
pub := &PublicKey{
G: publicKeyVal.G,
P: publicKeyVal.P,
Y: publicKeyVal.Y,
}
signatureBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding hexadecimal signature:", err)
return
}
hash := myHash()
// if _, err := io.Copy(h, os.Stdin); err != nil {
if _, err := io.Copy(hash, inputfile); err != nil {
log.Fatal(err)
}
if err != nil {
fmt.Println("Error hashing message:", err)
os.Exit(1)
}
hashBytes := hash.Sum(nil)
isValid, _ := VerifyASN1(pub, hashBytes, signatureBytes)
fmt.Println("Verified:", isValid)
if isValid {
os.Exit(0)
} else {
os.Exit(1)
}
}
}
if (strings.ToUpper(*alg) == "EC-ELGAMAL" || strings.ToUpper(*alg) == "ECKA-EG") && (*pkey == "keygen" || *pkey == "wrapkey" || *pkey == "unwrapkey" || *pkey == "text" || *pkey == "modulus" || *pkey == "fingerprint" || *pkey == "randomart") {
var blockType string
if *key != "" {
pemData, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Error decoding PEM block")
os.Exit(1)
}
blockType = block.Type
}
if *pkey == "text" && *key != "" && blockType == "EC-ELGAMAL ENCRYPTION KEY" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Deserialize the public key using bare
var pubKeyMarshal encryptionKeyMarshal
if err := bare.Unmarshal(keyBytes, &pubKeyMarshal); err != nil {
fmt.Println("Error deserializing public key:", err)
return
}
curveStr := string(pubKeyMarshal.Curve)
pubKeyPEM := pem.Block{Type: "EC-ELGAMAL ENCRYPTION KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("EncryptionKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Curve:", curveStr)
os.Exit(0)
} else if *pkey == "text" && *key != "" && blockType == "EC-ELGAMAL DECRYPTION KEY" {
keyBytes, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal(err)
}
block, _ := pem.Decode(keyBytes)
if block == nil {
log.Fatal(err)
}
keyBytes, err = readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Deserialize the private key using bare
var privKeyMarshal privateKeyMarshal
if err := bare.Unmarshal(keyBytes, &privKeyMarshal); err != nil {
fmt.Println("Error deserializing private key:", err)
return
}
curveStr := string(privKeyMarshal.Curve)
privKeyPEM := pem.Block{
Type: "EC-ELGAMAL DECRYPTION KEY",
Bytes: keyBytes,
}
keyPEMText := string(pem.EncodeToMemory(&privKeyPEM))
fmt.Print(keyPEMText)
dk := new(elgamal.DecryptionKey)
err = dk.UnmarshalBinary(keyBytes)
if err != nil {
fmt.Println("Error decoding private key:", err)
os.Exit(1)
}
ek := dk.EncryptionKey()
pubBytes, _ := ek.MarshalBinary()
fmt.Println("DecryptionKey:")
prv := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(prv, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("EncryptionKey:")
pub := fmt.Sprintf("%x", pubBytes)
splitz = SplitSubN(pub, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Curve:", curveStr)
os.Exit(0)
}
if *pkey == "modulus" && *key != "" && blockType == "EC-ELGAMAL ENCRYPTION KEY" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fmt.Printf("Public=%X\n", keyBytes)
os.Exit(0)
}
if *pkey == "modulus" && *key != "" && blockType == "EC-ELGAMAL DECRYPTION KEY" {
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
dk := new(elgamal.DecryptionKey)
err = dk.UnmarshalBinary(keyBytes)
if err != nil {
fmt.Println("Error decoding private key:", err)
os.Exit(1)
}
ek := dk.EncryptionKey()
pubBytes, _ := ek.MarshalBinary()
fmt.Printf("Public=%X\n", pubBytes)
os.Exit(0)
}
if *pkey == "fingerprint" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fingerprint := calculateFingerprint(keyBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
return
}
keySize := len(keyBytes) * 8
if keySize != 352 && keySize != 328 && keySize != 320 {
fmt.Println("EC-ElGamal (381-bit)")
} else {
fmt.Println("EC-ElGamal (256-bit)")
}
pubFile, err := os.Open(*key)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
}
if *pkey == "keygen" {
var curve *curves.Curve
switch strings.ToUpper(*curveFlag) {
case "BLS12381G1":
curve = curves.BLS12381G1()
case "BLS12381G2":
curve = curves.BLS12381G2()
case "P-256", "ECDSA", "EC", "SECP256R1":
curve = curves.P256()
case "ED25519":
curve = curves.ED25519()
case "PALLAS":
curve = curves.PALLAS()
case "KOBLITZ", "SECP256K1":
curve = curves.K256()
default:
curve = curves.P256()
}
ek, dk, _ := elgamal.NewKeys(curve)
privBytes, _ := dk.MarshalBinary()
pubBytes, _ := ek.MarshalBinary()
privKeyPEM := pem.Block{Type: "EC-ELGAMAL DECRYPTION KEY", Bytes: privBytes}
// privKeyPEM.Headers = map[string]string{"Curve": strings.ToUpper(*curveFlag)}
pubKeyPEM := pem.Block{Type: "EC-ELGAMAL ENCRYPTION KEY", Bytes: pubBytes}
// Save private key to file
savePEMToFile(*priv, &privKeyPEM, true)
privPath, err := filepath.Abs(*priv)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
os.Exit(1)
}
fmt.Printf("Private Key saved to: %s\n", privPath)
// Save public key to file
savePEMToFile(*pub, &pubKeyPEM, false)
pubPath, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key:", err)
os.Exit(1)
}
fmt.Printf("Public Key saved to: %s\n", pubPath)
// Fingerprint calculation and printing
fingerprint := calculateFingerprint(pubBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
// Randomart calculation and printing
keySize := len(pubBytes) * 8
if keySize != 352 && keySize != 328 && keySize != 320 {
fmt.Println("EC-ElGamal (381-bit)")
} else {
fmt.Println("EC-ElGamal (256-bit)")
}
pubFile, err := os.Open(*pub)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
} else {
if *pkey == "unwrapkey" {
if *key == "" {
fmt.Println("A key is required for decryption.")
os.Exit(3)
}
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Deserialize the private key using bare
var privKeyMarshal privateKeyMarshal
if err := bare.Unmarshal(keyBytes, &privKeyMarshal); err != nil {
fmt.Println("Error deserializing private key:", err)
return
}
var curve *curves.Curve
curveStr := string(privKeyMarshal.Curve)
if curveStr == "P-256" {
curve = curves.P256()
} else if curveStr == "BLS12381G1" {
curve = curves.BLS12381G1()
} else if curveStr == "BLS12381G2" {
curve = curves.BLS12381G2()
} else if curveStr == "ed25519" {
curve = curves.ED25519()
} else if curveStr == "pallas" {
curve = curves.PALLAS()
} else if curveStr == "secp256k1" {
curve = curves.K256()
}
privateScalar, err := curve.Scalar.SetBytes(privKeyMarshal.Value)
if err != nil {
fmt.Println("Error converting private key from bytes:", err)
return
}
ciphertextBytes, err := hex.DecodeString(*cph)
if err != nil {
fmt.Println("Error decoding ciphertext:", err)
os.Exit(1)
}
// Deserialize the ASN.1 encoded data to retrieve C1 and C2
var decodedCiphertext Ciphertext
if _, err := asn1.Unmarshal(ciphertextBytes, &decodedCiphertext); err != nil {
fmt.Println("Error decoding from ASN.1:", err)
return
}
// Convert C2 back to a point
C2Point, err := curve.Point.FromAffineCompressed(decodedCiphertext.C2)
if err != nil {
fmt.Println("Error converting C2 from affine:", err)
return
}
// Decrypt to retrieve the original value
xDecrypted := decrypt(privateScalar, new(big.Int).SetBytes(decodedCiphertext.C1), C2Point)
// Convert the decrypted value to bytes
decryptedBytes := xDecrypted.Bytes()
// Determine the expected byte length from the original ciphertext
// expectedLength := len(decodedCiphertext.C1)/8
expectedLength := len(C2Point.ToAffineCompressed())/8
// Pad the result with leading zeros if necessary
if len(decryptedBytes) < expectedLength {
paddedBytes := make([]byte, expectedLength)
copy(paddedBytes[expectedLength-len(decryptedBytes):], decryptedBytes)
decryptedBytes = paddedBytes
}
decryptedHex := fmt.Sprintf("%x", decryptedBytes)
fmt.Printf("Shared= %s\n", decryptedHex)
os.Exit(0)
} else {
if *key == "" {
fmt.Println("A key is required for encryption.")
return
}
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
return
}
// Deserialize the public key using bare
var pubKeyMarshal encryptionKeyMarshal
if err := bare.Unmarshal(keyBytes, &pubKeyMarshal); err != nil {
fmt.Println("Error deserializing public key:", err)
return
}
var curve *curves.Curve
curveStr := string(pubKeyMarshal.Curve)
if curveStr == "P-256" {
curve = curves.P256()
} else if curveStr == "BLS12381G1" {
curve = curves.BLS12381G1()
} else if curveStr == "BLS12381G2" {
curve = curves.BLS12381G2()
} else if curveStr == "ed25519" {
curve = curves.ED25519()
} else if curveStr == "pallas" {
curve = curves.PALLAS()
} else if curveStr == "secp256k1" {
curve = curves.K256()
}
publicKey, err := curve.Point.FromAffineCompressed(pubKeyMarshal.Value)
if err != nil {
fmt.Println("Error converting public key from affine:", err)
return
}
msgBytes := make([]byte, *length/8)
_, err = rand.Read(msgBytes)
if err != nil {
return
}
x := new(big.Int).SetBytes(msgBytes)
C1, C2 := encrypt(curve, x, curve.Point.Generator(), publicKey)
// Prepare data for ASN.1 encoding
ciphertext := Ciphertext{
C1: C1.Bytes(),
C2: C2.ToAffineCompressed(),
}
// Encode to ASN.1
asn1Data, err := asn1.Marshal(ciphertext)
if err != nil {
fmt.Println("Error encoding to ASN.1:", err)
return
}
fmt.Printf("Cipher= %x\n", asn1Data)
fmt.Printf("Shared= %x\n", msgBytes)
os.Exit(0)
}
}
}
if (strings.ToUpper(*alg) == "ECKA-EG-ALT") && (*pkey == "wrapkey" || *pkey == "unwrapkey") {
if *pkey == "unwrapkey" {
if *key == "" {
fmt.Println("A key is required for decryption.")
os.Exit(3)
}
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
domain := []byte(*id)
dk := new(elgamalAlt.DecryptionKey)
err = dk.UnmarshalBinary(keyBytes)
if err != nil {
fmt.Println("Error decoding private key:", err)
return
}
ciphertextBytes, err := hex.DecodeString(*cph)
if err != nil {
fmt.Println("Error decoding ciphertext:", err)
os.Exit(1)
}
cs := new(elgamalAlt.CipherText)
err = cs.UnmarshalBinary(ciphertextBytes)
if err != nil {
fmt.Println("Error decoding ciphertext:", err)
os.Exit(1)
}
dbytes, _, err := dk.VerifiableDecryptWithDomain(domain, cs)
if err != nil {
fmt.Println("Error decrypting:", err)
os.Exit(1)
}
fmt.Printf("Shared= %x\n", dbytes)
os.Exit(0)
} else {
if *key == "" {
fmt.Println("A key is required for encryption.")
return
}
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
return
}
domain := []byte(*id)
ek := new(elgamalAlt.EncryptionKey)
err = ek.UnmarshalBinary(keyBytes)
if err != nil {
fmt.Println("Error decoding public key:", err)
return
}
msgBytes := make([]byte, *length/8)
_, err = rand.Read(msgBytes)
if err != nil {
return
}
cs, proof, err := ek.VerifiableEncrypt(msgBytes, &elgamalAlt.EncryptParams{
Domain: domain,
MessageIsHashed: true,
GenProof: true,
ProofNonce: domain,
})
if err != nil {
fmt.Println("Error encrypting:", err)
return
}
res3, _ := cs.MarshalBinary()
fmt.Fprint(os.Stderr, "Verified: ")
rtn := ek.VerifyDomainEncryptProof(domain, cs, proof)
if rtn == nil {
fmt.Fprintln(os.Stderr, "true")
} else {
fmt.Fprintln(os.Stderr, "false")
}
fmt.Printf("Cipher= %x\n", res3)
fmt.Printf("Shared= %x\n", msgBytes)
os.Exit(0)
}
}
if (strings.ToUpper(*alg) == "ECKA-EG-SCHNORR") && (*pkey == "wrapkey" || *pkey == "unwrapkey") {
if *pkey == "unwrapkey" {
if *key == "" {
fmt.Println("A key is required for decryption.")
os.Exit(3)
}
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
domain := []byte(*id)
dk := new(elgamal.DecryptionKey)
err = dk.UnmarshalBinary(keyBytes)
if err != nil {
fmt.Println("Error decoding private key:", err)
return
}
ciphertextBytes, err := hex.DecodeString(*cph)
if err != nil {
fmt.Println("Error decoding ciphertext:", err)
os.Exit(1)
}
cs := new(elgamal.CipherText)
err = cs.UnmarshalBinary(ciphertextBytes)
if err != nil {
fmt.Println("Error decoding ciphertext:", err)
os.Exit(1)
}
dbytes, _, err := dk.VerifiableDecryptWithDomain(domain, cs)
if err != nil {
fmt.Println("Error decrypting:", err)
os.Exit(1)
}
fmt.Printf("Shared= %x\n", dbytes)
os.Exit(0)
} else {
if *key == "" {
fmt.Println("A key is required for encryption.")
return
}
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
return
}
domain := []byte(*id)
ek := new(elgamal.EncryptionKey)
err = ek.UnmarshalBinary(keyBytes)
if err != nil {
fmt.Println("Error decoding public key:", err)
return
}
msgBytes := make([]byte, *length/8)
_, err = rand.Read(msgBytes)
if err != nil {
return
}
cs, proof, err := ek.VerifiableEncrypt(msgBytes, &elgamal.EncryptParams{
Domain: domain,
MessageIsHashed: true,
GenProof: true,
ProofNonce: domain,
})
if err != nil {
fmt.Println("Error encrypting:", err)
return
}
res3, _ := cs.MarshalBinary()
fmt.Fprint(os.Stderr, "Verified: ")
rtn := ek.VerifyDomainEncryptProof(domain, cs, proof)
if rtn == nil {
fmt.Fprintln(os.Stderr, "true")
} else {
fmt.Fprintln(os.Stderr, "false")
}
fmt.Printf("Cipher= %x\n", res3)
fmt.Printf("Shared= %x\n", msgBytes)
os.Exit(0)
}
}
if (strings.ToUpper(*alg) == "ML-KEM") && (*pkey == "keygen" || *pkey == "wrapkey" || *pkey == "unwrapkey" || *pkey == "text" || *pkey == "fingerprint" || *pkey == "randomart") {
var blockType string
if *key != "" {
pemData, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Error decoding PEM block")
os.Exit(1)
}
blockType = block.Type
}
if *pkey == "text" && *key != "" && blockType == "ML-KEM SECRET KEY" {
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
pubKeyPEM := pem.Block{Type: "ML-KEM SECRET KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("SecretKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var oid string
switch len(keyBytes) {
case 1632:
oid = "ML-KEM-512"
case 2400:
oid = "ML-KEM-768"
case 3168:
oid = "ML-KEM-1024"
default:
fmt.Errorf("invalid public key size: %d", len(keyBytes))
}
fmt.Printf("ASN.1 OID: %s\n", oid)
os.Exit(0)
} else if *pkey == "text" && *key != "" && blockType == "ML-KEM PUBLIC KEY" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
pubKeyPEM := pem.Block{Type: "ML-KEM PUBLIC KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("PublicKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var oid string
switch len(keyBytes) {
case 800:
oid = "ML-KEM-512"
case 1184:
oid = "ML-KEM-768"
case 1568:
oid = "ML-KEM-1024"
default:
fmt.Errorf("invalid public key size: %d", len(keyBytes))
}
fmt.Printf("ASN.1 OID: %s\n", oid)
skid := sha3.Sum256(keyBytes)
fmt.Printf("\nKeyID: %x \n", skid[:20])
os.Exit(0)
}
if *pkey == "fingerprint" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fingerprint := calculateFingerprint(keyBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && *key != "" {
pubFile, err := os.Open(*key)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
// Determine key size based on the length of pubBuf
var keySize string
switch len(pk) {
case 800:
keySize = "512-bit"
case 1184:
keySize = "768-bit"
case 1568:
keySize = "1024-bit"
default:
keySize = "unknown size"
}
fmt.Printf("ML-KEM (%s)\n", keySize)
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
}
if *pkey == "keygen" {
// Generate keys
pk, sk, err := GenerateKyber(*length)
if err != nil {
fmt.Println("Error:", err)
return
}
block := &pem.Block{
Type: "ML-KEM SECRET KEY",
Bytes: sk,
}
// Save keys to pem files
if err := savePEMToFile(*priv, block, true); err != nil {
fmt.Println("Error saving keys:", err)
return
}
block = &pem.Block{
Type: "ML-KEM PUBLIC KEY",
Bytes: pk,
}
if err := savePEMToFile(*pub, block, false); err != nil {
fmt.Println("Error saving keys:", err)
return
}
// fmt.Println("Keys generated and saved successfully.")
privPath, err := filepath.Abs(*priv)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
os.Exit(1)
}
fmt.Printf("Private Key saved to: %s\n", privPath)
pubPath, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key:", err)
os.Exit(1)
}
fmt.Printf("Public Key saved to: %s\n", pubPath)
fingerprint := calculateFingerprint(pk)
fmt.Printf("Fingerprint: %s\n", fingerprint)
fmt.Printf("ML-KEM (%d-bit)\n", *length)
pubFile, err := os.Open(*pub)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
} else if *pkey == "wrapkey" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
// Wrap the key and save it to the specified public key file
err = WrapKey(pk)
if err != nil {
fmt.Println(err)
return
}
} else if *pkey == "unwrapkey" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
// Unwrap the key and specify the path to the cipher file
unwrappedKey, err := UnwrapKey(sk, *cph)
if err != nil {
fmt.Println("Error unwrapping key:", err)
return
}
fmt.Println("Shared=", hex.EncodeToString(unwrappedKey))
}
}
if (strings.ToUpper(*alg) == "ML-DSA") && (*pkey == "keygen" || *pkey == "certgen" || *pkey == "req" || *pkey == "x509" || *pkey == "check" || *pkey == "crl" || *pkey == "validate" || *pkey == "sign" || *pkey == "verify" || *pkey == "text" || *pkey == "fingerprint" || *pkey == "randomart") {
var blockType string
if *key != "" {
pemData, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Error decoding PEM block")
os.Exit(1)
}
blockType = block.Type
}
if *pkey == "text" && *key != "" && blockType == "ML-DSA SECRET KEY" {
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
pubKeyPEM := pem.Block{Type: "ML-DSA SECRET KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("SecretKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var oid string
switch len(keyBytes) {
case 2528:
oid = "ML-DSA-44"
case 4000:
oid = "ML-DSA-65"
case 4864:
oid = "ML-DSA-87"
default:
fmt.Errorf("invalid public key size: %d", len(keyBytes))
}
fmt.Printf("ASN.1 OID: %s\n", oid)
os.Exit(0)
} else if *pkey == "text" && *key != "" && blockType == "ML-DSA PUBLIC KEY" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
pubKeyPEM := pem.Block{Type: "ML-DSA PUBLIC KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("PublicKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var oid string
switch len(keyBytes) {
case 1312:
oid = "ML-DSA-44"
case 1952:
oid = "ML-DSA-65"
case 2592:
oid = "ML-DSA-87"
default:
fmt.Errorf("invalid public key size: %d", len(keyBytes))
}
fmt.Printf("ASN.1 OID: %s\n", oid)
skid := sha3.Sum256(keyBytes)
fmt.Printf("\nKeyID: %x \n", skid[:20])
os.Exit(0)
} else if *pkey == "text" && *key == "" && *crl != "" {
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
log.Fatalf("Erro ao ler o CRL: %v", err)
}
PrintCRLInfo(crl)
os.Exit(0)
}
if *pkey == "fingerprint" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fingerprint := calculateFingerprint(keyBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && *key != "" {
pubFile, err := os.Open(*key)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
// Determine key size based on the public key length
var keySize string
switch len(pk) {
case 1312:
keySize = "2048-bit"
case 1952:
keySize = "3072-bit"
case 2592:
keySize = "4096-bit"
default:
keySize = "unknown size"
}
fmt.Printf("ML-DSA (%s)\n", keySize)
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
}
if *pkey == "keygen" {
// Generate keys
pk, sk, err := GenerateDilithium(*length)
if err != nil {
fmt.Println("Error:", err)
return
}
block := &pem.Block{
Type: "ML-DSA SECRET KEY",
Bytes: sk,
}
// Save keys to pem files
if err := savePEMToFile(*priv, block, true); err != nil {
fmt.Println("Error saving keys:", err)
return
}
block = &pem.Block{
Type: "ML-DSA PUBLIC KEY",
Bytes: pk,
}
if err := savePEMToFile(*pub, block, false); err != nil {
fmt.Println("Error saving keys:", err)
return
}
privPath, err := filepath.Abs(*priv)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
os.Exit(1)
}
fmt.Printf("Private Key saved to: %s\n", privPath)
pubPath, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key:", err)
os.Exit(1)
}
fmt.Printf("Public Key saved to: %s\n", pubPath)
fingerprint := calculateFingerprint(pk)
fmt.Printf("Fingerprint: %s\n", fingerprint)
// Determine key size based on the public key length
var keySize string
switch len(pk) {
case 1312:
keySize = "2048-bit"
case 1952:
keySize = "3072-bit"
case 2592:
keySize = "4096-bit"
default:
keySize = "unknown size"
}
fmt.Printf("ML-DSA (%s)\n", keySize)
pubFile, err := os.Open(*pub)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
} else if *pkey == "sign" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Sign message
signature, err := Sign(sk, inputfile)
if err != nil {
fmt.Println("Error signing message:", err)
os.Exit(1)
}
// Save the signature
if err := SaveSignatureToPEM(signature, *sig); err != nil {
fmt.Println("Error saving signature:", err)
os.Exit(1)
}
} else if *pkey == "verify" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Read message from stdin
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading message:", err)
os.Exit(1)
}
// Verify message
err = Verify(pk, *sig, msg)
if err != nil {
fmt.Println("Error verifying signature:", err)
os.Exit(1)
}
fmt.Println("Verified: true")
} else if *pkey == "certgen" {
// Load public key
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
ca := NewCA(sk, pk, validity)
// subject := pkix.Name{CommonName: *subj}
subject := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
certificate, err := ca.IssueCertificate(subject, email, pk, sk, true, validity)
if err != nil {
fmt.Println("Error issuing certificate:", err)
return
}
err = SaveCertificateToPEM(certificate, *cert)
if err != nil {
fmt.Println("Error saving certificate:", err)
return
}
fmt.Println("Certificate issued and saved successfully.")
os.Exit(0)
} else if *pkey == "check" && *crl == "" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Erro ao ler o certificado:", err)
return
}
err = VerifyCertificate(certificate, pk)
if err != nil {
fmt.Println("Verified: false", err)
os.Exit(1)
} else {
fmt.Println("Verified: true")
os.Exit(0)
}
} else if *pkey == "text" && *cert != "" {
// Load certificate
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
// Try loading as CSR
csr, err := ReadCSRFromPEM(*cert)
if err != nil {
fmt.Println("Error loading certificate or CSR:", err)
return
}
// Print CSR info
PrintInfo(csr)
} else {
// Print certificate info
PrintInfo(certificate)
}
os.Exit(0)
} else if *pkey == "req" {
caPrivateKey, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
// Create a new CSR
// subject := pkix.Name{CommonName: *subj}
subject := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
publicKey, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
csr, err := CreateCSR(subject, email, publicKey, caPrivateKey)
if err != nil {
log.Fatalf("Failed to create CSR: %v", err)
}
// Save CSR to PEM
err = SaveCSRToPEM(csr, *cert)
if err != nil {
log.Fatalf("Failed to save CSR: %v", err)
}
fmt.Println("CSR created and saved to", *cert)
os.Exit(0)
} else if *pkey == "x509" {
caPrivateKey, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
caCert, err := ReadCertificateFromPEM(*root)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Read CSR from PEM
csr, err := ReadCSRFromPEM(*cert)
if err != nil {
log.Fatalf("Failed to read CSR: %v", err)
}
// Create CA instance
ca := &CA{
PrivateKey: caPrivateKey,
Certificate: *caCert,
}
// Sign the CSR with the CA's private key
signedCert, err := SignCSR(csr, ca, caPrivateKey, validity)
if err != nil {
log.Fatalf("Failed to sign CSR: %v", err)
}
var outputFilename string
if flag.Arg(0) == "" {
outputFilename = "stdout"
} else {
outputFilename = flag.Arg(0)
}
// Save signed certificate to PEM
err = SaveCertificateToPEM(signedCert, flag.Arg(0))
if err != nil {
log.Fatalf("Failed to save certificate: %v", err)
}
fmt.Fprintf(os.Stderr, "Certificate signed and saved to %s\n", outputFilename)
os.Exit(0)
} else if *pkey == "crl" {
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading public key:", err)
return
}
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading private key:", err)
return
}
cert, err := ReadCertificateFromPEM(*cert)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Create CA
ca := NewCA(sk, pk, validity)
// Create a CRL
crl, err := NewCRL(ca, *crl, validity)
if err != nil {
fmt.Println("Error generating CRL:", err)
return
}
// Read revoked serial numbers from the text file
revokedSerials, err := readRevokedSerials(flag.Arg(0))
if err != nil {
fmt.Printf("Error reading revoked serial numbers: %v\n", err)
return
}
// Revoke each serial number from the list
for _, serial := range revokedSerials {
crl.RevokeCertificate(serial)
}
// Sign the CRL
if err := crl.Sign(ca, cert); err != nil {
fmt.Printf("Error signing CRL: %v\n", err)
return
}
// Save the CRL to a specified output file or standard output
var outputFile string
if len(flag.Args()) > 0 {
outputFile = flag.Arg(1)
}
if err := SaveCRLToPEM(crl, outputFile); err != nil {
fmt.Printf("Error saving CRL: %v\n", err)
return
}
fmt.Println("CRL generated and saved successfully.")
os.Exit(0)
} else if *pkey == "validate" {
// Load the certificate to validate
certToValidate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Printf("Error reading certificate: %v\n", err)
return
}
readCRL, err := ReadCRLFromPEM(*crl)
if err != nil {
fmt.Printf("Error reading CRL: %v\n", err)
return
}
// Check if the certificate was revoked
if readCRL.IsRevoked(certToValidate.SerialNumber) {
fmt.Println("The certificate has been revoked")
os.Exit(1)
} else {
fmt.Println("The certificate is not revoked")
os.Exit(0)
}
} else if *pkey == "check" && *crl != "" {
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Error reading certificate:", err)
return
}
// Load the CRL
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
fmt.Printf("Error reading CRL: %v\n", err)
os.Exit(1)
}
// Verify the CRL against the CA's public key
if err := CheckCRL(crl, certificate.PublicKey); err != nil {
fmt.Println("Verified: false", err)
// fmt.Printf("%v\n", err)
os.Exit(3)
}
fmt.Println("Verified: true")
os.Exit(0)
}
}
if (strings.ToUpper(*alg) == "BLS12381I") && (*pkey == "keygen" || *pkey == "sign" || *pkey == "aggregate" || *pkey == "verify-aggregate" || *pkey == "verify" || *pkey == "derive" || *pkey == "encrypt" || *pkey == "decrypt" || *pkey == "text" || *pkey == "fingerprint" || *pkey == "randomart" || *pkey == "certgen" || *pkey == "x509" || *pkey == "req" || *pkey == "check" || *pkey == "text" || *pkey == "crl" || *pkey == "validate") {
var blockType string
if *key != "" {
pemData, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Error decoding PEM block")
os.Exit(1)
}
blockType = block.Type
}
// Comando de texto para exibir as chaves
if *pkey == "text" && *key != "" && blockType == "BLS12381I SECRET KEY" {
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Serializar a chave privada
var privKey bls.PrivateKey[bls.G2]
privKey.UnmarshalBinary(keyBytes)
// Derivar a chave pública de BLS12381
pubKey := privKey.PublicKey()
// Exibir chaves em formato PEM
keyPEM := pem.Block{Type: "BLS12381I SECRET KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&keyPEM))
fmt.Print(keyPEMText)
fmt.Println("SecretKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
pubBytes, err := pubKey.MarshalBinary()
if err != nil {
log.Fatalf("Erro ao serializar chave pública: %v", err)
}
fmt.Println("PublicKey:")
p = fmt.Sprintf("%x", pubBytes)
splitz = SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", "BLS12381")
os.Exit(0)
} else if *pkey == "text" && *key != "" && (blockType == "BLS12381I PUBLIC KEY" || blockType == "BLS12381I AGGREGATED PUBLIC KEY") {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
pubKeyPEM := pem.Block{Type: "BLS12381I PUBLIC KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("PublicKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", "BLS12381")
skid := sha3.Sum256(keyBytes)
fmt.Printf("\nKeyID: %x \n", skid[:20])
os.Exit(0)
} else if *pkey == "fingerprint" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fingerprint := calculateFingerprint(keyBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && *key != "" {
pubFile, err := os.Open(*key)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
fmt.Println("BLS12 381-bit")
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
} else if *pkey == "text" && *key == "" && *crl != "" {
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
log.Fatalf("Erro ao ler o CRL: %v", err)
}
PrintCRLInfo(crl)
os.Exit(0)
}
// Key generation command
if *pkey == "keygen" {
// Generate keys using BLS12381
ikm := make([]byte, 32)
_, err := rand.Read(ikm)
if err != nil {
log.Fatal("Erro ao gerar IKM aleatório:", err)
}
// Generate private key
privKey, err := bls.KeyGen[bls.G2](ikm, []byte(*salt), []byte(*info))
if err != nil {
log.Fatal("Error generating private key: ", err)
}
// Public key corresponding to the private key
pubKey := privKey.PublicKey()
// Convert to []byte for both keys
privBytes, err := privKey.MarshalBinary()
if err != nil {
log.Fatal("Error serializing private key: ", err)
}
pubBytes, err := pubKey.MarshalBinary()
if err != nil {
log.Fatal("Error serializing public key: ", err)
}
// Save keys as PEM (BLS12381)
privPEM := pem.Block{Type: "BLS12381I SECRET KEY", Bytes: privBytes}
pubPEM := pem.Block{Type: "BLS12381I PUBLIC KEY", Bytes: pubBytes}
if err := savePEMToFile(*priv, &privPEM, true); err != nil {
fmt.Println("Error saving private key:", err)
return
}
if err := savePEMToFile(*pub, &pubPEM, false); err != nil {
fmt.Println("Error saving public key:", err)
return
}
// Output paths of saved keys
privPath, err := filepath.Abs(*priv)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
os.Exit(1)
}
fmt.Printf("Private Key saved to: %s\n", privPath)
pubPath, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key:", err)
os.Exit(1)
}
fmt.Printf("Public Key saved to: %s\n", pubPath)
// Fingerprint calculation
fingerprint := calculateFingerprint(pubBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
// Random art visualization (optional)
pubFile, err := os.Open(*pub)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
fmt.Println("BLS12 381-bit")
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
} else if *pkey == "sign" {
// Carregar chave secreta (Privada)
privKeyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Desserializar a chave privada
var privKey bls.PrivateKey[bls.G2]
err = privKey.UnmarshalBinary(privKeyBytes)
if err != nil {
fmt.Println("Error unmarshaling private key:", err)
os.Exit(1)
}
// Mensagem a ser assinada
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
// Assinar a mensagem com a chave privada
signature := bls.Sign(&privKey, msg)
// Exibir a assinatura gerada
fmt.Println("PureBLS12381("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
} else if *pkey == "verify" {
// Carregar chave pública
pubKeyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública
var pubKey bls.PublicKey[bls.G2]
err = pubKey.UnmarshalBinary(pubKeyBytes)
if err != nil {
fmt.Println("Error unmarshaling public key:", err)
os.Exit(1)
}
// Ler a mensagem
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading message:", err)
os.Exit(1)
}
// Desserializar assinatura
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
// Verificando a assinatura com a chave pública
valid := bls.Verify(&pubKey, msg, sigBytes)
if valid {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
os.Exit(0)
} else if *pkey == "aggregate" {
// Load private key
privKeyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Deserialize private key
var privKey bls.PrivateKey[bls.G2]
err = privKey.UnmarshalBinary(privKeyBytes)
if err != nil {
fmt.Println("Error deserializing private key:", err)
os.Exit(1)
}
// Load the message to be signed
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Sign the message
signature := bls.Sign(&privKey, msg)
fmt.Println("Individual_BLS12381("+inputdesc+")=", hex.EncodeToString(signature))
// Aggregate the signature
aggregatedSignature := signature
if *sig != "" {
aggregatedSigData, err := hex.DecodeString(*sig)
if err != nil {
log.Fatalf("Error decoding aggregated signature: %v", err)
}
// Load the previous aggregated signature
existingAggregatedSig := aggregatedSigData
// Aggregate the signatures
aggregatedSignature, err = bls.Aggregate(bls.G2{}, []bls.Signature{existingAggregatedSig, signature})
if err != nil {
log.Fatalf("Error aggregating signatures: %v", err)
}
}
// Print the aggregated signature
fmt.Println("Aggregated_BLS12381=", hex.EncodeToString(aggregatedSignature[:]))
} else if *pkey == "verify-aggregate" {
// Verify that the number of public keys and messages are the same
if len(pubs) != len(msgs) {
log.Fatal("The number of public keys and messages must be the same.")
}
// Load public keys
var pubKeys []*bls.PublicKey[bls.G2]
for _, pubPath := range pubs {
pubKeyBytes, err := readKeyFromPEM(pubPath, false)
if err != nil {
fmt.Println("Error loading public key from", pubPath, ":", err)
os.Exit(1)
}
var pubKey bls.PublicKey[bls.G2]
err = pubKey.UnmarshalBinary(pubKeyBytes)
if err != nil {
fmt.Println("Error deserializing public key from", pubPath, ":", err)
os.Exit(1)
}
pubKeys = append(pubKeys, &pubKey)
}
// Load the messages
var msgsData [][]byte
for _, msgPath := range msgs {
msg, err := ioutil.ReadFile(msgPath)
if err != nil {
log.Fatalf("Error loading message %s: %v", msgPath, err)
}
msgsData = append(msgsData, msg)
}
// Decode the aggregated signature
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
// Verify the aggregated signature with multiple public keys
valid := bls.VerifyAggregate(pubKeys, msgsData, sigBytes)
if valid {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
os.Exit(0)
} else if *pkey == "derive" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading secret key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
// Convert big.Int to *ff.Scalar using SetBytes
skScalar := new(ff.Scalar)
skScalar.SetBytes(skBigInt.Bytes())
// Load public key
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Deserialize public key into a point on G2
var pubKey bls12381.G2
err = pubKey.SetBytes(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
// Base point for G1 (use the generator from the library)
baseG1 := bls12381.G1Generator()
// Compute the pairing e(PublicKey, SecretKey)
// This is essentially the Diffie-Hellman-like pairing using the Pair function
pairing := bls12381.Pair(baseG1, &pubKey)
// Exponentiate the pairing with the secret key to get the shared key
sharedKey := new(bls12381.Gt)
sharedKey.Exp(pairing, skScalar)
// Print the shared key
sharedBytes, err := sharedKey.MarshalBinary()
if err != nil {
log.Fatalf("Error marshaling shared key: %v", err)
}
fmt.Printf("Shared= %x\n", bmw.Sum256(sharedBytes))
} else if *pkey == "encrypt" {
// Carregar chave pública
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública em um ponto do grupo G2
var pubKey bls12381.G2
err = pubKey.SetBytes(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
// Ler a mensagem do arquivo de entrada
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
// Chamar a função de criptografia BLS
C1, C2, encryptedMessage := encryptBLS(string(msg), &pubKey, myHash)
// Serializar C1, C2 e a mensagem criptografada
serialized, err := serializeToASN1BLS(C1, C2, encryptedMessage)
if err != nil {
log.Fatal("Failed to serialize ciphertext: " + err.Error())
}
fmt.Printf("%s", serialized)
} else if *pkey == "decrypt" {
// Carregar chave secreta
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
// Ler o arquivo de entrada contendo o ciphertext
serialized, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
// Desserializar C1, C2 e a mensagem criptografada
deserializedC1, deserializedC2, deserializedMessage, err := deserializeFromASN1BLS(serialized)
if err != nil {
log.Fatal("Failed to deserialize ciphertext: " + err.Error())
}
// Decrypt a mensagem usando a função decryptBLS
decryptedMessage := decryptBLS(deserializedC1, deserializedC2, deserializedMessage, skBigInt, myHash)
// Exibir a mensagem descriptografada
fmt.Printf("%s", decryptedMessage)
} else if *pkey == "certgen" {
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Serializar a chave privada
var privKey bls.PrivateKey[bls.G2]
privKey.UnmarshalBinary(keyBytes)
// Derivar a chave pública de BLS12381
pubKey := privKey.PublicKey()
pubKeyBytes, err := pubKey.MarshalBinary()
if err != nil {
fmt.Println("Error marshaling public key from PEM:", err)
os.Exit(1)
}
ca := NewCA(keyBytes, pubKeyBytes, validity)
// subject := pkix.Name{CommonName: *subj}
subject := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
certificate, err := ca.IssueCertificate(subject, email, pubKeyBytes, keyBytes, true, validity)
if err != nil {
fmt.Println("Error issuing certificate:", err)
return
}
err = SaveCertificateToPEM(certificate, *cert)
if err != nil {
fmt.Println("Error saving certificate:", err)
return
}
fmt.Println("Certificate issued and saved successfully.")
os.Exit(0)
} else if *pkey == "check" && *crl == "" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Erro ao ler o certificado:", err)
return
}
err = VerifyCertificate(certificate, pk)
if err != nil {
fmt.Println("Verified: false", err)
os.Exit(1)
} else {
fmt.Println("Verified: true")
os.Exit(0)
}
} else if *pkey == "text" && *cert != "" {
// Load certificate
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
// Try loading as CSR
csr, err := ReadCSRFromPEM(*cert)
if err != nil {
fmt.Println("Error loading certificate or CSR:", err)
return
}
// Print CSR info
PrintInfo(csr)
} else {
// Print certificate info
PrintInfo(certificate)
}
os.Exit(0)
} else if *pkey == "req" {
// Load secret key
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Serializar a chave privada
var caPrivateKey bls.PrivateKey[bls.G2]
caPrivateKey.UnmarshalBinary(keyBytes)
// Derivar a chave pública de BLS12381
pubKey := caPrivateKey.PublicKey()
pubKeyBytes, err := pubKey.MarshalBinary()
// Create a new CSR
// subject := pkix.Name{CommonName: *subj}
subject := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
csr, err := CreateCSR(subject, email, pubKeyBytes, keyBytes)
if err != nil {
log.Fatalf("Failed to create CSR: %v", err)
}
// Save CSR to PEM
err = SaveCSRToPEM(csr, *cert)
if err != nil {
log.Fatalf("Failed to save CSR: %v", err)
}
fmt.Println("CSR created and saved to", *cert)
os.Exit(0)
} else if *pkey == "x509" {
// Load secret key
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Serializar a chave privada
var privKey bls.PrivateKey[bls.G2]
privKey.UnmarshalBinary(keyBytes)
caCert, err := ReadCertificateFromPEM(*root)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Read CSR from PEM
csr, err := ReadCSRFromPEM(*cert)
if err != nil {
log.Fatalf("Failed to read CSR: %v", err)
}
// Create CA instance
ca := &CA{
PrivateKey: keyBytes,
Certificate: *caCert,
}
// Sign the CSR with the CA's private key
signedCert, err := SignCSR(csr, ca, keyBytes, validity)
if err != nil {
log.Fatalf("Failed to sign CSR: %v", err)
}
var outputFilename string
if flag.Arg(0) == "" {
outputFilename = "stdout"
} else {
outputFilename = flag.Arg(0)
}
// Save signed certificate to PEM
err = SaveCertificateToPEM(signedCert, flag.Arg(0))
if err != nil {
log.Fatalf("Failed to save certificate: %v", err)
}
fmt.Fprintf(os.Stderr, "Certificate signed and saved to %s\n", outputFilename)
os.Exit(0)
} else if *pkey == "crl" {
// Load secret key
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Serializar a chave privada
var caPrivateKey bls.PrivateKey[bls.G2]
caPrivateKey.UnmarshalBinary(keyBytes)
// Derivar a chave pública de BLS12381
pubKey := caPrivateKey.PublicKey()
pubKeyBytes, err := pubKey.MarshalBinary()
cert, err := ReadCertificateFromPEM(*cert)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Create CA
ca := NewCA(keyBytes, pubKeyBytes, validity)
// Create a CRL
crl, err := NewCRL(ca, *crl, validity)
if err != nil {
fmt.Println("Error generating CRL:", err)
return
}
// Read revoked serial numbers from the text file
revokedSerials, err := readRevokedSerials(flag.Arg(0))
if err != nil {
fmt.Printf("Error reading revoked serial numbers: %v\n", err)
return
}
// Revoke each serial number from the list
for _, serial := range revokedSerials {
crl.RevokeCertificate(serial)
}
// Sign the CRL
if err := crl.Sign(ca, cert); err != nil {
fmt.Printf("Error signing CRL: %v\n", err)
return
}
// Save the CRL to a specified output file or standard output
var outputFile string
if len(flag.Args()) > 0 {
outputFile = flag.Arg(1)
}
if err := SaveCRLToPEM(crl, outputFile); err != nil {
fmt.Printf("Error saving CRL: %v\n", err)
return
}
fmt.Println("CRL generated and saved successfully.")
os.Exit(0)
} else if *pkey == "validate" {
// Load the certificate to validate
certToValidate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Printf("Error reading certificate: %v\n", err)
return
}
readCRL, err := ReadCRLFromPEM(*crl)
if err != nil {
fmt.Printf("Error reading CRL: %v\n", err)
return
}
// Check if the certificate was revoked
if readCRL.IsRevoked(certToValidate.SerialNumber) {
fmt.Println("The certificate has been revoked")
os.Exit(1)
} else {
fmt.Println("The certificate is not revoked")
os.Exit(0)
}
} else if *pkey == "check" && *crl != "" {
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Error reading certificate:", err)
return
}
// Load the CRL
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
fmt.Printf("Error reading CRL: %v\n", err)
os.Exit(1)
}
// Verify the CRL against the CA's public key
if err := CheckCRL(crl, certificate.PublicKey); err != nil {
fmt.Println("Verified: false", err)
// fmt.Printf("%v\n", err)
os.Exit(3)
}
fmt.Println("Verified: true")
os.Exit(0)
}
}
if strings.ToUpper(*alg) == "BLS12381PH" && (*pkey == "sign" || *pkey == "verify") {
if *pkey == "sign" {
// Carregar chave secreta (Privada)
privKeyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Desserializar a chave privada
var privKey bls.PrivateKey[bls.G2]
err = privKey.UnmarshalBinary(privKeyBytes)
if err != nil {
fmt.Println("Error unmarshaling private key:", err)
os.Exit(1)
}
// Abrir o arquivo da mensagem
inputfile, err := os.Open(inputdesc)
if err != nil {
fmt.Println("Error opening input file:", err)
os.Exit(1)
}
defer inputfile.Close()
// Pré-hash da mensagem usando o algoritmo selecionado
prehash := myHash()
if _, err := io.Copy(prehash, inputfile); err != nil {
log.Fatal(err)
}
hashBytes := prehash.Sum(nil)
// Assinar o hash da mensagem com a chave privada
signature := bls.Sign(&privKey, hashBytes)
// Exibir a assinatura gerada
fmt.Println("BLS12381-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature))
os.Exit(0)
} else if *pkey == "verify" {
// Carregar chave pública
pubKeyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública
var pubKey bls.PublicKey[bls.G2]
err = pubKey.UnmarshalBinary(pubKeyBytes)
if err != nil {
fmt.Println("Error unmarshaling public key:", err)
os.Exit(1)
}
// Abrir o arquivo da mensagem
inputfile, err := os.Open(inputdesc)
if err != nil {
fmt.Println("Error opening input file:", err)
os.Exit(1)
}
defer inputfile.Close()
// Pré-hash da mensagem usando o algoritmo selecionado
prehash := myHash()
if _, err := io.Copy(prehash, inputfile); err != nil {
log.Fatal(err)
}
hashBytes := prehash.Sum(nil)
// Desserializar a assinatura
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
// Verificar a assinatura com a chave pública e o hash da mensagem
valid := bls.Verify(&pubKey, hashBytes, sigBytes)
if valid {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
}
os.Exit(0)
}
}
if (strings.ToUpper(*alg) == "BLS12381I") && (*tcpip == "client" || *tcpip == "server") {
if *tcpip == "server" {
// Load secret key
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
log.Fatal(err)
}
port := "8081"
if *iport != "" {
port = *iport
}
// Start the TCP server
ln, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Fatal(err)
}
defer ln.Close()
// Print the message indicating the server is up and listening
fmt.Printf("Server(TUPI) up and listening on port %s\n", port)
for {
// Serializar a chave privada
var serverPrivKey bls.PrivateKey[bls.G2]
serverPrivKey.UnmarshalBinary(keyBytes)
// Send the server's public key to the client
serverPubKey := serverPrivKey.PublicKey()
serverPubKeyBytes, err := serverPubKey.MarshalBinary()
if err != nil {
log.Println("Error serializing server's public key:", err)
return
}
// conn.Write(serverPubKeyBytes)
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Erro ao ler o certificado:", err)
return
}
// Verifica se as chaves públicas coincidem
if len(certificate.PublicKey) != len(serverPubKeyBytes) || !bytes.Equal(certificate.PublicKey, serverPubKeyBytes) {
log.Fatal("The certificate does not match the private key.")
}
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
defer conn.Close()
// Abrir o arquivo do certificado
certData, err := os.ReadFile(*cert)
if err != nil {
log.Fatalf("Erro ao ler o certificado: %v", err)
}
_, err = conn.Write(certData)
if err != nil {
log.Printf("Erro ao enviar o certificado para o cliente: %v", err)
return
}
// Load the client's public key
clientPublicKeyBytes := make([]byte, 96)
_, err = conn.Read(clientPublicKeyBytes)
if err != nil {
// Check if the error is EOF, indicating that the client disconnected
if err == io.EOF {
fmt.Println("Client disconnected.")
} else {
log.Println("Error reading client's public key:", err)
}
return
}
var clientPubKey bls12381.G2
err = clientPubKey.SetBytes(clientPublicKeyBytes)
if err != nil {
log.Println("Error processing client's public key:", err)
return
}
// Send the server's public key to the client
// conn.Write(serverPubKeyBytes)
conn.Write(certificate.PublicKey)
// Pairing: G1 generator and client's public key
baseG1 := bls12381.G1Generator()
pairingResult := bls12381.Pair(baseG1, &clientPubKey)
serverPrivKeyBytes, err := serverPrivKey.MarshalBinary()
if err != nil {
log.Fatal(err)
}
// Convert the server's private key to ff.Scalar
serverPrivScalar := new(ff.Scalar)
serverPrivScalar.SetBytes(serverPrivKeyBytes)
// Raise the pairing result using the server's secret key (sk_server)
sharedKey := new(bls12381.Gt)
sharedKey.Exp(pairingResult, serverPrivScalar)
// Serialize the shared key
sharedBytes, err := sharedKey.MarshalBinary()
if err != nil {
log.Fatalf("Error serializing shared key: %v", err)
}
handshake := append(clientPublicKeyBytes, serverPubKeyBytes...)
handshake = append(handshake, sharedBytes...)
// Sign the shared key with the server's private key
signature := bls.Sign(&serverPrivKey, handshake)
conn.Write(signature)
// Deserialize the client's public key
var pubKey bls.PublicKey[bls.G2]
err = pubKey.UnmarshalBinary(clientPublicKeyBytes)
if err != nil {
fmt.Println("Error unmarshaling public key:", err)
os.Exit(1)
}
// Receive the shared key and server's signature
signatureBytes := make([]byte, 96)
_, err = conn.Read(signatureBytes)
if err != nil {
log.Fatal("Error reading server's signature:", err)
}
// Verify the client's signature on the session key
validClientSignature := bls.Verify(&pubKey, handshake, signatureBytes)
if !validClientSignature {
log.Fatal("Client's signature verification failed")
} else {
fmt.Println("Handshake completed")
}
// Encode the client's public key into PEM format
clientPubKeyPEM := pem.EncodeToMemory(&pem.Block{
Type: "BLS12381I PUBLIC KEY",
Bytes: clientPublicKeyBytes,
})
// Display the client's public key in PEM format
fmt.Printf("%s\n", clientPubKeyPEM)
// Display the client's IP address and port
clientAddr := conn.RemoteAddr()
currentTime := time.Now().Format("2006/01/02 15:04:05")
fmt.Printf("%s Client(TUPI) %s connected via secure channel.\n", currentTime, clientAddr)
// Hash the shared key with Whirlpool to create the Anubis key
whirlpoolHash := whirlpool.New()
whirlpoolHash.Write(sharedBytes)
whirlpoolHashSum := whirlpoolHash.Sum(nil)
/*
// Create the Anubis block
var block cipher.Block
var size int
// Create the Anubis cipher with the generated key
if strings.ToUpper(*paramset) == "A" {
block, err = anubis.NewWithKeySize(whirlpoolHashSum[:], 40)
size = 16
} else if strings.ToUpper(*paramset) == "B" {
block, err = curupira1.NewCipher(whirlpoolHashSum[:24])
size = 12
}
if err != nil {
log.Fatal("Error creating Anubis cipher:", err)
}
// Create AEAD (Authenticated Encryption with Associated Data)
// aead, err := cipher.NewGCMWithTagSize(block, 16)
aead, err := eax.NewEAX(block, size)
if err != nil {
log.Fatal("Error creating AEAD:", err)
}
*/
// Creating a Curupira instance for encryption
cipher, err := curupira1.NewCipher(whirlpoolHashSum[:24])
if err != nil {
log.Fatal("Error creating Curupira cipher instance:", err)
}
// Creating a LetterSoup instance for encryption
aead := curupira1.NewLetterSoup(cipher)
// Loop to receive and respond to messages
for {
// Receive encrypted data
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
// Check if the error is EOF, indicating that the client disconnected
if err == io.EOF {
log.Fatal("Client disconnected.")
}
log.Println("Error reading data from client:", err)
return
}
/*
// Separate the nonce and encrypted message
nonce, ciphertext := buf[:aead.NonceSize()], buf[aead.NonceSize():n]
// Decrypt the data
plaintext, err := aead.Open(nil, nonce, ciphertext, nil)
if err != nil {
log.Println("Error decrypting data:", err)
return
}
*/
nonce, tag, msg := buf[:12], buf[12:24], buf[24:n]
aead.SetIV(nonce)
plaintext := make([]byte, len(msg))
aead.Decrypt(plaintext, msg)
// Verifying data authenticity using the same tag calculated during encryption
ciphertext := make([]byte, len(plaintext))
aead.Encrypt(ciphertext, plaintext)
aead.Update(nil)
tagEnc := aead.GetTag(nil, 96)
if !bytes.Equal(tag, tagEnc) {
log.Fatal("Error: authentication verification failed!")
}
// Display the received message
fmt.Printf("Client response: %s\n", string(plaintext))
// Ask the server to type a response
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
response, err := reader.ReadString('\n')
if err != nil {
log.Fatal("Error reading input:", err)
}
response = response[:len(response)-1]
/*
// Encrypt the response
ciphertextResponse := aead.Seal(nonce, nonce, []byte(response), nil)
*/
nonce = make([]byte, 12)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
aead.SetIV(nonce)
ciphertext = make([]byte, len([]byte(response)))
aead.Encrypt(ciphertext, []byte(response))
aead.Update(nil)
tag = aead.GetTag(nil, 96)
// Displaying the encrypted message
ciphertextResponse := append(nonce, tag...)
ciphertextResponse = append(ciphertextResponse, ciphertext...)
// Send the encrypted response back to the client
_, err = conn.Write(ciphertextResponse)
if err != nil {
log.Fatal("Error sending encrypted data:", err)
}
}
}
} else {
ipport := "127.0.0.1:8081"
if *iport != "" {
ipport = *iport
}
// Connect to the TCP server
conn, err := net.Dial("tcp", ipport)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
// Load secret key
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
log.Fatal(err)
}
// Serializar a chave privada
var clientPrivKey bls.PrivateKey[bls.G2]
clientPrivKey.UnmarshalBinary(keyBytes)
clientPubKey := clientPrivKey.PublicKey()
// Send the client's public key to the server
clientPubKeyBytes, err := clientPubKey.MarshalBinary()
if err != nil {
log.Fatal("Error serializing client's public key:", err)
}
// conn.Write(clientPubKeyBytes)
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Erro ao ler o certificado:", err)
return
}
// Verifica se as chaves públicas coincidem
if len(certificate.PublicKey) != len(clientPubKeyBytes) || !bytes.Equal(certificate.PublicKey, clientPubKeyBytes) {
log.Fatal("The certificate does not match the private key.")
}
conn.Write(certificate.PublicKey)
certData := make([]byte, 2048)
n, err := conn.Read(certData)
if err != nil && err != io.EOF {
log.Fatalf("Erro ao ler o certificado do servidor: %v", err)
}
certBlock, _ := pem.Decode(certData)
if certBlock == nil {
return
}
if certBlock.Type != strings.ToUpper(*alg) + " CERTIFICATE" {
return
}
var cert Certificate
_, err = asn1.Unmarshal(certBlock.Bytes, &cert)
if err != nil {
log.Fatal(err)
}
fmt.Println("Issuer:")
fmt.Println(" ", cert.Issuer)
fmt.Println("Subject:")
fmt.Println(" ", cert.Subject)
fmt.Printf("Expiry: %s \n", cert.NotAfter.Format("Monday, 02-Jan-06 15:04:05 MST"))
fmt.Println(string(certData[:n]))
// Read the server's public key
serverPubKeyBytes := make([]byte, 96)
_, err = conn.Read(serverPubKeyBytes)
if err != nil {
log.Fatal("Error reading server's public key:", err)
}
var serverPubKey bls12381.G2
err = serverPubKey.SetBytes(serverPubKeyBytes)
if err != nil {
log.Fatal("Error processing server's public key:", err)
}
// Base point for G1 (curve generator)
baseG1 := bls12381.G1Generator()
// Perform the pairing between G1 and the server's public key (in G2)
pairing := bls12381.Pair(baseG1, &serverPubKey)
clientKeyBytes, err := clientPrivKey.MarshalBinary()
if err != nil {
log.Fatal(err)
}
// Exponentiate the pairing with the client's private key to obtain the shared key
clientPrivKeyBigInt := new(big.Int).SetBytes(clientKeyBytes)
clientPrivScalar := new(ff.Scalar)
clientPrivScalar.SetBytes(clientPrivKeyBigInt.Bytes())
// Exponentiate the pairing to generate the shared key
sharedKey := new(bls12381.Gt)
sharedKey.Exp(pairing, clientPrivScalar)
// Serialize the shared key
sharedBytes, err := sharedKey.MarshalBinary()
if err != nil {
log.Fatalf("Error serializing shared key: %v", err)
}
// Deserialize the public key
var pubKey bls.PublicKey[bls.G2]
err = pubKey.UnmarshalBinary(serverPubKeyBytes)
if err != nil {
fmt.Println("Error unmarshaling public key:", err)
os.Exit(1)
}
// Receive the shared key and server's signature
signatureBytes := make([]byte, 96)
_, err = conn.Read(signatureBytes)
if err != nil {
log.Fatal("Error reading server's signature:", err)
}
handshake := append(clientPubKeyBytes, serverPubKeyBytes...)
handshake = append(handshake, sharedBytes...)
// Verify the shared key signature
valid := bls.Verify(&pubKey, handshake, signatureBytes)
if !valid {
log.Fatal("Failed to verify the shared key's signature")
}
// The client must sign the generated session key
sessionKeySignature := bls.Sign(&clientPrivKey, handshake)
// Send the session key signature to the server
_, err = conn.Write(sessionKeySignature)
if err != nil {
log.Fatal("Error sending session key signature:", err)
}
// Hash the shared key with Whirlpool to create the Anubis key
whirlpoolHash := whirlpool.New()
whirlpoolHash.Write(sharedBytes)
whirlpoolHashSum := whirlpoolHash.Sum(nil)
/*
var block cipher.Block
var size int
// Create the Anubis cipher with the generated key
if strings.ToUpper(*paramset) == "A" {
block, err = anubis.NewWithKeySize(whirlpoolHashSum[:], 40)
size = 16
} else if strings.ToUpper(*paramset) == "B" {
block, err = curupira1.NewCipher(whirlpoolHashSum[:24])
size = 12
}
if err != nil {
log.Fatal("Error creating Anubis cipher:", err)
}
// Create AEAD (Authenticated Encryption with Associated Data)
// aead, err := cipher.NewGCMWithTagSize(block, 16)
aead, err := eax.NewEAX(block, size)
if err != nil {
log.Fatal("Error creating AEAD:", err)
}
*/
// Creating a Curupira instance for encryption
cipher, err := curupira1.NewCipher(whirlpoolHashSum[:24])
if err != nil {
log.Fatal("Error creating Curupira cipher instance:", err)
}
// Creating a LetterSoup instance for encryption
aead := curupira1.NewLetterSoup(cipher)
// Loop to send and receive messages
for {
// The client types the message
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
message, err := reader.ReadString('\n')
if err != nil {
log.Fatal("Error reading input:", err)
}
message = message[:len(message)-1]
/*
// Generate the nonce (initialization vector)
nonce := make([]byte, aead.NonceSize())
if _, err := rand.Read(nonce); err != nil {
log.Fatal("Error generating nonce:", err)
}
// Encrypt the message with Anubis-GCM
ciphertext := aead.Seal(nonce, nonce, []byte(message), nil)
*/
nonce := make([]byte, 12)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
aead.SetIV(nonce)
ciphertext := make([]byte, len([]byte(message)))
aead.Encrypt(ciphertext, []byte(message))
aead.Update(nil)
tag := aead.GetTag(nil, 96)
// Displaying the encrypted message
output := append(nonce, tag...)
output = append(output, ciphertext...)
// Send nonce + encrypted data to the server
// _, err = conn.Write(ciphertext)
_, err = conn.Write(output)
if err != nil {
log.Fatal("Error sending encrypted data:", err)
}
// Receive the server's response
buf := make([]byte, 1024)
n, err := conn.Read(buf)
if err != nil {
if err == io.EOF {
// If the error is EOF, it means the server closed the connection
fmt.Println("Server closed the connection. Exiting...")
break
} else {
log.Fatal("Error reading data from the server:", err)
}
}
/*
// Separate the nonce and encrypted message
nonce, ciphertext = buf[:aead.NonceSize()], buf[aead.NonceSize():n]
// Decrypt the response
plaintext, err := aead.Open(nil, nonce, ciphertext, nil)
if err != nil {
log.Fatal("Error decrypting data:", err)
}
*/
nonce, tag, msg := buf[:12], buf[12:24], buf[24:n]
aead.SetIV(nonce)
plaintext := make([]byte, len(msg))
aead.Decrypt(plaintext, msg)
// Verifying data authenticity using the same tag calculated during encryption
ciphertext = make([]byte, len(plaintext))
aead.Encrypt(ciphertext, plaintext)
aead.Update(nil)
tagEnc := aead.GetTag(nil, 96)
if !bytes.Equal(tag, tagEnc) {
log.Fatal("Error: authentication verification failed!")
}
// Display the server's response
fmt.Printf("Server response: %s\n", string(plaintext))
}
os.Exit(0)
}
}
if (strings.ToUpper(*alg) == "BN256I") && (*pkey == "keygen" || *pkey == "sign" || *pkey == "aggregate" || *pkey == "verify" || *pkey == "derive" || *pkey == "derive-scalar" || *pkey == "encrypt" || *pkey == "decrypt" || *pkey == "text" || *pkey == "fingerprint" || *pkey == "randomart" || *pkey == "certgen" || *pkey == "x509" || *pkey == "req" || *pkey == "check" || *pkey == "text" || *pkey == "crl" || *pkey == "validate") {
var blockType string
if *key != "" {
pemData, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Error decoding PEM block")
os.Exit(1)
}
blockType = block.Type
}
if *pkey == "text" && *key != "" && blockType == "BN256I SECRET KEY" {
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Serializar a chave privada
var privKey big.Int
privKey.SetBytes(keyBytes)
// Derivar a chave pública de BN256.G2 a partir da chave privada
pubKey := new(bn256i.G2).ScalarBaseMult(&privKey)
keyPEM := pem.Block{Type: "BN256I SECRET KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&keyPEM))
fmt.Print(keyPEMText)
fmt.Println("SecretKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("PublicKey:")
p = fmt.Sprintf("%x", pubKey.Marshal())
splitz = SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", "BN256")
os.Exit(0)
} else if *pkey == "text" && *key != "" && (blockType == "BN256I PUBLIC KEY" || blockType == "BN256I AGGREGATED PUBLIC KEY") {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
pubKeyPEM := pem.Block{Type: "BN256I PUBLIC KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("PublicKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", "BN256")
skid := sha3.Sum256(keyBytes)
fmt.Printf("\nKeyID: %x \n", skid[:20])
os.Exit(0)
}
if *pkey == "fingerprint" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fingerprint := calculateFingerprint(keyBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && *key != "" {
pubFile, err := os.Open(*key)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
fmt.Println("Barreto-Naehrig 256")
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
} else if *pkey == "text" && *key == "" && *crl != "" {
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
log.Fatalf("Erro ao ler o CRL: %v", err)
}
PrintCRLInfo(crl)
os.Exit(0)
}
if *pkey == "keygen" {
// Generate keys
sk, _, _ := bn256i.RandomG2(rand.Reader)
pk := new(bn256i.G2).ScalarBaseMult(sk)
if err != nil {
fmt.Println("Error:", err)
return
}
block := &pem.Block{
Type: "BN256I SECRET KEY",
Bytes: sk.Bytes(),
}
// Save keys to pem files
if err := savePEMToFile(*priv, block, true); err != nil {
fmt.Println("Error saving keys:", err)
return
}
block = &pem.Block{
Type: "BN256I PUBLIC KEY",
Bytes: pk.Marshal(),
}
if err := savePEMToFile(*pub, block, false); err != nil {
fmt.Println("Error saving keys:", err)
return
}
privPath, err := filepath.Abs(*priv)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
os.Exit(1)
}
fmt.Printf("Private Key saved to: %s\n", privPath)
pubPath, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key:", err)
os.Exit(1)
}
fmt.Printf("Public Key saved to: %s\n", pubPath)
fingerprint := calculateFingerprint(pk.Marshal())
fmt.Printf("Fingerprint: %s\n", fingerprint)
fmt.Printf("Barreto-Naehrig %d\n", 256)
pubFile, err := os.Open(*pub)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
} else if *pkey == "aggregate" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
// Sign message
hash := bn256i.HashG1(msg, []byte(*salt))
signature := hash.ScalarMult(hash, skBigInt)
if err != nil {
fmt.Println("Error signing message:", err)
os.Exit(1)
}
// Print the original signature (before aggregation)
fmt.Println("Individual_BN256("+inputdesc+")=", hex.EncodeToString(signature.Marshal()))
// Agregar assinatura com a assinatura anterior, se houver
aggregatedSignature := signature
// Se já houver uma assinatura agregada, carregar e agregar com a nova assinatura
if *sig != "" {
aggregatedSigData, err := hex.DecodeString(*sig)
if err != nil {
log.Fatalf("Error decoding aggregated signature from hex: %v", err)
}
existingAggregatedSig := new(bn256i.G1)
_, err = existingAggregatedSig.Unmarshal(aggregatedSigData)
if err != nil {
log.Fatalf("Error unmarshalling aggregated signature: %v", err)
}
aggregatedSignature.Add(aggregatedSignature, existingAggregatedSig)
}
// Agregar a chave pública correspondente à chave privada fornecida
pubKey := new(bn256i.G2).ScalarBaseMult(skBigInt)
// Se já houver uma chave pública agregada, carregar e agregar com a nova chave pública
aggregatedPubKey := pubKey
if *pub != "" {
aggregatedPubKeyData, err := readKeyFromPEM(*root, false)
if err != nil {
log.Fatalf("Error loading aggregated public key: %v", err)
}
existingAggregatedPubKey := new(bn256i.G2)
_, err = existingAggregatedPubKey.Unmarshal(aggregatedPubKeyData)
if err != nil {
log.Fatalf("Error unmarshalling aggregated public key: %v", err)
}
aggregatedPubKey.Add(aggregatedPubKey, existingAggregatedPubKey)
}
// Salvar a chave pública agregada em formato PEM
block := &pem.Block{
Type: "BN256I AGGREGATED PUBLIC KEY",
Bytes: aggregatedPubKey.Marshal(),
}
if err := savePEMToFile(*pub, block, false); err != nil {
fmt.Println("Error saving aggregated public key:", err)
return
}
// Save the signature
fmt.Println("Aggregated_BN256("+inputdesc+")=", hex.EncodeToString(signature.Marshal()))
} else if *pkey == "sign" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
// Sign message
hash := bn256i.HashG1(msg, []byte(*salt))
signature := hash.ScalarMult(hash, skBigInt)
if err != nil {
fmt.Println("Error signing message:", err)
os.Exit(1)
}
// Save the signature
fmt.Println("PureBN256("+inputdesc+")=", hex.EncodeToString(signature.Marshal()))
} else if *pkey == "verify" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Read message from stdin
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading message:", err)
os.Exit(1)
}
// Desserializar chave pública
var pubKey bn256i.G2
_, err = pubKey.Unmarshal(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
// Desserializar a assinatura
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
var signature bn256i.G1
signature.Unmarshal(sigBytes)
// Verificação da assinatura
h := bn256i.HashG1(msg, []byte(*salt))
rhs := bn256i.Pair(h, &pubKey)
lhs := bn256i.Pair(&signature, new(bn256i.G2).ScalarBaseMult(big.NewInt(1)))
if bytes.Equal(rhs.Marshal(), lhs.Marshal()) {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
}
} else if *pkey == "derive-scalar" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
// Load public key
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Desserializar chave pública
var pubKey bn256i.G2
_, err = pubKey.Unmarshal(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
// A calcula a chave compartilhada usando a chave pública de B e sua chave privada
sharedKey := new(bn256i.G2).ScalarMult(&pubKey, skBigInt)
// fmt.Printf("Shared= %x\n", sharedKey.Marshal())
fmt.Printf("Shared= %x\n", bmw.Sum256(sharedKey.Marshal()))
} else if *pkey == "derive" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
// Carregar chave pública
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública em um ponto do grupo G2
var pubKey bn256i.G2
_, err = pubKey.Unmarshal(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
// O gerador base de G1 pode ser utilizado diretamente como um ponto base (não exportado explicitamente)
// Se você não tiver um gerador, pode criar um novo, por exemplo:
baseG1 := new(bn256i.G1).ScalarBaseMult(big.NewInt(1048576))
// Calcular o pareamento e(PublicKey, SecretKey)
// A chave compartilhada é o pareamento entre a chave pública de uma parte e a chave secreta da outra parte
// No caso, usando o e(PublicKey, SecretKey), que é o equivalente a um "Diffie-Hellman" usando pareamento
pairing := bn256i.Pair(baseG1, &pubKey)
// Multiplicar o pareamento pela chave secreta
sharedKey := new(bn256i.GT)
sharedKey.ScalarMult(pairing, skBigInt)
// Imprimir a chave compartilhada gerada
// fmt.Printf("Shared= %x\n", sharedKey.Marshal())
fmt.Printf("Shared= %x\n", bmw.Sum256(sharedKey.Marshal()))
} else if *pkey == "encrypt" {
// Carregar chave pública
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública em um ponto do grupo G2
var pubKey bn256i.G2
_, err = pubKey.Unmarshal(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
C1, C2, encryptedMessage := encryptBN(string(msg), &pubKey, myHash)
serialized, err := serializeToASN1(C1, C2, encryptedMessage)
if err != nil {
log.Fatal("Failed to serialize ciphertext: " + err.Error())
}
fmt.Printf("%s", serialized)
} else if *pkey == "decrypt" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
serialized, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
deserializedC1, deserializedC2, deserializedMessage, err := deserializeFromASN1(serialized)
if err != nil {
log.Fatal("Failed to deserialize ciphertext: " + err.Error())
}
// Decrypt the message
decryptedMessage := decryptBN(deserializedC1, deserializedC2, deserializedMessage, skBigInt, myHash)
fmt.Printf("%s", decryptedMessage)
} else if *pkey == "certgen" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
var privKey big.Int
privKey.SetBytes(sk)
pk := new(bn256i.G2).ScalarBaseMult(&privKey)
ca := NewCA(sk, pk.Marshal(), validity)
// subject := pkix.Name{CommonName: *subj}
subject := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
certificate, err := ca.IssueCertificate(subject, email, pk.Marshal(), sk, true, validity)
if err != nil {
fmt.Println("Error issuing certificate:", err)
return
}
err = SaveCertificateToPEM(certificate, *cert)
if err != nil {
fmt.Println("Error saving certificate:", err)
return
}
fmt.Println("Certificate issued and saved successfully.")
os.Exit(0)
} else if *pkey == "check" && *crl == "" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
return
}
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Erro ao ler o certificado:", err)
return
}
err = VerifyCertificate(certificate, pk)
if err != nil {
fmt.Println("Verified: false", err)
os.Exit(1)
} else {
fmt.Println("Verified: true")
os.Exit(0)
}
} else if *pkey == "text" && *cert != "" {
// Load certificate
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
// Try loading as CSR
csr, err := ReadCSRFromPEM(*cert)
if err != nil {
fmt.Println("Error loading certificate or CSR:", err)
return
}
// Print CSR info
PrintInfo(csr)
} else {
// Print certificate info
PrintInfo(certificate)
}
os.Exit(0)
} else if *pkey == "req" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Create a new CSR
// subject := pkix.Name{CommonName: *subj}
subject := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
var privKey big.Int
privKey.SetBytes(sk)
pk := new(bn256i.G2).ScalarBaseMult(&privKey)
csr, err := CreateCSR(subject, email, pk.Marshal(), sk)
if err != nil {
log.Fatalf("Failed to create CSR: %v", err)
}
// Save CSR to PEM
err = SaveCSRToPEM(csr, *cert)
if err != nil {
log.Fatalf("Failed to save CSR: %v", err)
}
fmt.Println("CSR created and saved to", *cert)
os.Exit(0)
} else if *pkey == "x509" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
caCert, err := ReadCertificateFromPEM(*root)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Read CSR from PEM
csr, err := ReadCSRFromPEM(*cert)
if err != nil {
log.Fatalf("Failed to read CSR: %v", err)
}
// Create CA instance
ca := &CA{
PrivateKey: sk,
Certificate: *caCert,
}
// Sign the CSR with the CA's private key
signedCert, err := SignCSR(csr, ca, sk, validity)
if err != nil {
log.Fatalf("Failed to sign CSR: %v", err)
}
var outputFilename string
if flag.Arg(0) == "" {
outputFilename = "stdout"
} else {
outputFilename = flag.Arg(0)
}
// Save signed certificate to PEM
err = SaveCertificateToPEM(signedCert, flag.Arg(0))
if err != nil {
log.Fatalf("Failed to save certificate: %v", err)
}
fmt.Fprintf(os.Stderr, "Certificate signed and saved to %s\n", outputFilename)
os.Exit(0)
} else if *pkey == "crl" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
var privKey big.Int
privKey.SetBytes(sk)
pk := new(bn256i.G2).ScalarBaseMult(&privKey)
cert, err := ReadCertificateFromPEM(*cert)
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Create CA
ca := NewCA(sk, pk.Marshal(), validity)
// Create a CRL
crl, err := NewCRL(ca, *crl, validity)
if err != nil {
fmt.Println("Error generating CRL:", err)
return
}
// Read revoked serial numbers from the text file
revokedSerials, err := readRevokedSerials(flag.Arg(0))
if err != nil {
fmt.Printf("Error reading revoked serial numbers: %v\n", err)
return
}
// Revoke each serial number from the list
for _, serial := range revokedSerials {
crl.RevokeCertificate(serial)
}
// Sign the CRL
if err := crl.Sign(ca, cert); err != nil {
fmt.Printf("Error signing CRL: %v\n", err)
return
}
// Save the CRL to a specified output file or standard output
var outputFile string
if len(flag.Args()) > 0 {
outputFile = flag.Arg(1)
}
if err := SaveCRLToPEM(crl, outputFile); err != nil {
fmt.Printf("Error saving CRL: %v\n", err)
return
}
fmt.Println("CRL generated and saved successfully.")
os.Exit(0)
} else if *pkey == "validate" {
// Load the certificate to validate
certToValidate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Printf("Error reading certificate: %v\n", err)
return
}
readCRL, err := ReadCRLFromPEM(*crl)
if err != nil {
fmt.Printf("Error reading CRL: %v\n", err)
return
}
// Check if the certificate was revoked
if readCRL.IsRevoked(certToValidate.SerialNumber) {
fmt.Println("The certificate has been revoked")
os.Exit(1)
} else {
fmt.Println("The certificate is not revoked")
os.Exit(0)
}
} else if *pkey == "check" && *crl != "" {
certificate, err := ReadCertificateFromPEM(*cert)
if err != nil {
fmt.Println("Error reading certificate:", err)
return
}
// Load the CRL
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
fmt.Printf("Error reading CRL: %v\n", err)
os.Exit(1)
}
// Verify the CRL against the CA's public key
if err := CheckCRL(crl, certificate.PublicKey); err != nil {
fmt.Println("Verified: false", err)
// fmt.Printf("%v\n", err)
os.Exit(3)
}
fmt.Println("Verified: true")
os.Exit(0)
}
}
if strings.ToUpper(*alg) == "BN256PH" && (*pkey == "sign" || *pkey == "verify") {
if *pkey == "sign" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
// Pré-hash da mensagem usando o algoritmo selecionado
prehash := myHash()
if _, err := io.Copy(prehash, inputfile); err != nil {
log.Fatal(err)
}
hashBytes := prehash.Sum(nil)
// Assinar a mensagem
hashG1 := bn256i.HashG1(hashBytes, []byte(*salt))
signature := hashG1.ScalarMult(hashG1, skBigInt)
if err != nil {
fmt.Println("Error signing message:", err)
os.Exit(1)
}
// Salvar a assinatura
fmt.Println("BN256-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signature.Marshal()))
} else if *pkey == "verify" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Desserializar chave pública
var pubKey bn256i.G2
_, err = pubKey.Unmarshal(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
// Desserializar a assinatura
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
var signature bn256i.G1
signature.Unmarshal(sigBytes)
// Pré-hash da mensagem usando o algoritmo selecionado
prehash := myHash()
if _, err := io.Copy(prehash, inputfile); err != nil {
log.Fatal(err)
}
hashBytes := prehash.Sum(nil)
// Verificação da assinatura
h := bn256i.HashG1(hashBytes, []byte(*salt))
rhs := bn256i.Pair(h, &pubKey) // Passe o ponteiro de pubKey
lhs := bn256i.Pair(&signature, new(bn256i.G2).ScalarBaseMult(big.NewInt(1)))
if bytes.Equal(rhs.Marshal(), lhs.Marshal()) {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
}
}
}
if (strings.ToUpper(*alg) == "BN256") && (*pkey == "keygen" || *pkey == "setup" || *pkey == "sign" || *pkey == "aggregate" || *pkey == "verify" || *pkey == "derive" || *pkey == "encrypt" || *pkey == "decrypt" || *pkey == "text" || *pkey == "fingerprint" || *pkey == "randomart") {
var blockType string
if *key != "" {
pemData, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Error decoding PEM block")
os.Exit(1)
}
blockType = block.Type
}
if *pkey == "text" && *key != "" && (blockType == "BN256 SECRET KEY" || blockType == "BN256 MASTER KEY") {
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
// Serializar a chave privada
var privKey big.Int
privKey.SetBytes(keyBytes)
// Derivar a chave pública de BN256.G2 a partir da chave privada
pubKey := new(bn256i.G2).ScalarBaseMult(&privKey)
if blockType == "BN256 MASTER KEY" {
keyPEM := pem.Block{Type: "BN256 MASTER KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&keyPEM))
fmt.Print(keyPEMText)
fmt.Println("MasterKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("PublicKey:")
p = fmt.Sprintf("%x", pubKey.Marshal())
splitz = SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
} else {
keyPEM := pem.Block{Type: "BN256 SECRET KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&keyPEM))
fmt.Print(keyPEMText)
fmt.Println("SecretKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
}
fmt.Printf("Curve: %s\n", "BN256")
os.Exit(0)
} else if *pkey == "text" && *key != "" && (blockType == "BN256 PUBLIC KEY" || blockType == "BN256 PUBLIC KEY") {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
pubKeyPEM := pem.Block{Type: "BN256I PUBLIC KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("PublicKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", "BN256")
skid := sha3.Sum256(keyBytes)
fmt.Printf("\nKeyID: %x \n", skid[:20])
os.Exit(0)
}
if *pkey == "fingerprint" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fingerprint := calculateFingerprint(keyBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && *key != "" {
pubFile, err := os.Open(*key)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
fmt.Println("Barreto-Naehrig 256")
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
} else if *pkey == "text" && *key == "" && *crl != "" {
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
log.Fatalf("Erro ao ler o CRL: %v", err)
}
PrintCRLInfo(crl)
os.Exit(0)
}
if *pkey == "setup" {
// Generate keys
sk, _, _ := bn256i.RandomG2(rand.Reader)
pk := generateMasterPublicKey(sk)
if err != nil {
fmt.Println("Error:", err)
return
}
block := &pem.Block{
Type: "BN256 MASTER KEY",
Bytes: sk.Bytes(),
}
// Save keys to pem files
if err := savePEMToFile(*master, block, true); err != nil {
fmt.Println("Error saving keys:", err)
return
}
block = &pem.Block{
Type: "BN256 PUBLIC KEY",
Bytes: pk.Marshal(),
}
if err := savePEMToFile(*pub, block, false); err != nil {
fmt.Println("Error saving keys:", err)
return
}
privPath, err := filepath.Abs(*master)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
os.Exit(1)
}
fmt.Printf("Master Key saved to: %s\n", privPath)
pubPath, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key:", err)
os.Exit(1)
}
fmt.Printf("Public Key saved to: %s\n", pubPath)
fingerprint := calculateFingerprint(pk.Marshal())
fmt.Printf("Fingerprint: %s\n", fingerprint)
fmt.Printf("Barreto-Naehrig %d\n", 256)
pubFile, err := os.Open(*pub)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
} else if *pkey == "keygen" {
// Load master key
sk, err := readKeyFromPEM(*master, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
// Generate User Private Key
privateKey := generatePrivateKey(skBigInt, *id)
// Salvar a chave privada no formato PEM
block := &pem.Block{
Type: "BN256 SECRET KEY",
Bytes: privateKey.Bytes(),
}
if err := savePEMToFile2(*priv, block, true); err != nil {
fmt.Println("Error saving private key:", err)
return
}
// Obter o caminho absoluto do arquivo da chave privada
privPath, err := filepath.Abs(*priv)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
return
}
fmt.Printf("Private Key saved to: %s\n", privPath)
} else if *pkey == "sign" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
// Sign message
signature := signMessageBN(skBigInt, string(msg))
// Save the signature
fmt.Println("BN256("+inputdesc+")=", hex.EncodeToString(signature.Marshal()))
} else if *pkey == "verify" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Read message from stdin
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading message:", err)
os.Exit(1)
}
// Desserializar chave pública
var pubKey bn256i.G2
_, err = pubKey.Unmarshal(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
publicKey := generatePublicKeyForUser(&pubKey, *id)
// Desserializar a assinatura
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
var signature bn256i.G1
signature.Unmarshal(sigBytes)
// Verificação da assinatura
if verifySignatureBN(publicKey, string(msg), &signature) {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
os.Exit(0)
} else if *pkey == "derive" {
// Load secret key BN256
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
// Carregar chave pública
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública em um ponto do grupo G2
var pubKey bn256i.G2
_, err = pubKey.Unmarshal(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
// Gerar as chaves públicas para cada usuário
publicKey := generatePublicKeyForUser(&pubKey, *id)
// Calcular a chave secreta compartilhada entre os dois usuários usando o emparelhamento bilinear
sharedSecret := computeSharedSecret(skBigInt, publicKey)
// Imprimir a chave compartilhada gerada
fmt.Printf("Shared= %x\n", bmw.Sum256(sharedSecret.Bytes()))
} else if *pkey == "encrypt" {
// Carregar chave pública
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública em um ponto do grupo G2
var pubKey bn256i.G2
_, err = pubKey.Unmarshal(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
userPublicKey := generatePublicKeyForUser(&pubKey, *id)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
C1, C2, encryptedMessage := encryptBN(string(msg), userPublicKey, myHash)
serialized, err := serializeToASN1(C1, C2, encryptedMessage)
if err != nil {
log.Fatal("Failed to serialize ciphertext: " + err.Error())
}
fmt.Printf("%s", serialized)
} else if *pkey == "decrypt" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
serialized, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
deserializedC1, deserializedC2, deserializedMessage, err := deserializeFromASN1(serialized)
if err != nil {
log.Fatal("Failed to deserialize ciphertext: " + err.Error())
}
// Decrypt the message
decryptedMessage := decryptBN(deserializedC1, deserializedC2, deserializedMessage, skBigInt, myHash)
fmt.Printf("%s", decryptedMessage)
}
}
if (strings.ToUpper(*alg) == "BLS12381") && (*pkey == "keygen" || *pkey == "setup" || *pkey == "sign" || *pkey == "aggregate" || *pkey == "aggregate-proof" || *pkey == "aggregate-signatures" || *pkey == "verify-aggregate" || *pkey == "aggregate-vote" || *pkey == "aggregate-vote-encrypted" || *pkey == "aggregate-vote-audit" || *pkey == "aggregate-vote-proof" || *pkey == "verify-aggregate-vote" || *pkey == "verify-proof" || *pkey == "blind" || *pkey == "unblind" || *pkey == "count" || *pkey == "input" || *pkey == "count-total" || *pkey == "add" || *pkey == "sum" || *pkey == "hash" || *pkey == "verify" || *pkey == "derive" || *pkey == "encrypt" || *pkey == "decrypt" || *pkey == "text" || *pkey == "fingerprint" || *pkey == "randomart") {
var blockType string
if *key != "" {
pemData, err := ioutil.ReadFile(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
os.Exit(1)
}
block, _ := pem.Decode(pemData)
if block == nil {
fmt.Println("Error decoding PEM block")
os.Exit(1)
}
blockType = block.Type
}
if *pkey == "text" && *key != "" && (blockType == "BLS12381 SECRET KEY" || blockType == "BLS12381 MASTER KEY") {
// Load master key
keyBytes, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(keyBytes)
// Gerando o ponto G2 a partir da chave mestra escalar
pubKey := new(bls12381.G2)
pubKey.ScalarMult(skScalar, bls12381.G2Generator())
if blockType == "BLS12381 MASTER KEY" {
keyPEM := pem.Block{Type: "BLS12381 MASTER KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&keyPEM))
fmt.Print(keyPEMText)
fmt.Println("MasterKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("PublicKey:")
p = fmt.Sprintf("%x", pubKey.BytesCompressed())
splitz = SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
} else {
keyPEM := pem.Block{Type: "BLS12381 SECRET KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&keyPEM))
fmt.Print(keyPEMText)
fmt.Println("SecretKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
}
fmt.Printf("Curve: %s\n", "BLS12381")
os.Exit(0)
} else if *pkey == "text" && *key != "" && (blockType == "BLS12381 PUBLIC KEY") {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
pubKeyPEM := pem.Block{Type: "BLS12381 PUBLIC KEY", Bytes: keyBytes}
keyPEMText := string(pem.EncodeToMemory(&pubKeyPEM))
fmt.Print(keyPEMText)
fmt.Println("PublicKey:")
p := fmt.Sprintf("%x", keyBytes)
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", "BLS12381")
skid := sha3.Sum256(keyBytes)
fmt.Printf("\nKeyID: %x \n", skid[:20])
os.Exit(0)
}
if *pkey == "fingerprint" && *key != "" {
keyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error reading key from PEM:", err)
os.Exit(1)
}
fingerprint := calculateFingerprint(keyBytes)
fmt.Printf("Fingerprint: %s\n", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && *key != "" {
pubFile, err := os.Open(*key)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
fmt.Println("BLS12-381")
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
os.Exit(0)
} else if *pkey == "text" && *key == "" && *crl != "" {
crl, err := ReadCRLFromPEM(*crl)
if err != nil {
log.Fatalf("Erro ao ler o CRL: %v", err)
}
PrintCRLInfo(crl)
os.Exit(0)
}
if *pkey == "setup" {
var ikm []byte
var err error
if *key != "" {
// Read the master key from the provided file
ikm, err = readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error reading the master key:", err)
return
}
fmt.Println("Using provided master key.")
} else {
// Generate a random master key
ikm = make([]byte, 32)
_, err = rand.Read(ikm)
if err != nil {
log.Fatal("Error generating master key:", err)
}
fmt.Println("Generating new master key.")
// Save the generated master key
block := &pem.Block{
Type: "BLS12381 MASTER KEY",
Bytes: ikm,
}
if err := savePEMToFile(*master, block, true); err != nil {
fmt.Println("Error saving master key:", err)
return
}
privPath, err := filepath.Abs(*master)
if err != nil {
fmt.Println("Error getting absolute path for master key:", err)
os.Exit(1)
}
fmt.Printf("Master Key saved to: %s\n", privPath)
}
// Convert IKM to a scalar
skScalar := new(ff.Scalar)
skScalar.SetBytes(ikm)
if *key == "" {
// Save master (private) key
block := &pem.Block{
Type: "BLS12381 MASTER KEY",
Bytes: ikm,
}
if err := savePEMToFile(*master, block, true); err != nil {
fmt.Println("Error saving master key:", err)
return
}
// Display master key path
privPath, err := filepath.Abs(*master)
if err != nil {
fmt.Println("Error getting absolute path for master key:", err)
os.Exit(1)
}
fmt.Printf("Master Key saved to: %s\n", privPath)
}
if *pub2 != "" {
// Generate both public keys
pk1 := new(bls12381.G1)
pk1.ScalarMult(skScalar, bls12381.G1Generator())
pk2 := new(bls12381.G2)
pk2.ScalarMult(skScalar, bls12381.G2Generator())
// Save pk1 to *pub
block := &pem.Block{
Type: "BLS12381 PUBLIC KEY",
Bytes: pk1.BytesCompressed(),
}
if err := savePEMToFile(*pub, block, false); err != nil {
fmt.Println("Error saving public key G1:", err)
return
}
// Save pk2 to *pub2
block = &pem.Block{
Type: "BLS12381 PUBLIC KEY",
Bytes: pk2.BytesCompressed(),
}
if err := savePEMToFile(*pub2, block, false); err != nil {
fmt.Println("Error saving public key G2:", err)
return
}
// Display paths
pubPath1, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key G1:", err)
os.Exit(1)
}
fmt.Printf("Public Key G1 saved to: %s\n", pubPath1)
pubPath2, err := filepath.Abs(*pub2)
if err != nil {
fmt.Println("Error getting absolute path for public key G2:", err)
os.Exit(1)
}
fmt.Printf("Public Key G2 saved to: %s\n", pubPath2)
// Display fingerprints
fmt.Printf("Fingerprint G1: %s\n", calculateFingerprint(pk1.BytesCompressed()))
fmt.Printf("Fingerprint G2: %s\n", calculateFingerprint(pk2.BytesCompressed()))
// Print RandomArt for G1
fmt.Println("BLS12-381")
pubFile, err := os.Open(*pub)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
// Print RandomArt for G2
fmt.Println("BLS12-381")
pubFile2, err := os.Open(*pub2)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile2.Close()
pubInfo2, err := pubFile2.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf2 := make([]byte, pubInfo2.Size())
pubFile2.Read(pubBuf2)
randomArt2 := randomart.FromString(string(pubBuf2))
fmt.Println(randomArt2)
} else {
// Only generate pk2
pk2 := new(bls12381.G2)
pk2.ScalarMult(skScalar, bls12381.G2Generator())
// Save pk2 to *pub
block := &pem.Block{
Type: "BLS12381 PUBLIC KEY G2",
Bytes: pk2.BytesCompressed(),
}
if err := savePEMToFile(*pub, block, false); err != nil {
fmt.Println("Error saving public key G2:", err)
return
}
// Display path
pubPath, err := filepath.Abs(*pub)
if err != nil {
fmt.Println("Error getting absolute path for public key G2:", err)
os.Exit(1)
}
fmt.Printf("Public Key saved to: %s\n", pubPath)
// Display fingerprint
fmt.Printf("Fingerprint: %s\n", calculateFingerprint(pk2.BytesCompressed()))
// Print RandomArt for G2
fmt.Println("BLS12-381")
pubFile, err := os.Open(*pub)
if err != nil {
fmt.Println("Error opening public key file:", err)
os.Exit(1)
}
defer pubFile.Close()
pubInfo, err := pubFile.Stat()
if err != nil {
fmt.Println("Error getting public key file info:", err)
os.Exit(1)
}
pubBuf := make([]byte, pubInfo.Size())
pubFile.Read(pubBuf)
randomArt := randomart.FromString(string(pubBuf))
fmt.Println(randomArt)
}
} else if *pkey == "keygen" {
// Load master key
sk, err := readKeyFromPEM(*master, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Generate User Private Key
privateKey := generatePrivateKeyForUserBLS(skScalar, *id)
privateKeyBytes, _ := privateKey.MarshalBinary()
// Salvar a chave privada no formato PEM
block := &pem.Block{
Type: "BLS12381 SECRET KEY",
Bytes: privateKeyBytes,
}
if err := savePEMToFile2(*priv, block, true); err != nil {
fmt.Println("Error saving private key:", err)
return
}
// Obter o caminho absoluto do arquivo da chave privada
privPath, err := filepath.Abs(*priv)
if err != nil {
fmt.Println("Error getting absolute path for private key:", err)
return
}
fmt.Printf("Private Key saved to: %s\n", privPath)
} else if *pkey == "sign" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
// Sign message
signature := signMessageBLS(msg, skScalar)
// Save the signature
fmt.Println("BLS12381("+inputdesc+")=", hex.EncodeToString(signature.BytesCompressed()))
} else if *pkey == "verify" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Read message from stdin
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error reading message:", err)
os.Exit(1)
}
// Desserializar chave pública
var pubKey bls12381.G2
pubKey.SetBytes(pk)
publicKey := generatePublicKeyForUserBLS(&pubKey, *id)
// Desserializar a assinatura
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing signature: %v", err)
}
// Verificação da assinatura
if verifySignatureBLS(msg, signatureCopy, publicKey) {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
os.Exit(0)
} else if *pkey == "aggregate" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Load the message to be signed
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Sign the message
signature := signMessageBLS(msg, skScalar)
fmt.Println("Individual_BLS12381("+inputdesc+")=", hex.EncodeToString(signature.BytesCompressed()))
// Aggregate the signature
aggregatedSignature := signature
if *sig != "" {
// Desserializar a assinatura
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing signature: %v", err)
}
// Agregar as assinaturas
aggregatedSignature = aggregateSignatures([]*bls12381.G1{signatureCopy, signature})
}
// Print the aggregated signature
fmt.Println("Aggregated_BLS12381=", hex.EncodeToString(aggregatedSignature.BytesCompressed()))
} else if *pkey == "verify-aggregate" {
// Verifique se o número de chaves públicas e mensagens são iguais
if len(pubs) != len(msgs) {
log.Fatal("The number of public keys and messages must be the same.")
}
// Carregar a chave pública mestra
pubMasterKeyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading master public key:", err)
os.Exit(1)
}
// Desserializar a chave pública mestra
var masterPubKey bls12381.G2
masterPubKey.SetBytes(pubMasterKeyBytes)
// Carregar as chaves públicas dos usuários a partir dos UIDs (que estão passados pela flag -pubs)
var pubKeys [][]byte
for _, userID := range pubs {
// Gerar a chave pública do usuário a partir do ID
// A função `generatePublicKeyForUserBLS` irá gerar a chave pública do usuário usando a chave pública mestra
userPubKey := generatePublicKeyForUserBLS(&masterPubKey, userID)
// A chave pública é convertida para []byte para ser passada para a função de verificação
pubKeys = append(pubKeys, userPubKey.Bytes())
}
// Carregar as mensagens
var msgsData [][]byte
for _, msgPath := range msgs {
msg, err := ioutil.ReadFile(msgPath)
if err != nil {
log.Fatalf("Error loading message %s: %v", msgPath, err)
}
msgsData = append(msgsData, msg)
}
// Desserializar a assinatura agregada
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding the signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing the signature: %v", err)
}
// Verificar a assinatura agregada com as chaves públicas dos usuários (sem passar a chave mestra)
valid := verifyAggregateSignature(pubKeys, msgsData, signatureCopy)
if valid {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
os.Exit(0)
} else if *pkey == "aggregate-proof" {
// Load secret key
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Load the message to be signed
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Sign the message
signature := signMessageBLS(msg, skScalar)
fmt.Println("Individual_BLS12381("+inputdesc+")=", hex.EncodeToString(signature.BytesCompressed()))
// Gerar compromisso para a chave secreta (skScalar)
commitment := generateCommitment(randomScalar(), bls12381.G2Generator())
challenge := generateChallenge(commitment, msg)
response := generateResponse(skScalar, challenge)
// Aggregate the signature
aggregatedSignature := signature
if *sig != "" {
// Desserializar a assinatura
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing signature: %v", err)
}
// Agregar as assinaturas
aggregatedSignature = aggregateSignatures([]*bls12381.G1{signatureCopy, signature})
}
responseBytes, err := response.MarshalBinary()
if err != nil {
fmt.Println("Error serializing response:", err)
os.Exit(1)
}
challengeBytes, err := challenge.MarshalBinary()
if err != nil {
fmt.Println("Error serializing challenge:", err)
os.Exit(1)
}
// Print the aggregated signature
fmt.Println("Aggregated_BLS12381=", hex.EncodeToString(aggregatedSignature.BytesCompressed()))
// Prova de conhecimento
fmt.Printf("Commitment= %x\n", commitment.Bytes())
fmt.Printf("Challenge= %x\n", challengeBytes)
fmt.Printf("Response= %x\n", responseBytes)
} else if *pkey == "aggregate-vote" {
// Carregar chave secreta
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Ler a mensagem (voto)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Cegar a mensagem
originalG1 := hashToG1(msg)
blindFactor := generateBlindFactor()
blindedMessage := blindMessage(originalG1, blindFactor)
// Assinar a mensagem cegada
blindedSignature := signMessageBLS(blindedMessage.Bytes(), skScalar)
fmt.Println("Blinded_Signature("+inputdesc+")=", hex.EncodeToString(blindedSignature.BytesCompressed()))
// Agregar assinaturas cegas
aggregatedSignature := blindedSignature
if *sig != "" {
// Desserializar assinatura existente
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing signature: %v", err)
}
// Agregar assinaturas cegas
aggregatedSignature = aggregateSignatures([]*bls12381.G1{signatureCopy, blindedSignature})
}
// Imprimir assinatura agregada
fmt.Println("Aggregated_Blinded=", hex.EncodeToString(aggregatedSignature.BytesCompressed()))
// Imprimir o fator de cegamento para que o usuário possa descegar depois
blindFactorBytes, err := blindFactor.MarshalBinary()
if err != nil {
fmt.Println("Error serializing blind factor:", err)
os.Exit(1)
}
fmt.Printf("HashG1("+inputdesc+")= %x\n", originalG1.Bytes())
fmt.Println("Blind_Factor=", hex.EncodeToString(blindFactorBytes))
fmt.Println("Blind_Message=", hex.EncodeToString(blindedMessage.Bytes()))
} else if *pkey == "aggregate-vote-proof" {
// Carregar chave secreta
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Ler a mensagem (voto)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Cegar a mensagem
originalG1 := hashToG1(msg)
blindFactor := generateBlindFactor()
blindedMessage := blindMessage(originalG1, blindFactor)
// Assinar a mensagem cegada
blindedSignature := signMessageBLS(blindedMessage.Bytes(), skScalar)
fmt.Println("Blinded_Signature("+inputdesc+")=", hex.EncodeToString(blindedSignature.BytesCompressed()))
// Gerar compromisso para a chave secreta (skScalar)
commitment := generateCommitment(randomScalar(), bls12381.G2Generator())
challenge := generateChallenge(commitment, msg)
response := generateResponse(skScalar, challenge)
// Agregar assinaturas cegas
aggregatedSignature := blindedSignature
if *sig != "" {
// Desserializar assinatura existente
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing signature: %v", err)
}
// Agregar assinaturas cegas
aggregatedSignature = aggregateSignatures([]*bls12381.G1{signatureCopy, blindedSignature})
}
// Imprimir assinatura agregada
fmt.Println("Aggregated_Blinded=", hex.EncodeToString(aggregatedSignature.BytesCompressed()))
// Imprimir o fator de cegamento para que o usuário possa descegar depois
blindFactorBytes, err := blindFactor.MarshalBinary()
if err != nil {
fmt.Println("Error serializing blind factor:", err)
os.Exit(1)
}
responseBytes, err := response.MarshalBinary()
if err != nil {
fmt.Println("Error serializing response:", err)
os.Exit(1)
}
challengeBytes, err := challenge.MarshalBinary()
if err != nil {
fmt.Println("Error serializing challenge:", err)
os.Exit(1)
}
// Imprimir a chave de cegamento e a assinatura para verificação
fmt.Println("Blind_Factor=", hex.EncodeToString(blindFactorBytes))
fmt.Println("Blind_Message=", hex.EncodeToString(blindedMessage.Bytes()))
// Prova de conhecimento
fmt.Printf("Commitment= %x\n", commitment.Bytes())
fmt.Printf("Challenge= %x\n", challengeBytes)
fmt.Printf("Response= %x\n", responseBytes)
} else if *pkey == "aggregate-vote-encrypted" {
// Carregar chave secreta de assinatura (BLS)
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Ler a mensagem (voto)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Aplicar cegamento ao voto
originalG1 := hashToG1(msg)
blindFactor := generateBlindFactor()
blindedMessage := blindMessage(originalG1, blindFactor)
// If candidates are provided, compute HashG1 for each and compare
if *candidates != "" {
candidatesList := strings.Split(*candidates, ",")
var matchFound bool
// Iterate over each candidate and compute its HashG1
for _, candidate := range candidatesList {
candidate = strings.TrimSpace(candidate)
candidateHash := hashToG1([]byte(candidate))
// Compare the vote's HashG1 with the candidate's HashG1
if bytes.Equal(originalG1.Bytes(), candidateHash.Bytes()) {
fmt.Println("Vote matches one of the candidates.")
matchFound = true
break
}
}
if !matchFound {
fmt.Println("Vote does not match any provided candidates.")
return
}
}
// Assinar a mensagem cegada (BLS)
blindedSignature := signMessageBLS(blindedMessage.Bytes(), skScalar)
fmt.Println("Blinded_Signature("+inputdesc+")=", hex.EncodeToString(blindedSignature.BytesCompressed()))
// Gerar compromisso para a chave secreta (skScalar)
commitment := generateCommitment(randomScalar(), bls12381.G2Generator())
challenge := generateChallenge(commitment, msg)
response := generateResponse(skScalar, challenge)
// Agregar assinaturas cegas
aggregatedSignature := blindedSignature
if *sig != "" {
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing signature: %v", err)
}
// Agregar assinaturas cegas
aggregatedSignature = aggregateSignatures([]*bls12381.G1{signatureCopy, blindedSignature})
fmt.Println("Aggregated_Blinded=", hex.EncodeToString(aggregatedSignature.BytesCompressed()))
}
// Criptografar o blind factor com IBE
// Carregar chave pública mestra
masterPubKeyBytes, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading master public key:", err)
os.Exit(1)
}
var masterPubKey bls12381.G2
err = masterPubKey.SetBytes(masterPubKeyBytes)
if err != nil {
log.Fatalf("Error deserializing master public key: %v", err)
}
// Gerar chave pública do eleitor com base no ID
userPublicKey := generatePublicKeyForUserBLS(&masterPubKey, *id)
// Criptografar o fator de cegamento com a chave pública do eleitor
blindFactorBytes, err := blindFactor.MarshalBinary()
if err != nil {
fmt.Println("Error serializing blind factor:", err)
os.Exit(1)
}
responseBytes, err := response.MarshalBinary()
if err != nil {
fmt.Println("Error serializing response:", err)
os.Exit(1)
}
challengeBytes, err := challenge.MarshalBinary()
if err != nil {
fmt.Println("Error serializing challenge:", err)
os.Exit(1)
}
C1, C2, encryptedBlindFactor := encryptBLS(string(blindFactorBytes), userPublicKey, myHash)
serializedBlindFactor, err := serializeToASN1BLS(C1, C2, encryptedBlindFactor)
if err != nil {
log.Fatal("Failed to serialize encrypted blind factor: " + err.Error())
}
// Exibir resultados
// fmt.Printf("HashG1("+inputdesc+")= %x\n", originalG1.Bytes())
fmt.Printf("Encrypted_Blind_Factor= %x\n", serializedBlindFactor)
fmt.Println("Blind_Message=", hex.EncodeToString(blindedMessage.Bytes()))
// Prova de conhecimento
fmt.Printf("Commitment= %x\n", commitment.Bytes())
fmt.Printf("Challenge= %x\n", challengeBytes)
fmt.Printf("Response= %x\n", responseBytes)
} else if *pkey == "aggregate-vote-audit" {
// Carregar chave secreta de assinatura (BLS)
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Ler a mensagem (voto)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Aplicar cegamento ao voto
originalG1 := hashToG1(msg)
blindFactor := generateBlindFactor()
blindedMessage := blindMessage(originalG1, blindFactor)
// Se candidatos forem fornecidos, calcular HashG1 de cada um e comparar
if *candidates != "" {
candidatesList := strings.Split(*candidates, ",")
var matchFound bool
// Iterar sobre cada candidato e calcular seu HashG1
for _, candidate := range candidatesList {
candidate = strings.TrimSpace(candidate)
candidateHash := hashToG1([]byte(candidate))
// Comparar o HashG1 do voto com o HashG1 do candidato
if bytes.Equal(originalG1.Bytes(), candidateHash.Bytes()) {
fmt.Println("Vote matches one of the candidates.")
matchFound = true
/*
// Criando o compromisso do comando
fullCommand := fmt.Sprintf("edgetk -pkey %s -key %s -pub %s -id %s -md %s -candidates %s -signature %s vote.txt",
*pkey, *key, *pub, *id, *md, *candidates, *sig)
commandHash := bmw.Sum256([]byte(fullCommand))
*/
commandHash := bmw.Sum256([]byte(*candidates))
// Aqui, assine o hash do comando com a chave secreta
commandSignature := signMessageBLS(commandHash[:], skScalar)
// Exibir a assinatura
fmt.Println("Command_Signature("+*candidates+")=", hex.EncodeToString(commandSignature.BytesCompressed()))
break
}
}
if !matchFound {
fmt.Println("Vote does not match any provided candidates.")
os.Exit(1)
}
}
// Assinar a mensagem cegada (BLS)
blindedSignature := signMessageBLS(blindedMessage.Bytes(), skScalar)
fmt.Println("Blinded_Signature("+inputdesc+")=", hex.EncodeToString(blindedSignature.BytesCompressed()))
// Gerar compromisso para a chave secreta (skScalar)
commitment := generateCommitment(randomScalar(), bls12381.G2Generator())
challenge := generateChallenge(commitment, msg)
response := generateResponse(skScalar, challenge)
// Agregar assinaturas cegas
aggregatedSignature := blindedSignature
if *sig != "" {
fmt.Printf("Previous= %s\n", *sig)
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing signature: %v", err)
}
// Agregar assinaturas cegas
aggregatedSignature = aggregateSignatures([]*bls12381.G1{signatureCopy, blindedSignature})
fmt.Println("Aggregated_Blinded=", hex.EncodeToString(aggregatedSignature.BytesCompressed()))
}
// fmt.Println("Aggregated_Blinded=", hex.EncodeToString(aggregatedSignature.BytesCompressed()))
// Criptografar o blind factor com IBE
// Carregar chave pública mestra
masterPubKeyBytes, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading master public key:", err)
os.Exit(1)
}
var masterPubKey bls12381.G2
err = masterPubKey.SetBytes(masterPubKeyBytes)
if err != nil {
log.Fatalf("Error deserializing master public key: %v", err)
}
// Gerar chave pública do eleitor com base no ID
userPublicKey := generatePublicKeyForUserBLS(&masterPubKey, *id)
// Gerar chave pública da autoridade auditora
auditPublicKey := generatePublicKeyForUserBLS(&masterPubKey, "audit")
// Criptografar o fator de cegamento com a chave pública do eleitor
blindFactorBytes, err := blindFactor.MarshalBinary()
if err != nil {
fmt.Println("Error serializing blind factor:", err)
os.Exit(1)
}
responseBytes, err := response.MarshalBinary()
if err != nil {
fmt.Println("Error serializing response:", err)
os.Exit(1)
}
challengeBytes, err := challenge.MarshalBinary()
if err != nil {
fmt.Println("Error serializing challenge:", err)
os.Exit(1)
}
C1, C2, encryptedBlindFactor := encryptBLS(string(blindFactorBytes), userPublicKey, myHash)
serializedBlindFactor1, err := serializeToASN1BLS(C1, C2, encryptedBlindFactor)
if err != nil {
log.Fatal("Failed to serialize encrypted blind factor: " + err.Error())
}
C1, C2, encryptedBlindFactor = encryptBLS(string(blindFactorBytes), auditPublicKey, myHash)
serializedBlindFactor2, err := serializeToASN1BLS(C1, C2, encryptedBlindFactor)
if err != nil {
log.Fatal("Failed to serialize encrypted blind factor: " + err.Error())
}
// Exibir resultados
// fmt.Printf("HashG1("+inputdesc+")= %x\n", originalG1.Bytes())
fmt.Printf("Blind_Factor(%s)= %x\n", *id, serializedBlindFactor1)
fmt.Printf("Blind_Factor(auditor)= %x\n", serializedBlindFactor2)
fmt.Println("Blind_Message=", hex.EncodeToString(blindedMessage.Bytes()))
// Prova de conhecimento
fmt.Printf("Commitment= %x\n", commitment.Bytes())
fmt.Printf("Challenge= %x\n", challengeBytes)
fmt.Printf("Response= %x\n", responseBytes)
} else if *pkey == "verify-proof" {
// Load public key
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
// Desserializar chave pública
var pubKey bls12381.G2
pubKey.SetBytes(pk)
publicKey := generatePublicKeyForUserBLS(&pubKey, *id)
// Carregar o compromisso, desafio e resposta a partir dos flags
commitment := new(bls12381.G2)
challenge := new(ff.Scalar)
response := new(ff.Scalar)
// Desserializar commitment
commitmentBytes, err := hex.DecodeString(*commitmentFlag)
if err != nil {
log.Fatalf("Error decoding commitment: %v", err)
}
err = commitment.SetBytes(commitmentBytes)
if err != nil {
log.Fatalf("Error deserializing commitment: %v", err)
}
// Carregar challenge
challengeBytes, err := hex.DecodeString(*challengeFlag)
if err != nil {
log.Fatalf("Error decoding challenge: %v", err)
}
challenge.SetBytes(challengeBytes)
// Carregar response
responseBytes, err := hex.DecodeString(*responseFlag)
if err != nil {
log.Fatalf("Error decoding response: %v", err)
}
response.SetBytes(responseBytes)
isValid := verifyProof(commitment, challenge, response, publicKey)
if isValid {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
} else if *pkey == "verify-aggregate-vote" {
// Verificar se o número de chaves públicas e mensagens são iguais
if len(pubs) != len(msgs) {
log.Fatal("The number of public keys and messages must be the same.")
}
// Carregar chave pública mestra
pubMasterKeyBytes, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading master public key:", err)
os.Exit(1)
}
// Desserializar chave pública mestra
var masterPubKey bls12381.G2
masterPubKey.SetBytes(pubMasterKeyBytes)
// Carregar chaves públicas dos usuários a partir dos UIDs
var pubKeys []*bls12381.G2
for _, userID := range pubs {
pubKey := generatePublicKeyForUserBLS(&masterPubKey, userID)
pubKeys = append(pubKeys, pubKey)
}
// Carregar as mensagens cegadas (que foram assinadas)
var blindedMessages []*bls12381.G1
for _, msgPath := range msgs {
// Ler o arquivo de mensagem (contendo o conteúdo em hexadecimal)
blindedMessageHex, err := ioutil.ReadFile(msgPath)
if err != nil {
log.Fatalf("Error loading message %s: %v", msgPath, err)
}
// Remover espaços em branco, novas linhas e qualquer nova linha extra no final
cleanedHex := strings.ReplaceAll(string(blindedMessageHex), "\n", "")
cleanedHex = strings.ReplaceAll(cleanedHex, "\r", "")
cleanedHex = strings.ReplaceAll(cleanedHex, " ", "")
// Verificar e remover o último caractere (se for nova linha)
if len(cleanedHex) > 0 && cleanedHex[len(cleanedHex)-1] == 'a' {
cleanedHex = cleanedHex[:len(cleanedHex)-1]
}
// Decodificar o conteúdo hexadecimal para bytes
blindedMessageBytes, err := hex.DecodeString(cleanedHex)
if err != nil {
log.Fatalf("Error decoding hexadecimal message from file %s: %v", msgPath, err)
}
// Transformar os bytes em um ponto G1
blindedG1 := new(bls12381.G1)
err = blindedG1.SetBytes(blindedMessageBytes)
if err != nil {
log.Fatalf("Error deserializing blinded message into G1: %v", err)
}
// Adicionar a mensagem cegada à lista
blindedMessages = append(blindedMessages, blindedG1)
}
// Desserializar a assinatura agregada cega
sigBytes, err := hex.DecodeString(*sig)
if err != nil {
fmt.Println("Error decoding the signature:", err)
os.Exit(1)
}
signatureCopy := new(bls12381.G1)
err = signatureCopy.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Error deserializing the signature: %v", err)
}
// Verificar a assinatura agregada dos votos cegados
valid := verifyAggregateSignatureVote(blindedMessages, signatureCopy, pubKeys)
if valid {
fmt.Println("Vote Verified: true")
} else {
fmt.Println("Vote Verified: false")
os.Exit(1)
}
os.Exit(0)
} else if *pkey == "aggregate-signatures" {
signatures := []*bls12381.G1{}
// Separar as assinaturas por vírgulas
sigList := strings.Split(*sig, ",")
for _, sigHex := range sigList {
sigHex = strings.TrimSpace(sigHex) // Remover espaços extras
sigBytes, err := hex.DecodeString(sigHex)
if err != nil {
fmt.Println("Erro ao decodificar assinatura:", err)
os.Exit(1)
}
signature := new(bls12381.G1)
err = signature.SetBytes(sigBytes)
if err != nil {
log.Fatalf("Erro ao desserializar assinatura: %v", err)
}
signatures = append(signatures, signature)
}
// Agregar assinaturas
aggregatedSignature := aggregateSignatures(signatures)
// Exibir assinatura agregada
fmt.Println("Aggregated_Signature=", hex.EncodeToString(aggregatedSignature.BytesCompressed()))
} else if *pkey == "input" {
// Prompt the user for the vote to be entered (using gopass to hide the input)
fmt.Print("Enter the desired vote: ")
vote, _ := gopass.GetPasswd()
// Open the input file to overwrite its content
file, err := os.OpenFile(flag.Arg(0), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Fatalf("Error opening file to update vote: %v", err)
}
defer file.Close()
// Write the vote to the file (overwriting the content)
_, err = file.Write([]byte(fmt.Sprintf("%s", vote)))
if err != nil {
log.Fatalf("Error writing vote to file: %v", err)
}
// Confirm the vote has been correctly entered
fmt.Println("Vote successfully recorded in the file.")
} else if *pkey == "count" {
// Ensure that candidates are correctly defined
candidateList := strings.Split(*candidates, ",")
// Sort candidates in alphabetical order
sort.Strings(candidateList)
if *votesFlag == "" {
log.Fatal("No vote file provided.")
}
data, err := ioutil.ReadFile(*votesFlag)
if err != nil {
log.Fatalf("Error reading vote file: %v", err)
}
if len(data) == 0 {
log.Println("The vote file is empty.")
return
}
decodedVotes, err := decodeVotesFromASN1(strings.TrimSpace(string(data)))
if err != nil {
log.Fatalf("Error decoding votes: %v", err)
}
fmt.Println("Votes successfully confirmed.")
fmt.Println("Votes decoded successfully!")
// Convert the stored votes from []byte to []*bls12381.G1
var decodedG1Votes []*bls12381.G1
for i, voteBytes := range decodedVotes.Votes {
g1Vote := new(bls12381.G1)
err := g1Vote.SetBytes(voteBytes)
if err != nil {
log.Fatalf("Error converting vote to G1: %v", err)
}
decodedG1Votes = append(decodedG1Votes, g1Vote)
// Display the decoded G1 values
fmt.Printf("Vote %d: %x\n", i+1, g1Vote.Bytes())
}
// Decode the votes and obtain the count for each candidate
decodedVoteCounts := decodeSum(decodedG1Votes)
// Initialize the map to count votes by candidate
voteMap := make(map[string]int)
totalVotes := 0
// Count votes for each candidate
for i, count := range decodedVoteCounts {
if i < len(candidateList) {
candidate := candidateList[i]
voteMap[candidate] = count
totalVotes += count
}
}
// Sort candidates in alphabetical order
sortedCandidates := make([]string, 0, len(voteMap))
for candidate := range voteMap {
sortedCandidates = append(sortedCandidates, candidate)
}
sort.Strings(sortedCandidates)
// Calculate the maximum candidate name length to align columns
maxCandidateLength := 5
for _, candidate := range sortedCandidates {
if len(candidate) > maxCandidateLength {
maxCandidateLength = len(candidate)
}
}
// Ensure the vote column is at least 3 characters wide
voteColumnWidth := 3
for _, candidate := range sortedCandidates {
candidateVotes := voteMap[candidate]
voteLength := len(fmt.Sprintf("%d", candidateVotes))
if voteLength > voteColumnWidth {
voteColumnWidth = voteLength
}
}
// Calculate the total table width
tableWidth := maxCandidateLength + voteColumnWidth + 3
// Display results with table formatting
separator := strings.Repeat("=", tableWidth)
fmt.Println(separator)
fmt.Println("Result")
fmt.Println(separator)
for _, candidate := range sortedCandidates {
count := voteMap[candidate]
fmt.Printf("%-*s : %*d\n", maxCandidateLength, candidate, voteColumnWidth, count)
}
// Display total votes, ensuring consistent width
fmt.Println(strings.Repeat("-", tableWidth))
fmt.Printf("%-*s : %*d\n", maxCandidateLength, "Total", voteColumnWidth, totalVotes)
} else if *pkey == "count-total" {
// Ensure that candidates are correctly defined
candidateList := strings.Split(*candidates, ",")
// Sort candidates in alphabetical order
sort.Strings(candidateList)
if *votesFlag == "" {
log.Fatal("No vote file provided.")
}
// Read the vote files passed as parameters
voteFiles := strings.Split(*votesFlag, ",")
var allDecodedVotes [][]*bls12381.G1
for _, voteFile := range voteFiles {
data, err := ioutil.ReadFile(strings.TrimSpace(voteFile))
if err != nil {
log.Fatalf("Error reading vote file %s: %v", voteFile, err)
}
if len(data) == 0 {
log.Printf("The vote file %s is empty.", voteFile)
continue
}
decodedVotes, err := decodeVotesFromASN1(strings.TrimSpace(string(data)))
if err != nil {
log.Fatalf("Error decoding votes from file %s: %v", voteFile, err)
}
voteGroups := make([][]*bls12381.G1, len(decodedVotes.Votes)/len(candidateList))
for i := range voteGroups {
voteGroups[i] = make([]*bls12381.G1, len(candidateList))
for j := 0; j < len(candidateList); j++ {
voteGroups[i][j] = new(bls12381.G1)
err := voteGroups[i][j].SetBytes(decodedVotes.Votes[i*len(candidateList)+j])
if err != nil {
log.Fatalf("Error converting vote to G1: %v", err)
}
}
}
allDecodedVotes = append(allDecodedVotes, voteGroups...)
}
// Sum all the decoded votes
sums := addVotes(allDecodedVotes)
// Decode the sum
decodedVoteCounts := decodeSum(sums)
// Initialize the map to count votes by candidate
voteMap := make(map[string]int)
totalVotes := 0
// Count votes for each candidate
for i, count := range decodedVoteCounts {
if i < len(candidateList) {
candidate := candidateList[i]
voteMap[candidate] = count
totalVotes += count
}
}
// Sort candidates in alphabetical order
sortedCandidates := make([]string, 0, len(voteMap))
for candidate := range voteMap {
sortedCandidates = append(sortedCandidates, candidate)
}
sort.Strings(sortedCandidates)
// Calculate the maximum candidate name length to align columns
maxCandidateLength := 5
for _, candidate := range sortedCandidates {
if len(candidate) > maxCandidateLength {
maxCandidateLength = len(candidate)
}
}
// Calculate the width of the largest vote number
voteColumnWidth := 3
for _, candidate := range sortedCandidates {
candidateVotes := voteMap[candidate]
voteLength := len(fmt.Sprintf("%d", candidateVotes))
if voteLength > voteColumnWidth {
voteColumnWidth = voteLength
}
}
// Calculate the total table width
tableWidth := maxCandidateLength + voteColumnWidth + 3
// Display results with table formatting
separator := strings.Repeat("=", tableWidth)
fmt.Println(separator)
fmt.Println("Final Result")
fmt.Println(separator)
for _, candidate := range sortedCandidates {
count := voteMap[candidate]
fmt.Printf("%-*s : %*d\n", maxCandidateLength, candidate, voteColumnWidth, count)
}
// Display total votes, ensuring consistent width
fmt.Println(strings.Repeat("-", tableWidth))
fmt.Printf("%-*s : %*d\n", maxCandidateLength, "Total", voteColumnWidth, totalVotes)
} else if *pkey == "add" {
candidateList := strings.Split(*candidates, ",")
if len(candidateList) < 1 {
log.Fatal("Invalid candidate list.")
}
// Sort candidates in alphabetical order
sort.Strings(candidateList)
if *votesFlag == "" {
log.Fatal("Please specify the files correctly.")
}
var decodedVotes *EncodedVotes
if data, err := ioutil.ReadFile(*votesFlag); err == nil && len(data) > 0 {
decodedVotes, err = decodeVotesFromASN1(strings.TrimSpace(string(data)))
if err != nil {
log.Fatalf("Error decoding existing votes: %v", err)
}
}
newVoteData, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatalf("Error reading vote file: %v", err)
}
newVote := strings.TrimSpace(string(newVoteData))
encodedNewVote := encodeVote(newVote, candidateList)
var allVotes [][]*bls12381.G1
if decodedVotes != nil {
existingVoteGroups := make([][]*bls12381.G1, len(decodedVotes.Votes)/len(candidateList))
for i := range existingVoteGroups {
existingVoteGroups[i] = make([]*bls12381.G1, len(candidateList))
for j := 0; j < len(candidateList); j++ {
existingVoteGroups[i][j] = new(bls12381.G1)
err := existingVoteGroups[i][j].SetBytes(decodedVotes.Votes[i*len(candidateList)+j])
if err != nil {
log.Fatalf("Error converting vote to G1: %v", err)
}
}
}
allVotes = append(allVotes, existingVoteGroups...)
}
allVotes = append(allVotes, encodedNewVote)
updatedEnc, err := encodeVotesToASN1(addVotes(allVotes))
if err != nil {
log.Fatalf("Error encoding votes: %v", err)
}
if err := ioutil.WriteFile(*votesFlag, []byte(updatedEnc), 0644); err != nil {
log.Fatalf("Error saving votes: %v", err)
}
fmt.Println("Vote successfully added!")
} else if *pkey == "sum" {
candidateList := strings.Split(*candidates, ",")
if len(candidateList) < 1 {
log.Fatal("Invalid candidate list.")
}
// Sort candidates in alphabetical order
sort.Strings(candidateList)
if *votesFlag == "" {
log.Fatal("Please specify the files correctly.")
}
// Read the vote files passed as parameters
voteFiles := strings.Split(*votesFlag, ",")
var allDecodedVotes [][]*bls12381.G1
// Process each vote file
for _, voteFile := range voteFiles {
data, err := ioutil.ReadFile(strings.TrimSpace(voteFile))
if err != nil {
log.Fatalf("Error reading vote file %s: %v", voteFile, err)
}
if len(data) == 0 {
log.Printf("The vote file %s is empty.", voteFile)
continue
}
// Decode votes from each file
decodedVotes, err := decodeVotesFromASN1(strings.TrimSpace(string(data)))
if err != nil {
log.Fatalf("Error decoding votes from file %s: %v", voteFile, err)
}
// Organize votes into groups
voteGroups := make([][]*bls12381.G1, len(decodedVotes.Votes)/len(candidateList))
for i := range voteGroups {
voteGroups[i] = make([]*bls12381.G1, len(candidateList))
for j := 0; j < len(candidateList); j++ {
voteGroups[i][j] = new(bls12381.G1)
err := voteGroups[i][j].SetBytes(decodedVotes.Votes[i*len(candidateList)+j])
if err != nil {
log.Fatalf("Error converting vote to G1: %v", err)
}
}
}
allDecodedVotes = append(allDecodedVotes, voteGroups...)
}
// Sum all the decoded votes
sums := addVotes(allDecodedVotes)
// Save the sum result in the specified file
encodedSum, err := encodeVotesToASN1(sums)
if err != nil {
log.Fatalf("Error encoding vote sum: %v", err)
}
// Display the final result
fmt.Println(encodedSum)
} else if *pkey == "hash" {
// Ler a mensagem (voto)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Cegar a mensagem
originalG1 := hashToG1(msg)
fmt.Printf("HashG1("+inputdesc+")= %x\n", originalG1.Bytes())
} else if *pkey == "blind" {
// Decode the blinding factor (hex to ff.Scalar)
blindFactorBytes, err := hex.DecodeString(*factorb)
if err != nil {
fmt.Println("Error decoding blinding factor:", err)
os.Exit(1)
}
blindFactor := new(ff.Scalar)
err = blindFactor.UnmarshalBinary(blindFactorBytes)
if err != nil {
fmt.Println("Error deserializing blinding factor:", err)
os.Exit(1)
}
// Ler a mensagem (voto)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error loading input file:", err)
os.Exit(1)
}
// Cegar a mensagem
originalG1 := hashToG1(msg)
blindedMessage := blindMessage(originalG1, blindFactor)
fmt.Printf("Blind= %x\n", blindedMessage.Bytes())
} else if *pkey == "unblind" {
// handleUnblindMessageCommand()
// Check if required flags are set
if *factorb == "" {
fmt.Println("You must provide the blinding factor.")
os.Exit(1)
}
// Decode the blinding factor (hex to ff.Scalar)
blindFactorBytes, err := hex.DecodeString(*factorb)
if err != nil {
fmt.Println("Error decoding blinding factor:", err)
os.Exit(1)
}
blindFactor := new(ff.Scalar)
err = blindFactor.UnmarshalBinary(blindFactorBytes)
if err != nil {
fmt.Println("Error deserializing blinding factor:", err)
os.Exit(1)
}
// Ler o arquivo de mensagem (contendo o conteúdo em hexadecimal)
blindedMessageHex, err := ioutil.ReadAll(inputfile)
if err != nil {
log.Fatalf("Error loading message %s: %v", inputfile, err)
}
// Remover espaços em branco, novas linhas e qualquer nova linha extra no final
cleanedHex := strings.ReplaceAll(string(blindedMessageHex), "\n", "")
cleanedHex = strings.ReplaceAll(cleanedHex, "\r", "")
cleanedHex = strings.ReplaceAll(cleanedHex, " ", "")
// Verificar e remover o último caractere (se for nova linha)
if len(cleanedHex) > 0 && cleanedHex[len(cleanedHex)-1] == 'a' {
cleanedHex = cleanedHex[:len(cleanedHex)-1]
}
// Decodificar o conteúdo hexadecimal para bytes
blindedMessageBytes, err := hex.DecodeString(cleanedHex)
if err != nil {
log.Fatalf("Error decoding hexadecimal message from file %s: %v", inputfile, err)
}
blindedMessage := new(bls12381.G1)
err = blindedMessage.SetBytes(blindedMessageBytes)
if err != nil {
fmt.Println("Error deserializing blinded message in G1:", err)
os.Exit(1)
}
// Unblind the message
originalMessage := unblindMessage(blindedMessage, blindFactor)
// Display the unblinded message
fmt.Printf("HashG1= %x\n", originalMessage.Bytes())
if *candidates != "" {
// Split the candidates into a list
candidatesList := strings.Split(*candidates, ",")
// Iterate through the candidates and compare their G1 hash with the unblinded message
for _, candidate := range candidatesList {
// Convert the candidate string to G1 using hashToG1
hashOfCandidateG1 := hashToG1([]byte(candidate))
// Compare the hash of the candidate with the unblinded message's HashG1
if originalMessage.IsEqual(hashOfCandidateG1) {
// If they match, display the selected candidate
fmt.Printf("Selected candidate: %s\n", candidate)
return
}
}
// If no match is found, inform that no candidate matches the unblinded message
fmt.Println("No matching candidate found.")
}
} else if *pkey == "derive" && *pub2 == "" {
// Load secret key BN256
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Carregar chave pública
pk, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública em um ponto do grupo G2
var pubKey bls12381.G2
err = pubKey.SetBytes(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
// Gerar as chaves públicas para cada usuário
publicKey := generatePublicKeyForUserBLS(&pubKey, *id)
// Calcular a chave secreta compartilhada entre os dois usuários usando o emparelhamento bilinear
sharedSecret := computeSharedSecretBLS(skScalar, publicKey)
sharedSecretBytes, err := sharedSecret.MarshalBinary()
if err != nil {
log.Fatalf("Error serializing shared secret: %v", err)
}
// Imprimir a chave compartilhada gerada
// fmt.Printf("Shared= %x\n", sharedSecretBytes)
fmt.Printf("Shared= %x\n", bmw.Sum256(sharedSecretBytes))
} else if *pkey == "derive" && *pub2 != "" {
// Load secret key BN256
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skScalar := new(ff.Scalar)
skScalar.SetBytes(sk)
// Read pk1 from G1
pk1Bytes, err := readKeyFromPEM(*pub, false)
if err != nil {
fmt.Println("Error loading public key G1:", err)
os.Exit(1)
}
var pubKey1 bls12381.G1
if err := pubKey1.SetBytes(pk1Bytes); err != nil {
log.Fatalf("Error deserializing public key G1: %v", err)
}
// Read pk2 from G2
pk2Bytes, err := readKeyFromPEM(*pub2, false)
if err != nil {
fmt.Println("Error loading public key G2:", err)
os.Exit(1)
}
var pubKey2 bls12381.G2
if err := pubKey2.SetBytes(pk2Bytes); err != nil {
log.Fatalf("Error deserializing public key G2: %v", err)
}
// Generate the public key for each user
publicKey1 := generatePublicKeyForUserBLSG1(&pubKey1, *id)
publicKey2 := generatePublicKeyForUserBLS(&pubKey2, *id2)
// Compute the shared secret using bilinear pairing
sharedSecret := bls12381.Pair(publicKey1, publicKey2)
sharedSecret.Exp(sharedSecret, skScalar)
// Serialize the shared secrets
sharedSecretBytes, err := sharedSecret.MarshalBinary()
if err != nil {
log.Fatalf("Error serializing shared secret G1: %v", err)
}
// Print the hashed shared secrets
fmt.Printf("Shared= %x\n", bmw.Sum256(sharedSecretBytes))
} else if *pkey == "encrypt" {
// Carregar chave pública
pk, err := readKeyFromPEM(*key, false)
if err != nil {
fmt.Println("Error loading public key:", err)
os.Exit(1)
}
// Desserializar chave pública em um ponto do grupo G2
var pubKey bls12381.G2
err = pubKey.SetBytes(pk)
if err != nil {
log.Fatalf("Error deserializing public key: %v", err)
}
userPublicKey := generatePublicKeyForUserBLS(&pubKey, *id)
msg, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
C1, C2, encryptedMessage := encryptBLS(string(msg), userPublicKey, myHash)
serialized, err := serializeToASN1BLS(C1, C2, encryptedMessage)
if err != nil {
log.Fatal("Failed to serialize ciphertext: " + err.Error())
}
fmt.Printf("%s", serialized)
} else if *pkey == "decrypt" {
// Load secret key BN256
sk, err := readKeyFromPEM(*key, true)
if err != nil {
fmt.Println("Error loading key:", err)
os.Exit(1)
}
skBigInt := new(big.Int).SetBytes(sk)
serialized, err := ioutil.ReadAll(inputfile)
if err != nil {
fmt.Println("Error getting input file:", err)
os.Exit(1)
}
deserializedC1, deserializedC2, deserializedMessage, err := deserializeFromASN1BLS(serialized)
if err != nil {
log.Fatal("Failed to deserialize ciphertext: " + err.Error())
}
// Decrypt the message
decryptedMessage := decryptBLS(deserializedC1, deserializedC2, deserializedMessage, skBigInt, myHash)
fmt.Printf("%s", decryptedMessage)
}
}
if *pkey == "modulus" && (strings.ToUpper(*alg) == "SM9SIGN" || strings.ToUpper(*alg) == "SM9ENCRYPT") && (PEM == "Master" || PEM == "Private") {
keyFileContent, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal("Error reading key file:", err)
}
keyBlock, _ := pem.Decode(keyFileContent)
if keyBlock == nil {
log.Fatal("Failed to decode PEM block containing the private key.")
}
var privPEM []byte
if IsEncryptedPEMBlock(keyBlock) {
privKeyBytes, err := DecryptPEMBlock(keyBlock, []byte(*pwd))
if err != nil {
log.Fatal("Error decrypting private key:", err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "SM9 PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = keyFileContent
}
var privateKeyPemBlock *pem.Block
privateKeyPemBlock, _ = pem.Decode(privPEM)
privateKey, err := smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal("Error parsing private key:", err)
}
switch keyType := privateKey.(type) {
case *sm9.EncryptPrivateKey:
fmt.Printf("Public=%X\n", keyType.MasterPublicKey.Marshal())
case *sm9.SignPrivateKey:
fmt.Printf("Public=%X\n", keyType.MasterPublicKey.Marshal())
case *sm9.EncryptMasterPrivateKey:
fmt.Printf("Public=%X\n", keyType.MasterPublicKey.Marshal())
case *sm9.SignMasterPrivateKey:
fmt.Printf("Public=%X\n", keyType.MasterPublicKey.Marshal())
default:
log.Fatal("Invalid private key type. Expected sm9.EncryptPrivateKey, or sm9.SignPrivateKey.")
}
}
if *pkey == "modulus" && (strings.ToUpper(*alg) == "SM9SIGN") && (PEM == "Public") {
keyFileContent, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal("Error reading key file:", err)
}
keyBlock, _ := pem.Decode(keyFileContent)
if keyBlock == nil {
log.Fatal("Failed to decode PEM block containing the public key.")
}
pubKey := new(sm9.SignMasterPublicKey)
err = pubKey.UnmarshalASN1(keyBlock.Bytes)
if err != nil {
fmt.Println("Error parsing public key with UnmarshalASN1:", err)
return
}
fmt.Printf("Public=%X\n", pubKey.MasterPublicKey.Marshal())
os.Exit(0)
}
if *pkey == "modulus" && (strings.ToUpper(*alg) == "SM9ENCRYPT") && (PEM == "Public") {
keyFileContent, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal("Error reading key file:", err)
}
keyBlock, _ := pem.Decode(keyFileContent)
if keyBlock == nil {
log.Fatal("Failed to decode PEM block containing the public key.")
}
pubKey := new(sm9.EncryptMasterPublicKey)
err = pubKey.UnmarshalASN1(keyBlock.Bytes)
if err != nil {
fmt.Println("Error parsing public key with UnmarshalASN1:", err)
return
}
fmt.Printf("Public=%X\n", pubKey.MasterPublicKey.Marshal())
os.Exit(0)
}
if *pkey == "text" && (strings.ToUpper(*alg) == "SM9SIGN" || strings.ToUpper(*alg) == "SM9ENCRYPT") && (PEM == "Master" || PEM == "Private") {
keyFileContent, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal("Error reading key file:", err)
}
keyBlock, _ := pem.Decode(keyFileContent)
if keyBlock == nil {
log.Fatal("Failed to decode PEM block containing the private key.")
}
var privPEM []byte
var privateKeyPemBlock *pem.Block
var privKeyBytes []byte
if IsEncryptedPEMBlock(keyBlock) {
privKeyBytes, err = DecryptPEMBlock(keyBlock, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
if PEM == "Master" && strings.ToUpper(*alg) == "SM9ENCRYPT" {
privPEM = pem.EncodeToMemory(&pem.Block{Type: "SM9 ENC MASTER KEY", Bytes: privKeyBytes})
} else if PEM == "Master" && strings.ToUpper(*alg) == "SM9SIGN" {
privPEM = pem.EncodeToMemory(&pem.Block{Type: "SM9 SIGN MASTER KEY", Bytes: privKeyBytes})
} else if PEM == "Private" && strings.ToUpper(*alg) == "SM9ENCRYPT" {
privPEM = pem.EncodeToMemory(&pem.Block{Type: "SM9 ENC PRIVATE KEY", Bytes: privKeyBytes})
} else if PEM == "Private" && strings.ToUpper(*alg) == "SM9SIGN" {
privPEM = pem.EncodeToMemory(&pem.Block{Type: "SM9 SIGN PRIVATE KEY", Bytes: privKeyBytes})
}
} else {
privPEM = keyFileContent
}
privateKeyPemBlock, _ = pem.Decode(privPEM)
privateKey, err := smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal("Error parsing private key:", err)
}
fmt.Print(string(privPEM))
switch keyType := privateKey.(type) {
case *sm9.EncryptPrivateKey:
fmt.Println("Encrypt Private-Key: (256-bit)")
fmt.Println("priv:")
privKeyHex := fmt.Sprintf("%x", keyType.PrivateKey.Marshal())
splitz := SplitSubN(privKeyHex, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("pub:")
pubKeyHex := fmt.Sprintf("%x", keyType.MasterPublicKey.Marshal())
splitz = SplitSubN(pubKeyHex, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Curve: sm9p256v1")
case *sm9.SignPrivateKey:
fmt.Println("Sign Private-Key: (256-bit)")
fmt.Println("priv:")
privKeyHex := fmt.Sprintf("%x", keyType.PrivateKey.Marshal())
splitz := SplitSubN(privKeyHex, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("pub:")
pubKeyHex := fmt.Sprintf("%x", keyType.MasterPublicKey.Marshal())
splitz = SplitSubN(pubKeyHex, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Curve: sm9p256v1")
case *sm9.EncryptMasterPrivateKey:
fmt.Println("Encrypt Master-Key: (256-bit)")
fmt.Println("master:")
privKeyHex, err := keyType.MarshalASN1()
if err != nil {
log.Fatal(err)
}
splitz := SplitSubN(hex.EncodeToString(privKeyHex), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("pub:")
pubKeyHex := fmt.Sprintf("%x", keyType.MasterPublicKey.Marshal())
splitz = SplitSubN(pubKeyHex, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Curve: sm9p256v1")
case *sm9.SignMasterPrivateKey:
fmt.Println("Sign Master-Key: (256-bit)")
fmt.Println("master:")
privKeyHex, err := keyType.MarshalASN1()
if err != nil {
log.Fatal(err)
}
splitz := SplitSubN(hex.EncodeToString(privKeyHex), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("pub:")
pubKeyHex := fmt.Sprintf("%x", keyType.MasterPublicKey.Marshal())
splitz = SplitSubN(pubKeyHex, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Curve: sm9p256v1")
default:
log.Fatal("Invalid private key type. Expected sm9.EncryptPrivateKey, or sm9.SignPrivateKey.")
}
}
if *pkey == "text" && (strings.ToUpper(*alg) == "SM9SIGN") && (PEM == "Public") {
keyFileContent, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal("Error reading key file:", err)
}
keyBlock, _ := pem.Decode(keyFileContent)
if keyBlock == nil {
log.Fatal("Failed to decode PEM block containing the public key.")
}
pubKey := new(sm9.SignMasterPublicKey)
err = pubKey.UnmarshalASN1(keyBlock.Bytes)
if err != nil {
fmt.Println("Error parsing public key with UnmarshalASN1:", err)
return
}
fmt.Print(string(keyFileContent))
fmt.Println("Sign Public-Key: (256-bit)")
fmt.Println("pub:")
pubKeyHex := fmt.Sprintf("%x", pubKey.MasterPublicKey.Marshal())
splitz := SplitSubN(pubKeyHex, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Curve: sm9p256v1")
os.Exit(0)
}
if *pkey == "text" && (strings.ToUpper(*alg) == "SM9ENCRYPT") && (PEM == "Public") {
keyFileContent, err := ioutil.ReadFile(*key)
if err != nil {
log.Fatal("Error reading key file:", err)
}
keyBlock, _ := pem.Decode(keyFileContent)
if keyBlock == nil {
log.Fatal("Failed to decode PEM block containing the public key.")
}
pubKey := new(sm9.EncryptMasterPublicKey)
err = pubKey.UnmarshalASN1(keyBlock.Bytes)
if err != nil {
fmt.Println("Error parsing public key with UnmarshalASN1:", err)
return
}
fmt.Print(string(keyFileContent))
fmt.Println("Encrypt Public-Key: (256-bit)")
fmt.Println("pub:")
pubKeyHex := fmt.Sprintf("%x", pubKey.MasterPublicKey.Marshal())
splitz := SplitSubN(pubKeyHex, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("Curve: sm9p256v1")
os.Exit(0)
}
if *pkey == "randomart" && (strings.ToUpper(*alg) == "SM9SIGN") && (PEM == "Public") {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
randomArt := randomart.FromString(string(buf))
fmt.Fprintln(os.Stderr, "SM9 Sign (256-bit)")
println(randomArt)
os.Exit(0)
}
if *pkey == "randomart" && (strings.ToUpper(*alg) == "SM9ENCRYPT") && (PEM == "Public") {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
randomArt := randomart.FromString(string(buf))
fmt.Fprintln(os.Stderr, "SM9 Enc (256-bit)")
println(randomArt)
os.Exit(0)
}
if *pkey == "fingerprint" && (strings.ToUpper(*alg) == "SM9SIGN") && (PEM == "Public") {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint= ")
println(fingerprint)
os.Exit(0)
}
if *pkey == "fingerprint" && (strings.ToUpper(*alg) == "SM9ENCRYPT") && (PEM == "Public") {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint= ")
println(fingerprint)
os.Exit(0)
}
if *pkey == "certgen" && strings.ToUpper(*alg) == "GOST2012" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var priv interface{}
var block *pem.Block
block, _ = pem.Decode(buf)
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
priv, err = x509.ParsePKCS8PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
priv, err = x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
gost341012256Priv := priv.(*gost3410.PrivateKey)
gost341012256Pub := gost341012256Priv.Public()
keyUsage := x509.KeyUsageDigitalSignature
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 160)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %v", err)
}
if *subj == "" {
println("You are about to be asked to enter information \nthat will be incorporated into your certificate.")
scanner := bufio.NewScanner(os.Stdin)
print("Common Name: ")
scanner.Scan()
name = scanner.Text()
print("Country Name (2 letter code) [AU]: ")
scanner.Scan()
country = scanner.Text()
print("State or Province Name (full name) [Some-State]: ")
scanner.Scan()
province = scanner.Text()
print("Locality Name (eg, city): ")
scanner.Scan()
locality = scanner.Text()
print("Organization Name (eg, company) [Internet Widgits Pty Ltd]: ")
scanner.Scan()
organization = scanner.Text()
print("Organizational Unit Name (eg, section): ")
scanner.Scan()
organizationunit = scanner.Text()
print("Email Address []: ")
scanner.Scan()
email = scanner.Text()
print("StreetAddress: ")
scanner.Scan()
street = scanner.Text()
print("PostalCode: ")
scanner.Scan()
postalcode = scanner.Text()
print("SerialNumber: ")
scanner.Scan()
number = scanner.Text()
} else {
name, number, country, province, locality, organization, organizationunit, street, email, postalcode, err = parseSubjectString(*subj)
if err != nil {
log.Fatal(err)
}
}
var validity string
// Check if the 'days' flag was provided
if *days > 0 {
// If provided, use the value from the flag
validity = fmt.Sprintf("%d", *days)
} else {
// Otherwise, prompt the user for input
fmt.Print("Validity (in Days): ")
fmt.Scanln(&validity)
}
intVar, err := strconv.Atoi(validity)
if err != nil {
log.Fatal(err)
}
NotAfter := time.Now().AddDate(0, 0, intVar)
hasher := gost34112012256.New()
if _, err = hasher.Write(gost341012256Pub.(*gost3410.PublicKey).Raw()); err != nil {
log.Fatalln(err)
}
spki := hasher.Sum(nil)
spki = spki[:20]
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
},
EmailAddresses: []string{email},
SubjectKeyId: spki,
AuthorityKeyId: spki,
NotBefore: time.Now(),
NotAfter: NotAfter,
KeyUsage: keyUsage,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
PermittedDNSDomainsCritical: true,
DNSNames: []string{name},
/*
PermittedDNSDomainsCritical: true,
DNSNames: []string{ip.String()},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
*/
}
template.IsCA = true
template.KeyUsage |= x509.KeyUsageContentCommitment | x509.KeyUsageKeyEncipherment | x509.KeyUsageDataEncipherment | x509.KeyUsageKeyAgreement | x509.KeyUsageCertSign | x509.KeyUsageCRLSign
derBytes, err := x509.CreateCertificate(
rand.Reader,
&template, &template,
gost341012256Pub, &gost3410.PrivateKeyReverseDigest{Prv: gost341012256Priv},
)
if err != nil {
log.Println(err)
}
certfile, err := os.Create(*cert)
if err != nil {
log.Println(err)
}
pem.Encode(certfile, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
os.Exit(0)
}
if *pkey == "req" && *key != "" && strings.ToUpper(*alg) == "GOST2012" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
// var keyBytes interface{}
var block *pem.Block
block, _ = pem.Decode(buf)
var priva interface{}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
priva, err = x509.ParsePKCS8PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
priva, err = x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
// keyBytes = priva.(*gost3410.PrivateKey)
if *subj == "" {
println("You are about to be asked to enter information \nthat will be incorporated into your certificate.")
scanner := bufio.NewScanner(os.Stdin)
print("Common Name: ")
scanner.Scan()
name = scanner.Text()
print("Country Name (2 letter code) [AU]: ")
scanner.Scan()
country = scanner.Text()
print("State or Province Name (full name) [Some-State]: ")
scanner.Scan()
province = scanner.Text()
print("Locality Name (eg, city): ")
scanner.Scan()
locality = scanner.Text()
print("Organization Name (eg, company) [Internet Widgits Pty Ltd]: ")
scanner.Scan()
organization = scanner.Text()
print("Organizational Unit Name (eg, section): ")
scanner.Scan()
organizationunit = scanner.Text()
print("Email Address []: ")
scanner.Scan()
email = scanner.Text()
print("StreetAddress: ")
scanner.Scan()
street = scanner.Text()
print("PostalCode: ")
scanner.Scan()
postalcode = scanner.Text()
print("SerialNumber: ")
scanner.Scan()
number = scanner.Text()
} else {
name, number, country, province, locality, organization, organizationunit, street, email, postalcode, err = parseSubjectString(*subj)
if err != nil {
log.Fatal(err)
}
}
var sigalg x509.SignatureAlgorithm
if *length == 512 {
sigalg = x509.GOST512
} else {
sigalg = x509.GOST256
}
emailAddress := email
subj := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
rawSubj := subj.ToRDNSequence()
rawSubj = append(rawSubj, []pkix.AttributeTypeAndValue{
{Type: oidEmailAddress, Value: emailAddress},
})
asn1Subj, _ := asn1.Marshal(rawSubj)
var template x509.CertificateRequest
template = x509.CertificateRequest{
RawSubject: asn1Subj,
EmailAddresses: []string{emailAddress},
SignatureAlgorithm: sigalg,
}
var output *os.File
if *cert == "" {
output = os.Stdout
} else {
file, err := os.Create(*cert)
if err != nil {
log.Fatal(err)
}
defer file.Close()
output = file
}
csrBytes, _ := x509.CreateCertificateRequest(rand.Reader, &template, &gost3410.PrivateKeyReverseDigest{Prv: priva.(*gost3410.PrivateKey)})
pem.Encode(output, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes})
os.Exit(0)
}
if (*tcpip == "server" || *tcpip == "client") && strings.ToUpper(*alg) == "GOST2012" {
var certPEM []byte
var privPEM []byte
tls.GOSTInstall()
file, err := os.Open(*key)
if err != nil {
log.Println(err)
}
info, err := file.Stat()
if err != nil {
log.Println(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Println(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
file, err = os.Open(*cert)
if err != nil {
log.Println(err)
}
info, err = file.Stat()
if err != nil {
log.Println(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
certPEM = buf
if *tcpip == "server" {
cert, err := tls.X509KeyPair(certPEM, privPEM)
if err != nil {
log.Fatal(err)
}
cfg := tls.Config{Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequireAnyClientCert, MinVersion: tls.VersionTLS13, MaxVersion: tls.VersionTLS13}
cfg.Rand = rand.Reader
port := "8081"
if *iport != "" {
port = *iport
}
ln, err := tls.Listen("tcp", ":"+port, &cfg)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Server(TLS) up and listening on port "+port)
conn, err := ln.Accept()
if err != nil {
log.Println(err)
}
defer ln.Close()
tlscon := conn.(*tls.Conn)
err = tlscon.Handshake()
if err != nil {
log.Fatalf("server: handshake failed: %s", err)
} else {
log.Print("server: conn: Handshake completed")
}
state := tlscon.ConnectionState()
for _, v := range state.PeerCertificates {
derBytes, err := x509.MarshalPKIXPublicKey(v.PublicKey)
if err != nil {
log.Fatal(err)
}
pubPEM := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: derBytes})
fmt.Printf("%s\n", pubPEM)
}
go handleConnectionTLS(conn)
fmt.Println("Connection accepted")
for {
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Client response: " + string(message))
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
}
}
if *tcpip == "client" {
cert, err := tls.X509KeyPair(certPEM, privPEM)
if err != nil {
log.Fatal(err)
}
cfg := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
ipport := "127.0.0.1:8081"
if *iport != "" {
ipport = *iport
}
conn, err := tls.Dial("tcp", ipport, &cfg)
if err != nil {
log.Fatal(err)
}
certs := conn.ConnectionState().PeerCertificates
for _, cert := range certs {
fmt.Printf("Issuer: \n\t%s\n", cert.Issuer)
fmt.Printf("Subject: \n\t%s\n", cert.Subject)
fmt.Printf("Expiry: %s \n", cert.NotAfter.Format("Monday, 02-Jan-06 15:04:05 MST"))
}
if err != nil {
log.Fatal(err)
}
defer conn.Close()
var b bytes.Buffer
for _, cert := range conn.ConnectionState().PeerCertificates {
err := pem.Encode(&b, &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
})
if err != nil {
log.Println(err)
}
}
fmt.Println(b.String())
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Server response: " + message)
}
}
os.Exit(0)
}
if *pkey == "keygen" && strings.ToUpper(*alg) == "RSA" {
GenerateRsaKey(*length)
os.Exit(0)
}
if *pkey == "pkcs12" && *key != "" {
err := PfxGen()
if err != nil {
log.Fatal(err)
}
os.Exit(0)
}
if *pkey == "pkcs12" && *key == "" {
err := PfxParse()
if err != nil {
log.Fatal(err)
}
os.Exit(0)
}
if *pkey == "x509" && strings.ToUpper(*alg) != "GOST2012" {
err := csrToCrt()
if err != nil {
log.Fatal(err)
}
os.Exit(0)
}
if *pkey == "x509" && strings.ToUpper(*alg) == "GOST2012" {
err := csrToCrt2()
if err != nil {
log.Fatal(err)
}
os.Exit(0)
}
if *pkey == "sign" && *key == "" && strings.ToUpper(*alg) == "RSA" {
fmt.Fprintln(os.Stderr, "Usage:")
fmt.Fprintln(os.Stderr, os.Args[0]+" -pkey sign -key <privatekey.pem>")
os.Exit(1)
} else if *pkey == "sign" && *key != "" && strings.ToUpper(*alg) == "RSA" {
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
Data := string(buf.Bytes())
sourceData := []byte(Data)
signData, err := SignatureRSA(sourceData)
if err != nil {
fmt.Println("cryption error:", err)
os.Exit(1)
}
fmt.Println("RSA-"+strings.ToUpper(*md)+"("+inputdesc+")=", hex.EncodeToString(signData))
os.Exit(0)
}
if *pkey == "verify" && (*key == "" || *sig == "") && strings.ToUpper(*alg) == "RSA" {
fmt.Fprintln(os.Stderr, "Usage:")
fmt.Fprintln(os.Stderr, os.Args[0]+" -pkey verify -key <publickey.pem> -signature <$signature>")
os.Exit(1)
} else if *pkey == "verify" && (*key != "" || *sig != "") && strings.ToUpper(*alg) == "RSA" {
buf := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buf, data)
Data := string(buf.Bytes())
Signature, err := hex.DecodeString(*sig)
if err != nil {
log.Fatal(err)
}
err = VerifyRSA([]byte(Data), Signature)
if err != nil {
fmt.Println("Checksum error:", err)
os.Exit(1)
}
fmt.Println("Verified: true")
}
if *pkey == "encrypt" && (*key != "") && strings.ToUpper(*alg) == "RSA" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
publicInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
publicKey := publicInterface.(*rsa.PublicKey)
buffer := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buffer, data)
ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, buffer.Bytes())
if err != nil {
fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
return
}
fmt.Printf("%s", ciphertext)
}
if *pkey == "decrypt" && (*key != "") && strings.ToUpper(*alg) == "RSA" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
var privateKey *rsa.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privateKey, err = x509.ParsePKCS1PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
buffer := bytes.NewBuffer(nil)
// data := os.Stdin
data := inputfile
io.Copy(buffer, data)
plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, buffer.Bytes())
if err != nil {
fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err)
return
}
fmt.Printf("%s", plaintext)
}
if (*pkey == "text" || *pkey == "modulus") && PEM == "Private" && strings.ToUpper(*alg) == "GOST2012" {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Println(err)
}
info, err := file.Stat()
if err != nil {
log.Println(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "GOST PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
var privKey, _ = x509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Println(err)
}
gostKey := privKey.(*gost3410.PrivateKey)
pubKey := gostKey.Public()
if *pkey == "modulus" {
var publicKey = pubKey.(*gost3410.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
/*
derBytes, err := x509.MarshalPKIXPublicKey(gostKey.Public())
if err != nil {
log.Fatal(err)
}
*/
p := fmt.Sprintf("%X", gostKey.Raw())
fmt.Println("Private key:", p)
fmt.Printf("Public key: \n")
var publicKey = pubKey.(*gost3410.PublicKey)
fmt.Printf(" X:%X\n", publicKey.X)
fmt.Printf(" Y:%X\n", publicKey.Y)
/*
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Println(err)
}
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
*/
fmt.Printf("Curve: %s\n", publicKey.C.Name)
hasher := gost34112012256.New()
if _, err = hasher.Write(publicKey.Raw()); err != nil {
log.Fatalln(err)
}
spki := hasher.Sum(nil)
spki = spki[:20]
fmt.Printf("\nKeyID: %x \n", spki)
os.Exit(0)
}
if *pkey == "fingerprint" && (strings.ToUpper(*alg) == "ELGAMAL") && (PEM == "Public") {
// Primeiro tenta ler como ASN1
data, err := os.ReadFile(*key)
if err != nil {
fmt.Println("Error reading public key file:", err)
os.Exit(1)
}
block, _ := pem.Decode(data)
if block == nil {
fmt.Println("Failed to decode PEM block")
os.Exit(1)
}
var pubASN1 PublicKeyASN1
if _, err := asn1.Unmarshal(block.Bytes, &pubASN1); err == nil {
// Formato ASN1 - calcula fingerprint usando P, G e Y
fingerprint := calculateFingerprintFromASN1(pubASN1.Y.Bytes())
fmt.Println("Fingerprint=", fingerprint)
os.Exit(0)
}
// Se não for ASN1, tenta o formato antigo
publicKeyVal, err := readPublicKeyFromPEM(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
return
}
fingerprint := calculateFingerprint(publicKeyVal.Y.Bytes())
fmt.Println("Fingerprint=", fingerprint)
os.Exit(0)
}
if *pkey == "randomart" && (strings.ToUpper(*alg) == "ELGAMAL") && (PEM == "Public") {
publicKeyVal, err := readPublicKeyFromPEM(*key)
if err != nil {
fmt.Println("Error reading PEM file:", err)
return
}
primeBitLength := publicKeyVal.P.BitLen()
fmt.Fprintf(os.Stderr, "ElGamal (%d-bits)\n", primeBitLength)
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
randomArt := randomart.FromString(string(buf))
fmt.Println(randomArt)
os.Exit(0)
}
if (*pkey == "randomart") && PEM == "Public" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
parsers := []func([]byte) (interface{}, error){
func(b []byte) (interface{}, error) {
return smx509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
return x509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
return nums.ParsePublicKey(b)
},
func(b []byte) (interface{}, error) {
pub, err := ed448.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := x448.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
return kx509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
pub, err := ecgdsa.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := ecsdsa.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := bip0340.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := bign.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := frp256v1.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := secp256k1.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := tom.ParsePublicKey(b)
return pub, err
},
}
var publicInterface interface{}
for _, parser := range parsers {
publicInterface, err = parser(block.Bytes)
if err == nil {
break
}
}
if err != nil {
log.Fatal("Failed to parse public key:", err)
}
switch publicInterface.(type) {
case *rsa.PublicKey:
publicKey := publicInterface.(*rsa.PublicKey)
fmt.Printf("RSA (%v-bit)\n", publicKey.N.BitLen())
case *ecdsa.PublicKey:
publicKey := publicInterface.(*ecdsa.PublicKey)
fmt.Printf("ECDSA (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *nums.PublicKey:
publicKey := publicInterface.(*nums.PublicKey)
// curve := determineCurve(publicKey)
curve := publicKey.Curve
fmt.Printf("NUMS (%v-bit)\n", curve.Params().BitSize)
case *frp256v1.PublicKey:
publicKey := publicInterface.(*frp256v1.PublicKey)
// curve := determineCurve(publicKey)
curve := publicKey.Curve
fmt.Printf("ANSSI (%v-bit)\n", curve.Params().BitSize)
case *secp256k1.PublicKey:
publicKey := publicInterface.(*secp256k1.PublicKey)
// curve := determineCurve(publicKey)
curve := publicKey.Curve
fmt.Printf("KOBLITZ (%v-bit)\n", curve.Params().BitSize)
case *eckcdsa.PublicKey:
publicKey := publicInterface.(*eckcdsa.PublicKey)
// curve := determineCurve(publicKey)
curve := publicKey.Curve
fmt.Printf("ECKCDSA (%v-bit)\n", curve.Params().BitSize)
case *tom.PublicKey:
publicKey := publicInterface.(*tom.PublicKey)
// curve := determineCurve(publicKey)
curve := publicKey.Curve
fmt.Printf("Tom (%v-bit)\n", curve.Params().BitSize)
case *ecgdsa.PublicKey:
publicKey := publicInterface.(*ecgdsa.PublicKey)
// curve := determineCurve(publicKey)
curve := publicKey.Curve
fmt.Printf("ECGDSA (%v-bit)\n", curve.Params().BitSize)
case *ecsdsa.PublicKey:
publicKey := publicInterface.(*ecsdsa.PublicKey)
// curve := determineCurve(publicKey)
curve := publicKey.Curve
fmt.Printf("ECSDSA (%v-bit)\n", curve.Params().BitSize)
case *bip0340.PublicKey:
publicKey := publicInterface.(*bip0340.PublicKey)
// curve := determineCurve(publicKey)
curve := publicKey.Curve
fmt.Printf("BIP0340 (%v-bit)\n", curve.Params().BitSize)
case *bign.PublicKey:
publicKey := publicInterface.(*bign.PublicKey)
curve := publicKey.Curve
fmt.Printf("BIGN (%v-bit)\n", curve.Params().BitSize)
case *ecdh.PublicKey:
fmt.Println("X25519 (256-bit)")
case ed25519.PublicKey:
fmt.Println("Ed25519 (256-bit)")
case ed448.PublicKey:
fmt.Println("Ed448 (448-bit)")
case x448.PublicKey:
fmt.Println("X448 (448-bit)")
case *gost3410.PublicKey:
publicKey := publicInterface.(*gost3410.PublicKey)
fmt.Printf("GOST2012 (%v-bit)\n", len(publicKey.Raw())*4)
default:
log.Fatal("unknown type of public key")
}
fmt.Println(randomart.FromString(strings.ReplaceAll(string(buf), "\r\n", "\n")))
}
if (*pkey == "fingerprint") && PEM == "Public" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
parsers := []func([]byte) (interface{}, error){
func(b []byte) (interface{}, error) {
return smx509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
return x509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
return nums.ParsePublicKey(b)
},
func(b []byte) (interface{}, error) {
pub, err := ed448.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := x448.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
return kx509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
pub, err := ecgdsa.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := ecsdsa.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := bip0340.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := bign.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := frp256v1.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := secp256k1.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := tom.ParsePublicKey(b)
return pub, err
},
}
var publicInterface interface{}
for _, parser := range parsers {
publicInterface, err = parser(block.Bytes)
if err == nil {
break
}
}
if err != nil {
log.Fatal("Failed to parse public key:", err)
}
var fingerprint string
switch publicInterface.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey, *ecdh.PublicKey, ed25519.PublicKey:
fingerprint = calculateFingerprint(buf)
case *gost3410.PublicKey:
fingerprint = calculateFingerprintGOST(buf)
case *nums.PublicKey:
fingerprint = calculateFingerprint(buf)
case *frp256v1.PublicKey:
fingerprint = calculateFingerprint(buf)
case *secp256k1.PublicKey:
fingerprint = calculateFingerprint(buf)
case *eckcdsa.PublicKey:
fingerprint = calculateFingerprint(buf)
case *ecgdsa.PublicKey:
fingerprint = calculateFingerprint(buf)
case *ecsdsa.PublicKey:
fingerprint = calculateFingerprint(buf)
case *bip0340.PublicKey:
fingerprint = calculateFingerprint(buf)
case ed448.PublicKey:
fingerprint = calculateFingerprint(buf)
case x448.PublicKey:
fingerprint = calculateFingerprint(buf)
case *bign.PublicKey:
fingerprint = calculateFingerprint(buf)
case *tom.PublicKey:
fingerprint = calculateFingerprint(buf)
default:
log.Fatal("unknown type of public key")
}
fmt.Print("Fingerprint= ")
fmt.Println(fingerprint)
}
if (*pkey == "text" || *pkey == "modulus") && PEM == "Public" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
parsers := []func([]byte) (interface{}, error){
func(b []byte) (interface{}, error) {
return smx509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
return x509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
return nums.ParsePublicKey(b)
},
func(b []byte) (interface{}, error) {
pub, err := ed448.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := x448.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
return kx509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
pub, err := ecgdsa.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := ecsdsa.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := bip0340.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := bign.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := frp256v1.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := secp256k1.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := tom.ParsePublicKey(b)
return pub, err
},
}
var publicInterface interface{}
for _, parser := range parsers {
publicInterface, err = parser(block.Bytes)
if err == nil {
break
}
}
if err != nil {
log.Fatal("Failed to parse public key:", err)
}
switch publicInterface.(type) {
case *ecdh.PublicKey:
*alg = "X25519"
case ed25519.PublicKey:
*alg = "ED25519"
case ed448.PublicKey:
*alg = "ED448"
case x448.PublicKey:
*alg = "X448"
case *rsa.PublicKey:
*alg = "RSA"
case *ecdsa.PublicKey:
*alg = "EC"
case *eckcdsa.PublicKey:
*alg = "ECKCDSA"
case *ecgdsa.PublicKey:
*alg = "ECGDSA"
case *ecsdsa.PublicKey:
*alg = "ECSDSA"
case *bip0340.PublicKey:
*alg = "BIP0340"
case *nums.PublicKey:
*alg = "NUMS"
case *frp256v1.PublicKey:
*alg = "ANSSI"
case *secp256k1.PublicKey:
*alg = "KOBLITZ"
case *tom.PublicKey:
*alg = "TOM"
case *bign.PublicKey:
*alg = "BIGN"
case *gost3410.PublicKey:
*alg = "GOST2012"
default:
log.Fatal("unknown type of public key")
}
if *pkey == "modulus" && strings.ToUpper(*alg) == "RSA" {
var publicKey = publicInterface.(*rsa.PublicKey)
fmt.Printf("Modulus=%X\n", publicKey.N)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "SM2") {
var publicKey = publicInterface.(*ecdsa.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "NUMS") {
var publicKey = publicInterface.(*nums.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "ANSSI") {
var publicKey = publicInterface.(*frp256v1.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "KOBLITZ") {
var publicKey = publicInterface.(*secp256k1.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "TOM") {
var publicKey = publicInterface.(*tom.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "BIGN") {
var publicKey = publicInterface.(*bign.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "ECKCDSA") {
var publicKey = publicInterface.(*eckcdsa.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "ECGDSA") {
var publicKey = publicInterface.(*ecgdsa.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "ECSDSA") {
var publicKey = publicInterface.(*ecsdsa.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "BIP0340") {
var publicKey = publicInterface.(*bip0340.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "ED25519") {
var publicKey = publicInterface.(ed25519.PublicKey)
fmt.Printf("Public=%X\n", publicKey)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "ED448") {
var publicKey = publicInterface.(ed448.PublicKey)
fmt.Printf("Public=%X\n", publicKey)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "X448") {
var publicKey = publicInterface.(x448.PublicKey)
fmt.Printf("Public=%X\n", publicKey)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "GOST2012") {
var publicKey = publicInterface.(*gost3410.PublicKey)
fmt.Printf("Public.X=%X\n", publicKey.X)
fmt.Printf("Public.Y=%X\n", publicKey.Y)
os.Exit(0)
}
if strings.ToUpper(*alg) == "RSA" {
publicKey := publicInterface.(*rsa.PublicKey)
derBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("RSA Public-Key: (%v-bit)\n", publicKey.N.BitLen())
// modulus := fmt.Sprintf("%x", publicKey.N)
fmt.Printf("Modulus: \n")
m := publicKey.N.Bytes()
b, _ := hex.DecodeString("00")
c := []byte{}
c = append(c, b...)
c = append(c, m...)
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Exponent: %d (0x%X)\n", publicKey.E, publicKey.E)
} else if strings.ToUpper(*alg) == "ED25519" {
publicKey := publicInterface.(ed25519.PublicKey)
derBytes, err := smx509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key:\n")
fmt.Printf("pub: \n")
splitz := SplitSubN(hex.EncodeToString(derBytes)[24:], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Println("Curve: ed25519")
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "ED448" {
publicKey := publicInterface.(ed448.PublicKey)
derBytes, err := ed448.MarshalPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "ED448 PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key:\n")
fmt.Printf("pub: \n")
splitz := SplitSubN(hex.EncodeToString(derBytes)[24:], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Println("Curve: ed448")
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "X448" {
publicKey := publicInterface.(x448.PublicKey)
derBytes, err := x448.MarshalPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "X448 PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key:\n")
fmt.Printf("pub: \n")
splitz := SplitSubN(hex.EncodeToString(derBytes)[24:], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Println("Curve: x448")
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "X25519" {
publicKey := publicInterface.(*ecdh.PublicKey)
derBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key:\n")
fmt.Printf("pub: \n")
splitz := SplitSubN(hex.EncodeToString(derBytes)[24:], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Println("Curve: x25519")
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "EC" {
publicKey := publicInterface.(*ecdsa.PublicKey)
derBytes, err := smx509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", publicKey.Curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
} else if strings.ToUpper(*alg) == "ECKCDSA" {
publicKey := publicInterface.(*eckcdsa.PublicKey)
derBytes, err := kx509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", publicKey.Curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
} else if strings.ToUpper(*alg) == "ECGDSA" {
publicKey := publicInterface.(*ecgdsa.PublicKey)
derBytes, err := ecgdsa.MarshalPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", publicKey.Curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
} else if strings.ToUpper(*alg) == "ECSDSA" {
publicKey := publicInterface.(*ecsdsa.PublicKey)
derBytes, err := ecsdsa.MarshalPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", publicKey.Curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
} else if strings.ToUpper(*alg) == "BIP0340" {
publicKey := publicInterface.(*bip0340.PublicKey)
derBytes, err := bip0340.MarshalPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", publicKey.Curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
} else if strings.ToUpper(*alg) == "ANSSI" {
publicKey := publicInterface.(*frp256v1.PublicKey)
// Determine the curve
curve := publicKey.Curve
derBytes, err := publicKey.MarshalPKCS8PublicKey(curve)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Curve.Params().Name)
} else if strings.ToUpper(*alg) == "KOBLITZ" {
publicKey := publicInterface.(*secp256k1.PublicKey)
// Determine the curve
curve := publicKey.Curve
derBytes, err := publicKey.MarshalPKCS8PublicKey(curve)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Curve.Params().Name)
} else if strings.ToUpper(*alg) == "TOM" {
publicKey := publicInterface.(*tom.PublicKey)
// Determine the curve
curve := publicKey.Curve
derBytes, err := publicKey.MarshalPKCS8PublicKey(curve)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Curve.Params().Name)
} else if strings.ToUpper(*alg) == "BIGN" {
publicKey := publicInterface.(*bign.PublicKey)
derBytes, err := bign.MarshalPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", publicKey.Curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
} else if strings.ToUpper(*alg) == "NUMS" {
publicKey := publicInterface.(*nums.PublicKey)
curve := publicKey.Curve
derBytes, err := publicKey.MarshalPKCS8PublicKey(curve)
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public-Key: (%v-bit)\n", curve.Params().BitSize)
// x := fmt.Sprintf("%x", publicKey.X)
x := publicKey.X.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
c := []byte{}
c = append(c, x...)
fmt.Printf("pub.X: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
// y := fmt.Sprintf("%x", publicKey.Y)
y := publicKey.Y.Bytes()
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, y...)
fmt.Printf("pub.Y: \n")
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
x = publicKey.X.Bytes()
y = publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Curve: %s\n", publicKey.Curve.Params().Name)
} else if strings.ToUpper(*alg) == "GOST2012" {
publicKey := publicInterface.(*gost3410.PublicKey)
derBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Println(err)
}
block = &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
public := pem.EncodeToMemory(block)
fmt.Printf(string(public))
fmt.Printf("Public key:\n")
fmt.Printf(" X:%X\n", publicKey.X)
fmt.Printf(" Y:%X\n", publicKey.Y)
fmt.Printf("Curve: %s\n", publicKey.C.Name)
}
}
if (*pkey == "text" || *pkey == "modulus") && PEM == "Private" {
var privPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
if strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "SM2" {
var privKey, err = smx509.ParseECPrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
derBytes, err := smx509.MarshalPKIXPublicKey(&privKey.PublicKey)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(privKey.Curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", privKey.Curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "ECKCDSA" {
var privKey, err = kx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
eckcdsaPrivKey, ok := privKey.(*eckcdsa.PrivateKey)
if !ok {
log.Fatalf("expected an ECKCDSA key but received another type")
}
derBytes, err := kx509.MarshalPKIXPublicKey(&eckcdsaPrivKey.PublicKey)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", eckcdsaPrivKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", eckcdsaPrivKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := eckcdsaPrivKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(eckcdsaPrivKey.Curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", eckcdsaPrivKey.Curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := eckcdsaPrivKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "ECGDSA" {
var privKey, err = ecgdsa.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
derBytes, err := ecgdsa.MarshalPublicKey(&privKey.PublicKey)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(privKey.Curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", privKey.Curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "ECSDSA" {
var privKey, err = ecsdsa.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
derBytes, err := ecsdsa.MarshalPublicKey(&privKey.PublicKey)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(privKey.Curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", privKey.Curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "BIP0340" {
var privKey, err = bip0340.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
derBytes, err := bip0340.MarshalPublicKey(&privKey.PublicKey)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(privKey.Curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", privKey.Curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "ANSSI" {
var privKey, err = frp256v1.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
curve := privKey.PublicKey.Curve
pub := &privKey.PublicKey
derBytes, err := pub.MarshalPKCS8PublicKey(curve)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Curve.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "KOBLITZ" {
var privKey, err = secp256k1.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
curve := privKey.PublicKey.Curve
pub := &privKey.PublicKey
derBytes, err := pub.MarshalPKCS8PublicKey(curve)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Curve.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "TOM" {
var privKey, err = tom.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
curve := privKey.PublicKey.Curve
pub := &privKey.PublicKey
derBytes, err := pub.MarshalPKCS8PublicKey(curve)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Curve.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "BIGN" {
var privKey, err = bign.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
derBytes, err := bign.MarshalPublicKey(&privKey.PublicKey)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(privKey.Curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", privKey.Curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(publicKey.Curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "NUMS" {
var privKey, err = nums.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
curve := privKey.PublicKey.Curve
pub := &privKey.PublicKey
derBytes, err := pub.MarshalPKCS8PublicKey(curve)
if err != nil {
log.Fatal(err)
}
if *pkey == "modulus" {
fmt.Printf("Public.X=%X\n", privKey.PublicKey.X)
fmt.Printf("Public.Y=%X\n", privKey.PublicKey.Y)
os.Exit(0)
}
fmt.Printf(string(privPEM))
d := privKey.D.Bytes()
if n := len(d); n < 24 && n < 32 && n < 48 && n < 64 {
d = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], d...)
}
c := []byte{}
c = append(c, d...)
fmt.Printf("Private-Key: (%v-bit)\n", curve.Params().BitSize)
fmt.Printf("priv: \n")
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
publicKey := privKey.PublicKey
fmt.Printf("pub: \n")
x := publicKey.X.Bytes()
y := publicKey.Y.Bytes()
if n := len(x); n < 24 && n < 32 && n < 48 && n < 64 {
x = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], x...)
}
if n := len(y); n < 24 && n < 32 && n < 48 && n < 64 {
y = append(zeroByteSlice()[:(curve.Params().BitSize/8)-n], y...)
}
c = []byte{}
c = append(c, x...)
c = append(c, y...)
c = append([]byte{0x04}, c...)
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Curve: %s\n", publicKey.Curve.Params().Name)
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "ED25519" {
var privKey, _ = smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
edKey := privKey.(ed25519.PrivateKey)
if *pkey == "modulus" {
fmt.Printf("Public=%X\n", edKey.Public())
os.Exit(0)
}
fmt.Printf(string(privPEM))
derBytes, err := smx509.MarshalPKIXPublicKey(edKey.Public())
if err != nil {
log.Fatal(err)
}
fmt.Printf("Private-Key:\n")
p := fmt.Sprintf("%x", privKey)
fmt.Printf("priv: \n")
splitz := SplitSubN(p[:64], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
splitz = SplitSubN(p[64:], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Println("Curve: ed25519")
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "ED448" {
var privKey, _ = ed448.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
edKey := privKey
if *pkey == "modulus" {
fmt.Printf("Public=%X\n", edKey.Public())
os.Exit(0)
}
fmt.Printf(string(privPEM))
derBytes, err := ed448.MarshalPublicKey(edKey.Public().(ed448.PublicKey))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Private-Key:\n")
p := fmt.Sprintf("%x", privKey)
fmt.Printf("priv: \n")
splitz := SplitSubN(p[:114], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
splitz = SplitSubN(p[114:], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Println("Curve: ed448")
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "X448" {
var privKey, _ = x448.ParsePrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
edKey := privKey
if *pkey == "modulus" {
fmt.Printf("Public=%X\n", edKey.Public())
os.Exit(0)
}
fmt.Printf(string(privPEM))
derBytes, err := x448.MarshalPublicKey(edKey.Public().(x448.PublicKey))
if err != nil {
log.Fatal(err)
}
fmt.Printf("Private-Key:\n")
p := fmt.Sprintf("%x", privKey)
fmt.Printf("priv: \n")
splitz := SplitSubN(p[:112], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("pub: \n")
splitz = SplitSubN(p[112:], 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Println("Curve: x448")
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "X25519" {
var privKey, _ = smx509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
edKey := privKey.(*ecdh.PrivateKey)
fmt.Printf(string(privPEM))
derBytes, err := x509.MarshalPKIXPublicKey(edKey.Public())
if err != nil {
log.Fatal(err)
}
fmt.Printf("Private-Key:\n")
p := fmt.Sprintf("%x", edKey.Bytes())
fmt.Printf("priv: \n")
splitz := SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
p = fmt.Sprintf("%x", edKey.PublicKey().Bytes())
fmt.Printf("pub: \n")
splitz = SplitSubN(p, 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
fmt.Println("Curve: x25519")
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
} else if strings.ToUpper(*alg) == "RSA" {
var privKey, _ = x509.ParsePKCS1PrivateKey(privateKeyPemBlock.Bytes)
if err := privKey.Validate(); err != nil {
panic("error validating the private key: " + err.Error())
}
var privKeyPublicKey = privKey.PublicKey
if *pkey == "modulus" {
fmt.Printf("Modulus=%X\n", privKey.N)
os.Exit(0)
}
fmt.Printf(string(privPEM))
fmt.Printf("RSA Private-Key: (%v-bit)\n", privKey.N.BitLen())
// modulus := fmt.Sprintf("%x", privKeyPublicKey.N)
fmt.Printf("Modulus (N): \n")
m := privKeyPublicKey.N.Bytes()
b, _ := hex.DecodeString("00")
c := []byte{}
c = append(c, b...)
c = append(c, m...)
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Public Exponent (E): %d (0x%X)\n", privKeyPublicKey.E, privKeyPublicKey.E)
derBytes, err := x509.MarshalPKIXPublicKey(&privKeyPublicKey)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Private Exponent (D): \n")
splitz = SplitSubN(hex.EncodeToString(privKey.D.Bytes()), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Prime 1 (P): \n")
splitz = SplitSubN(hex.EncodeToString(privKey.Primes[0].Bytes()), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Prime 2 (Q): \n")
splitz = SplitSubN(hex.EncodeToString(privKey.Primes[1].Bytes()), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Exponent 1 (D mod (P-1)): \n")
splitz = SplitSubN(hex.EncodeToString(privKey.Precomputed.Dp.Bytes()), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Exponent 2 (D mod (Q-1)): \n")
splitz = SplitSubN(hex.EncodeToString(privKey.Precomputed.Dq.Bytes()), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("Coefficient (Q^-1 mod P): \n")
splitz = SplitSubN(hex.EncodeToString(privKey.Precomputed.Qinv.Bytes()), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
log.Fatal(err)
}
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
fmt.Printf("\nKeyID: %x \n", skid)
}
}
if (*pkey == "text" || *pkey == "modulus" || *pkey == "info") && (PEM == "Certificate") {
var certPEM []byte
file, err := os.Open(*cert)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
certPEM = buf
var certPemBlock, _ = pem.Decode([]byte(certPEM))
var certa, _ = smx509.ParseCertificate(certPemBlock.Bytes)
signature := fmt.Sprintf("%s", certa.SignatureAlgorithm)
if signature == "ECDSA-SHA256" || signature == "ECDSA-SHA384" || signature == "ECDSA-SHA512" {
*alg = "EC"
} else if signature == "99" {
*alg = "SM2"
} else if signature == "Ed25519" {
*alg = "ED25519"
} else if signature == "SHA256-RSA" || signature == "SHA384-RSA" || signature == "SHA512-RSA" {
*alg = "RSA"
} else {
*alg = "GOST2012"
}
if *pkey == "modulus" && strings.ToUpper(*alg) == "RSA" {
var certaPublicKey = certa.PublicKey.(*rsa.PublicKey)
fmt.Printf("Modulus=%X\n", certaPublicKey.N)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "SM2") {
var certaPublicKey = certa.PublicKey.(*ecdsa.PublicKey)
fmt.Printf("Public.X=%X\n", certaPublicKey.X)
fmt.Printf("Public.Y=%X\n", certaPublicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "ED25519") {
var certaPublicKey = certa.PublicKey.(ed25519.PublicKey)
fmt.Printf("Public=%X\n", certaPublicKey)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "GOST2012") {
var certa, _ = x509.ParseCertificate(certPemBlock.Bytes)
var certaPublicKey = certa.PublicKey.(*gost3410.PublicKey)
fmt.Printf("Public.X=%X\n", certaPublicKey.X)
fmt.Printf("Public.Y=%X\n", certaPublicKey.Y)
os.Exit(0)
}
if *pkey == "info" {
fmt.Printf("Expiry: %s \n", certa.NotAfter.Format("Monday, 02-Jan-06 15:04:05 MST"))
fmt.Printf("Common Name: %s \n", certa.Issuer.CommonName)
fmt.Printf("EmailAddresses: %s \n", certa.EmailAddresses)
fmt.Printf("IP Address: %s \n", certa.IPAddresses)
fmt.Printf("DNSNames: %s \n", certa.DNSNames)
fmt.Printf("SerialNumber: %x \n", certa.SerialNumber)
fmt.Printf("SubjectKeyId: %x \n", certa.SubjectKeyId)
fmt.Printf("AuthorityKeyId: %x \n", certa.AuthorityKeyId)
os.Exit(0)
}
if *alg == "GOST2012" {
var certPEM []byte
file, err := os.Open(*cert)
if err != nil {
log.Println(err)
}
info, err := file.Stat()
if err != nil {
log.Println(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
certPEM = buf
var certPemBlock, _ = pem.Decode([]byte(certPEM))
var certa, _ = x509.ParseCertificate(certPemBlock.Bytes)
if *pkey == "modulus" {
var certaPublicKey = certa.PublicKey.(*gost3410.PublicKey)
fmt.Printf("Public.X=%X\n", certaPublicKey.X)
fmt.Printf("Public.Y=%X\n", certaPublicKey.Y)
os.Exit(0)
}
var buf2 bytes.Buffer
buf2.Grow(4096)
buf2.WriteString(fmt.Sprintf("Certificate:\n"))
buf2.WriteString(fmt.Sprintf("%4sData:\n", ""))
printVersion(certa.Version, &buf2)
buf2.WriteString(fmt.Sprintf("%8sSerial Number : %d (%X)\n", "", certa.SerialNumber, certa.SerialNumber))
buf2.WriteString(fmt.Sprintf("%8sCommonName : %s \n", "", certa.Subject.CommonName))
buf2.WriteString(fmt.Sprintf("%8sEmailAddresses: %s \n", "", certa.EmailAddresses))
buf2.WriteString(fmt.Sprintf("%8sIsCA : %v \n", "", certa.IsCA))
buf2.WriteString(fmt.Sprintf("%8sCurve : %s \n", "", certa.PublicKey.(*gost3410.PublicKey).C.Name))
// Issuer information
buf2.WriteString(fmt.Sprintf("%8sIssuer\n ", ""))
printName(certa.Issuer.Names, &buf2)
// Subject information
buf2.WriteString(fmt.Sprintf("%8sSubject\n ", ""))
printName(certa.Subject.Names, &buf2)
// Validity information
buf2.WriteString(fmt.Sprintf("%8sValidity\n", ""))
buf2.WriteString(fmt.Sprintf("%12sNot Before: %s\n", "", certa.NotBefore.Format("Jan 2 15:04:05 2006 MST")))
buf2.WriteString(fmt.Sprintf("%12sNot After : %s\n", "", certa.NotAfter.Format("Jan 2 15:04:05 2006 MST")))
var certaPublicKey = certa.PublicKey.(*gost3410.PublicKey)
x := certaPublicKey.X.Bytes()
c := []byte{}
c = append(c, x...)
buf2.WriteString(fmt.Sprintf("%8sPub.X\n", ""))
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
buf2.WriteString(fmt.Sprintf(" %-10s \n", strings.ReplaceAll(chunk, " ", ":")))
}
y := certaPublicKey.Y.Bytes()
c = []byte{}
c = append(c, y...)
buf2.WriteString(fmt.Sprintf("%8sPub.Y\n", ""))
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
buf2.WriteString(fmt.Sprintf(" %-10s \n", strings.ReplaceAll(chunk, " ", ":")))
}
buf2.WriteString(fmt.Sprintf("%8sSubjectKeyId : %x \n", "", certa.SubjectKeyId))
buf2.WriteString(fmt.Sprintf("%8sAuthorityKeyId: %x \n", "", certa.AuthorityKeyId))
printSignature(certa.SignatureAlgorithm, certa.Signature, &buf2)
fmt.Print(buf2.String())
ok := time.Now().Before(certa.NotAfter)
fmt.Println("IsValid:", ok)
if ok {
os.Exit(0)
} else {
os.Exit(1)
}
}
pemData, err := ioutil.ReadFile(*cert)
if err != nil {
log.Fatal(err)
}
block, rest := pem.Decode([]byte(pemData))
if block == nil || len(rest) > 0 {
log.Fatal("Certificate decoding error")
}
result, err := certinfo.CertificateText(certa.ToX509())
if err != nil {
log.Fatal(err)
}
fmt.Print(result)
ok := time.Now().Before(certa.NotAfter)
fmt.Println("IsValid:", ok)
if ok {
os.Exit(0)
} else {
os.Exit(1)
}
}
if *pkey == "check" && *crl == "" {
var certPEM []byte
file, err := os.Open(*cert)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
certPEM = buf
var certPemBlock, _ = pem.Decode([]byte(certPEM))
var certa, _ = smx509.ParseCertificate(certPemBlock.Bytes)
pemData, err := ioutil.ReadFile(*cert)
if err != nil {
log.Fatal(err)
}
block, rest := pem.Decode([]byte(pemData))
if block == nil || len(rest) > 0 {
log.Fatal("Certificate decoding error")
}
signature := fmt.Sprintf("%s", certa.SignatureAlgorithm)
if signature == "ECDSA-SHA256" || signature == "ECDSA-SHA384" || signature == "ECDSA-SHA512" {
*alg = "EC"
} else if signature == "99" {
*alg = "SM2"
} else if signature == "Ed25519" {
*alg = "ED25519"
} else if signature == "SHA256-RSA" || signature == "SHA384-RSA" || signature == "SHA512-RSA" {
*alg = "RSA"
} else if signature == "0" {
*alg = "GOST2012"
}
var h hash.Hash
h = sha256.New()
if signature == "ECDSA-SHA256" {
h = sha256.New()
} else if signature == "ECDSA-SHA384" {
h = sha512.New384()
} else if signature == "ECDSA-SHA512" {
h = sha512.New()
} else if signature == "SHA384-RSA" {
h = sha512.New384()
} else if signature == "SHA512-RSA" {
h = sha512.New()
} else if signature == "SHA1-RSA" {
h = sha1.New()
}
var verifystatus bool
h.Write(certa.RawTBSCertificate)
hash_data := h.Sum(nil)
file, err = os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
block, _ = pem.Decode(buf)
publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
publicKey, err = smx509.ParsePKIXPublicKey(block.Bytes)
}
if *alg == "EC" {
verifystatus = ecdsa.VerifyASN1(publicKey.(*ecdsa.PublicKey), hash_data, certa.Signature)
} else if *alg == "RSA" {
if signature == "SHA256-RSA" {
err = rsa.VerifyPKCS1v15(publicKey.(*rsa.PublicKey), crypto.SHA256, hash_data, certa.Signature)
} else if signature == "SHA384-RSA" {
err = rsa.VerifyPKCS1v15(publicKey.(*rsa.PublicKey), crypto.SHA384, hash_data, certa.Signature)
h = sha512.New384()
} else if signature == "SHA512-RSA" {
err = rsa.VerifyPKCS1v15(publicKey.(*rsa.PublicKey), crypto.SHA512, hash_data, certa.Signature)
h = sha512.New()
} else if signature == "SHA1-RSA" {
err = rsa.VerifyPKCS1v15(publicKey.(*rsa.PublicKey), crypto.SHA1, hash_data, certa.Signature)
h = sha1.New()
}
if err != nil {
verifystatus = false
} else {
verifystatus = true
}
} else if *alg == "SM2" {
// verifystatus = sm2.VerifyASN1(publicKey.(*ecdsa.PublicKey), hash_data, certa.Signature)
verifystatus = sm2.VerifyASN1WithSM2(publicKey.(*ecdsa.PublicKey), nil, certa.RawTBSCertificate, certa.Signature)
} else if *alg == "ED25519" {
verifystatus = ed25519.Verify(publicKey.(ed25519.PublicKey), certa.RawTBSCertificate, certa.Signature)
} else if *alg == "GOST2012" {
var certa, _ = x509.ParseCertificate(certPemBlock.Bytes)
signature := fmt.Sprintf("%s", certa.SignatureAlgorithm)
if signature == "GOST512" {
h = gost34112012512.New()
} else {
h = gost34112012256.New()
}
h.Write(certa.RawTBSCertificate)
hash_data := h.Sum(nil)
reverseBytes(hash_data)
verifystatus, err = publicKey.(*gost3410.PublicKey).VerifyDigest(hash_data, certa.Signature)
if err != nil {
log.Fatal(err)
}
}
fmt.Println("Verified:", verifystatus)
if verifystatus {
os.Exit(0)
} else {
os.Exit(1)
}
}
if *pkey == "certgen" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var priv interface{}
var block *pem.Block
block, _ = pem.Decode(buf)
if strings.ToUpper(*alg) == "ED25519" {
var priva interface{}
// var privateKey ed25519.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
priva, err = x509.ParsePKCS8PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
priva, err = x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
priv = priva
} else if strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA" {
var privateKey *ecdsa.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privateKey, err = smx509.ParseECPrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
privateKey, err = smx509.ParseECPrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
priv = privateKey
} else if strings.ToUpper(*alg) == "SM2" {
var privateKey *sm2.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privateKey, err = smx509.ParseSM2PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
privateKey, err = smx509.ParseSM2PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
priv = privateKey
} else if strings.ToUpper(*alg) == "RSA" {
var privateKey *rsa.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privateKey, err = x509.ParsePKCS1PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
priv = privateKey
}
keyUsage := smx509.KeyUsageDigitalSignature
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 160)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %v", err)
}
// consensus := externalip.DefaultConsensus(nil, nil)
// ip, _ := consensus.ExternalIP()
if *subj == "" {
println("You are about to be asked to enter information \nthat will be incorporated into your certificate.")
scanner := bufio.NewScanner(os.Stdin)
print("Common Name: ")
scanner.Scan()
name = scanner.Text()
print("Country Name (2 letter code) [AU]: ")
scanner.Scan()
country = scanner.Text()
print("State or Province Name (full name) [Some-State]: ")
scanner.Scan()
province = scanner.Text()
print("Locality Name (eg, city): ")
scanner.Scan()
locality = scanner.Text()
print("Organization Name (eg, company) [Internet Widgits Pty Ltd]: ")
scanner.Scan()
organization = scanner.Text()
print("Organizational Unit Name (eg, section): ")
scanner.Scan()
organizationunit = scanner.Text()
print("Email Address []: ")
scanner.Scan()
email = scanner.Text()
print("StreetAddress: ")
scanner.Scan()
street = scanner.Text()
print("PostalCode: ")
scanner.Scan()
postalcode = scanner.Text()
print("SerialNumber: ")
scanner.Scan()
number = scanner.Text()
} else {
name, number, country, province, locality, organization, organizationunit, street, email, postalcode, err = parseSubjectString(*subj)
if err != nil {
log.Fatal(err)
}
}
var validity string
// Check if the 'days' flag was provided
if *days > 0 {
// If provided, use the value from the flag
validity = fmt.Sprintf("%d", *days)
} else {
// Otherwise, prompt the user for input
fmt.Print("Validity (in Days): ")
fmt.Scanln(&validity)
}
intVar, err := strconv.Atoi(validity)
if err != nil {
log.Fatal(err)
}
NotAfter := time.Now().AddDate(0, 0, intVar)
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
},
EmailAddresses: []string{email},
NotBefore: time.Now(),
NotAfter: NotAfter,
KeyUsage: keyUsage,
ExtKeyUsage: []smx509.ExtKeyUsage{smx509.ExtKeyUsageClientAuth, smx509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
// AuthorityKeyId: authority,
PermittedDNSDomainsCritical: true,
// DNSNames: []string{ip.String()},
// IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
// IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4()},
}
template.IsCA = true
template.KeyUsage |= smx509.KeyUsageCertSign | smx509.KeyUsageCRLSign | x509.KeyUsageContentCommitment | x509.KeyUsageKeyEncipherment | x509.KeyUsageDataEncipherment | x509.KeyUsageKeyAgreement
if strings.ToUpper(*alg) == "RSA" {
if *md == "sha256" {
template.SignatureAlgorithm = smx509.SHA256WithRSA
} else if *md == "sha384" {
template.SignatureAlgorithm = smx509.SHA384WithRSA
} else if *md == "sha512" {
template.SignatureAlgorithm = smx509.SHA512WithRSA
} else if *md == "sha1" {
template.SignatureAlgorithm = smx509.SHA1WithRSA
}
}
derBytes, err := smx509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
if err != nil {
log.Fatalf("Failed to create certificate: %v", err)
}
certfile, err := os.Create(*cert)
if err != nil {
log.Fatal(err)
}
pem.Encode(certfile, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
os.Exit(0)
}
if *pkey == "req" && *key != "" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var keyBytes interface{}
var block *pem.Block
block, _ = pem.Decode(buf)
if strings.ToUpper(*alg) == "ED25519" {
var priva interface{}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
priva, err = x509.ParsePKCS8PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
priva, err = x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
keyBytes = priva
} else if strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA" {
var privateKey *ecdsa.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privateKey, err = smx509.ParseECPrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
privateKey, err = smx509.ParseECPrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
keyBytes = privateKey
} else if strings.ToUpper(*alg) == "SM2" {
var privateKey *sm2.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privateKey, err = smx509.ParseSM2PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
privateKey, err = smx509.ParseSM2PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
keyBytes = privateKey
} else if strings.ToUpper(*alg) == "RSA" {
var privateKey *rsa.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privateKey, err = x509.ParsePKCS1PrivateKey(privKeyBytes)
if err != nil {
log.Fatal(err)
}
} else {
privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
log.Fatal(err)
}
}
keyBytes = privateKey
}
if *subj == "" {
println("You are about to be asked to enter information \nthat will be incorporated into your certificate.")
scanner := bufio.NewScanner(os.Stdin)
print("Common Name: ")
scanner.Scan()
name = scanner.Text()
print("Country Name (2 letter code) [AU]: ")
scanner.Scan()
country = scanner.Text()
print("State or Province Name (full name) [Some-State]: ")
scanner.Scan()
province = scanner.Text()
print("Locality Name (eg, city): ")
scanner.Scan()
locality = scanner.Text()
print("Organization Name (eg, company) [Internet Widgits Pty Ltd]: ")
scanner.Scan()
organization = scanner.Text()
print("Organizational Unit Name (eg, section): ")
scanner.Scan()
organizationunit = scanner.Text()
print("Email Address []: ")
scanner.Scan()
email = scanner.Text()
print("StreetAddress: ")
scanner.Scan()
street = scanner.Text()
print("PostalCode: ")
scanner.Scan()
postalcode = scanner.Text()
print("SerialNumber: ")
scanner.Scan()
number = scanner.Text()
} else {
name, number, country, province, locality, organization, organizationunit, street, email, postalcode, err = parseSubjectString(*subj)
if err != nil {
log.Fatal(err)
}
}
emailAddress := email
subj := pkix.Name{
CommonName: name,
SerialNumber: number,
Country: []string{country},
Province: []string{province},
Locality: []string{locality},
Organization: []string{organization},
OrganizationalUnit: []string{organizationunit},
StreetAddress: []string{street},
PostalCode: []string{postalcode},
}
rawSubj := subj.ToRDNSequence()
rawSubj = append(rawSubj, []pkix.AttributeTypeAndValue{
{Type: oidEmailAddress, Value: emailAddress},
})
asn1Subj, _ := asn1.Marshal(rawSubj)
var template x509.CertificateRequest
if strings.ToUpper(*alg) == "RSA" {
template = x509.CertificateRequest{
RawSubject: asn1Subj,
EmailAddresses: []string{emailAddress},
SignatureAlgorithm: x509.SHA256WithRSA,
}
} else if strings.ToUpper(*alg) == "ECDSA" || strings.ToUpper(*alg) == "EC" {
template = x509.CertificateRequest{
RawSubject: asn1Subj,
EmailAddresses: []string{emailAddress},
SignatureAlgorithm: x509.ECDSAWithSHA256,
}
} else if strings.ToUpper(*alg) == "SM2" {
template = x509.CertificateRequest{
RawSubject: asn1Subj,
EmailAddresses: []string{emailAddress},
SignatureAlgorithm: smx509.SM2WithSM3,
}
} else if strings.ToUpper(*alg) == "ED25519" {
template = x509.CertificateRequest{
RawSubject: asn1Subj,
EmailAddresses: []string{emailAddress},
SignatureAlgorithm: x509.PureEd25519,
}
}
var output *os.File
// if flag.Arg(0) == "" {
if *cert == "" {
output = os.Stdout
} else {
// file, err := os.Create(flag.Arg(0))
file, err := os.Create(*cert)
if err != nil {
log.Fatal(err)
}
defer file.Close()
output = file
}
csrBytes, _ := smx509.CreateCertificateRequest(rand.Reader, &template, keyBytes)
pem.Encode(output, &pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrBytes})
}
if (*pkey == "crl") && *key != "" && *cert != "" && strings.ToUpper(*alg) != "SM2" {
revokedCerts := make([]pkix.RevokedCertificate, 0)
scanner := bufio.NewScanner(inputfile)
existingSerialNumbers := make(map[string]bool)
for scanner.Scan() {
serialStr := strings.TrimSpace(scanner.Text())
serialNumber, success := new(big.Int).SetString(serialStr, 16)
if !success {
log.Fatalf("Invalid serial number: %s", serialStr)
}
serialKey := serialNumber.String()
if existingSerialNumbers[serialKey] {
continue
}
revocationTime := time.Now()
revokedCert := pkix.RevokedCertificate{
SerialNumber: serialNumber,
RevocationTime: revocationTime,
}
revokedCerts = append(revokedCerts, revokedCert)
existingSerialNumbers[serialKey] = true
}
if err := scanner.Err(); err != nil {
log.Fatal("Failed to read serials list:", err)
}
if *crl != "" {
existingCRLData, err := ioutil.ReadFile(*crl)
if err != nil {
log.Fatal("Failed to read the existing CRL file:", err)
}
existingCRLBlock, _ := pem.Decode(existingCRLData)
if existingCRLBlock == nil {
log.Fatal("Failed to decode the PEM block of the existing CRL")
}
existingCRL, err := x509.ParseRevocationList(existingCRLBlock.Bytes)
if err != nil {
log.Fatal("Failed to parse the existing CRL:", err)
}
for _, revokedCert := range existingCRL.RevokedCertificates {
serialKey := revokedCert.SerialNumber.String()
if existingSerialNumbers[serialKey] {
continue
}
revokedCerts = append(revokedCerts, revokedCert)
existingSerialNumbers[serialKey] = true
}
}
desiredLength := 80
randomNumber, err := rand.Int(rand.Reader, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(desiredLength)), nil))
if err != nil {
log.Fatal("Failed to generate a random number:", err)
}
issuanceTime := time.Now()
nextUpdateTime := time.Now().Add(time.Hour*24*365)
issuerKeyPEM, err := os.ReadFile(*key)
if err != nil {
log.Fatal("Failed to read private key file:", err)
}
issuerCertPEM, err := os.ReadFile(*cert)
if err != nil {
log.Fatal("Failed to read certificate file:", err)
}
issuerKey, issuerCert, err := parsePrivateKeyAndCert(issuerKeyPEM, issuerCertPEM)
if err != nil {
log.Fatal("Failed to parse private key and certificate:", err)
}
revocationListTemplate := &x509.RevocationList{
RevokedCertificates: revokedCerts,
Number: randomNumber,
ThisUpdate: issuanceTime,
NextUpdate: nextUpdateTime,
}
var crlBytes []byte
if strings.ToUpper(*alg) == "GOST2012" {
crlBytes, err = x509.CreateRevocationList(rand.Reader, revocationListTemplate, issuerCert, &gost3410.PrivateKeyReverseDigest{Prv: issuerKey.(*gost3410.PrivateKey)})
} else {
crlBytes, err = x509.CreateRevocationList(rand.Reader, revocationListTemplate, issuerCert, issuerKey)
}
if err != nil {
log.Fatal("Failed to create new CRL:", err)
}
pemBlock := &pem.Block{
Type: "X509 CRL",
Bytes: crlBytes,
}
// pemData := pem.EncodeToMemory(pemBlock)
// fmt.Print(string(pemData))
var output *os.File
if flag.Arg(1) == "" {
output = os.Stdout
} else {
file, err := os.Create(flag.Arg(1))
if err != nil {
log.Fatal(err)
}
defer file.Close()
output = file
}
pem.Encode(output, pemBlock)
}
if (*pkey == "crl") && *key != "" && *cert != "" && strings.ToUpper(*alg) == "SM2" {
revokedCerts := make([]pkix.RevokedCertificate, 0)
scanner := bufio.NewScanner(inputfile)
existingSerialNumbers := make(map[string]bool)
for scanner.Scan() {
serialStr := strings.TrimSpace(scanner.Text())
serialNumber, success := new(big.Int).SetString(serialStr, 16)
if !success {
log.Fatalf("Invalid serial number: %s", serialStr)
}
serialKey := serialNumber.String()
if existingSerialNumbers[serialKey] {
continue
}
revocationTime := time.Now()
revokedCert := pkix.RevokedCertificate{
SerialNumber: serialNumber,
RevocationTime: revocationTime,
}
revokedCerts = append(revokedCerts, revokedCert)
existingSerialNumbers[serialKey] = true
}
if err := scanner.Err(); err != nil {
log.Fatal("Failed to read serials.txt:", err)
}
if *crl != "" {
existingCRLData, err := ioutil.ReadFile(*crl)
if err != nil {
log.Fatal("Failed to read the existing CRL file:", err)
}
existingCRLBlock, _ := pem.Decode(existingCRLData)
if existingCRLBlock == nil {
log.Fatal("Failed to decode the PEM block of the existing CRL")
}
existingCRL, err := x509.ParseRevocationList(existingCRLBlock.Bytes)
if err != nil {
log.Fatal("Failed to parse the existing CRL:", err)
}
for _, revokedCert := range existingCRL.RevokedCertificates {
serialKey := revokedCert.SerialNumber.String()
if existingSerialNumbers[serialKey] {
continue
}
revokedCerts = append(revokedCerts, revokedCert)
existingSerialNumbers[serialKey] = true
}
}
desiredLength := 80
randomNumber, err := rand.Int(rand.Reader, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(desiredLength)), nil))
if err != nil {
log.Fatal("Failed to generate a random number:", err)
}
issuanceTime := time.Now()
nextUpdateTime := time.Now().Add(time.Hour*24*365)
revocationListTemplate := &x509.RevocationList{
RevokedCertificates: revokedCerts,
Number: randomNumber,
ThisUpdate: issuanceTime,
NextUpdate: nextUpdateTime,
}
issuerKeyPEM, err := os.ReadFile(*key)
if err != nil {
log.Fatal("Failed to read private key file:", err)
}
issuerCertPEM, err := os.ReadFile(*cert)
if err != nil {
log.Fatal("Failed to read certificate file:", err)
}
issuerKey, issuerCert, err := parsePrivateKeyAndCertSM2(issuerKeyPEM, issuerCertPEM)
if err != nil {
log.Fatal("Failed to parse private key and certificate:", err)
}
var crlBytes []byte
crlBytes, err = smx509.CreateRevocationList(rand.Reader, revocationListTemplate, issuerCert, issuerKey)
if err != nil {
log.Fatal("Failed to create new CRL:", err)
}
pemBlock := &pem.Block{
Type: "X509 CRL",
Bytes: crlBytes,
}
// pemData := pem.EncodeToMemory(pemBlock)
// fmt.Print(string(pemData))
var output *os.File
if flag.Arg(1) == "" {
output = os.Stdout
} else {
file, err := os.Create(flag.Arg(1))
if err != nil {
log.Fatal(err)
}
defer file.Close()
output = file
}
pem.Encode(output, pemBlock)
}
if *pkey == "validate" {
crlBytes, err := ioutil.ReadFile(*crl)
if err != nil {
log.Fatal("Failed to read CRL file:", err)
}
pemBlock, _ := pem.Decode(crlBytes)
if pemBlock == nil {
log.Fatal("Failed to decode CRL PEM block")
}
crl, err := x509.ParseDERCRL(pemBlock.Bytes)
if err != nil {
log.Fatal("Failed to parse CRL:", err)
}
certBytes, err := ioutil.ReadFile(*cert)
if err != nil {
log.Fatal("Failed to read certificate file:", err)
}
pemBlock, _ = pem.Decode(certBytes)
if pemBlock == nil {
log.Fatal("Failed to decode certificate PEM block")
}
cert, err := x509.ParseCertificate(pemBlock.Bytes)
if err != nil {
cert, err := smx509.ParseCertificate(pemBlock.Bytes)
if err != nil {
log.Fatal("Failed to parse certificate:", err)
}
isRevoked, revocationTime := isCertificateRevokedSM2(cert, crl)
if isRevoked {
fmt.Println("The certificate is revoked")
fmt.Println("Revocation Time:", revocationTime)
os.Exit(1)
} else {
fmt.Println("The certificate is not revoked")
os.Exit(0)
}
}
isRevoked, revocationTime := isCertificateRevoked(cert, crl)
if isRevoked {
fmt.Println("The certificate is revoked")
fmt.Println("Revocation Time:", revocationTime)
os.Exit(1)
} else {
fmt.Println("The certificate is not revoked")
os.Exit(0)
}
}
if (*pkey == "check") && *crl != "" {
crlBytes, err := ioutil.ReadFile(*crl)
if err != nil {
log.Fatal("Failed to read CRL file:", err)
}
pemBlock, _ := pem.Decode(crlBytes)
if pemBlock == nil {
log.Fatal("Failed to decode CRL PEM block")
}
revocationList, err := x509.ParseDERCRL(pemBlock.Bytes)
if err != nil {
log.Fatal("Failed to parse CRL:", err)
}
issuerCertBytes, err := ioutil.ReadFile(*cert)
if err != nil {
log.Fatal("Failed to read issuer's certificate file:", err)
}
issuerCertBlock, _ := pem.Decode(issuerCertBytes)
if issuerCertBlock == nil {
log.Fatal("Failed to decode PEM block of issuer's certificate")
}
issuerCert, err := x509.ParseCertificate(issuerCertBlock.Bytes)
if err != nil {
issuerCert, err := smx509.ParseCertificate(issuerCertBlock.Bytes)
if err != nil {
log.Fatal("Failed to parse issuer's certificate:", err)
}
err = issuerCert.CheckCRLSignature(revocationList)
if err != nil {
log.Fatal("Verified: false: ", err)
}
fmt.Println("Verified: true")
os.Exit(0)
}
err = issuerCert.CheckCRLSignature(revocationList)
if err != nil {
log.Fatal("Verified: false: ", err)
}
fmt.Println("Verified: true")
}
if (*pkey == "text") && *crl != "" {
pemData, err := ioutil.ReadFile(*crl)
if err != nil {
log.Fatal("Failed to read the CRL file:", err)
}
pemBlock, _ := pem.Decode(pemData)
if pemBlock == nil {
log.Fatal("Failed to decode the PEM block")
}
revocationList, err := x509.ParseRevocationList(pemBlock.Bytes)
if err != nil {
log.Fatal("Failed to parse the CRL:", err)
}
akid := getAuthorityKeyIdentifierFromCRL(revocationList)
crl, err := x509.ParseDERCRL(pemBlock.Bytes)
if err != nil {
log.Fatal("Failed to parse the CRL:", err)
}
fmt.Println("CRL:")
fmt.Println(" Data:")
fmt.Printf(" Number : %d (%X)\n", revocationList.Number, revocationList.Number)
fmt.Println(" Last Update :", crl.TBSCertList.ThisUpdate)
fmt.Println(" Next Update :", crl.TBSCertList.NextUpdate)
fmt.Println(" Issuer")
fmt.Println(" ", crl.TBSCertList.Issuer)
fmt.Printf(" Authority Key ID : %x\n", akid)
// fmt.Println(" Algorithm OID :", crl.SignatureAlgorithm.Algorithm.String())
algoName := getAlgorithmName(crl.SignatureAlgorithm.Algorithm.String())
fmt.Println(" Signature Algorithm:", algoName)
// fmt.Println(" Signature:")
splitz := SplitSubN(hex.EncodeToString(crl.SignatureValue.Bytes), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s \n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println(" Revoked Certificates:")
for _, revokedCert := range revocationList.RevokedCertificates {
fmt.Printf(" - Serial Number: %X\n", revokedCert.SerialNumber)
fmt.Println(" Revocation Time:", revokedCert.RevocationTime)
}
}
if (*pkey == "text" || *pkey == "modulus") && PEM == "CertificateRequest" {
var certPEM []byte
file, err := os.Open(*cert)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
certPEM = buf
var certPemBlock, _ = pem.Decode([]byte(certPEM))
var certa, _ = smx509.ParseCertificateRequest(certPemBlock.Bytes)
signature := fmt.Sprintf("%s", certa.SignatureAlgorithm)
if signature == "ECDSA-SHA256" || signature == "ECDSA-SHA384" || signature == "ECDSA-SHA512" {
*alg = "EC"
} else if signature == "99" {
*alg = "SM2"
} else if signature == "Ed25519" {
*alg = "ED25519"
} else if signature == "SHA256-RSA" || signature == "SHA384-RSA" || signature == "SHA512-RSA" {
*alg = "RSA"
} else if signature == "0" {
*alg = "GOST2012"
}
if *pkey == "modulus" && strings.ToUpper(*alg) == "RSA" {
var certaPublicKey = certa.PublicKey.(*rsa.PublicKey)
fmt.Printf("Modulus=%X\n", certaPublicKey.N)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "SM2") {
var certaPublicKey = certa.PublicKey.(*ecdsa.PublicKey)
fmt.Printf("Public.X=%X\n", certaPublicKey.X)
fmt.Printf("Public.Y=%X\n", certaPublicKey.Y)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "ED25519") {
var certaPublicKey = certa.PublicKey.(ed25519.PublicKey)
fmt.Printf("Public=%X\n", certaPublicKey)
os.Exit(0)
} else if *pkey == "modulus" && (strings.ToUpper(*alg) == "GOST2012") {
var certa, _ = x509.ParseCertificateRequest(certPemBlock.Bytes)
var certaPublicKey = certa.PublicKey.(*gost3410.PublicKey)
fmt.Printf("Public.X=%X\n", certaPublicKey.X)
fmt.Printf("Public.Y=%X\n", certaPublicKey.Y)
os.Exit(0)
}
if *alg == "GOST2012" {
var certPEM []byte
file, err := os.Open(*cert)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
certPEM = buf
var certPemBlock, _ = pem.Decode([]byte(certPEM))
certa, _ := x509.ParseCertificateRequest(certPemBlock.Bytes)
if *pkey == "modulus" && (strings.ToUpper(*alg) == "GOST2012") {
var certaPublicKey = certa.PublicKey.(*gost3410.PublicKey)
fmt.Printf("Public.X=%X\n", certaPublicKey.X)
fmt.Printf("Public.Y=%X\n", certaPublicKey.Y)
os.Exit(0)
}
var certaPublicKey = certa.PublicKey.(*gost3410.PublicKey)
var buf2 bytes.Buffer
buf2.Grow(4096)
buf2.WriteString(fmt.Sprintf("Certificate:\n"))
buf2.WriteString(fmt.Sprintf("%4sData:\n", ""))
printVersion(certa.Version, &buf2)
buf2.WriteString(fmt.Sprintf("%8sCommonName : %s \n", "", certa.Subject.CommonName))
buf2.WriteString(fmt.Sprintf("%8sEmailAddresses: %s \n", "", certa.EmailAddresses))
buf2.WriteString(fmt.Sprintf("%8sCurve : %s \n", "", certa.PublicKey.(*gost3410.PublicKey).C.Name))
buf2.WriteString(fmt.Sprintf("%8sSubject\n ", ""))
printName(certa.Subject.Names, &buf2)
x := certaPublicKey.X.Bytes()
c := []byte{}
c = append(c, x...)
buf2.WriteString(fmt.Sprintf("%8sPub.X\n", ""))
splitz := SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
buf2.WriteString(fmt.Sprintf(" %-10s \n", strings.ReplaceAll(chunk, " ", ":")))
}
y := certaPublicKey.Y.Bytes()
c = []byte{}
c = append(c, y...)
buf2.WriteString(fmt.Sprintf("%8sPub.Y\n", ""))
splitz = SplitSubN(hex.EncodeToString(c), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
buf2.WriteString(fmt.Sprintf(" %-10s \n", strings.ReplaceAll(chunk, " ", ":")))
}
printSignature(certa.SignatureAlgorithm, certa.Signature, &buf2)
fmt.Print(buf2.String())
os.Exit(0)
}
result, err := certinfo.CertificateRequestText(certa.ToX509())
if err != nil {
log.Fatal(err)
}
fmt.Print(result)
}
if (*tcpip == "server" || *tcpip == "client") && (strings.ToUpper(*alg) != "SM2" && strings.ToUpper(*alg) != "GOST2012") {
var certPEM []byte
var privPEM []byte
if *key == "" {
var priv interface{}
var err error
if strings.ToUpper(*alg) == "ED25519" {
_, priv, err = ed25519.GenerateKey(rand.Reader)
} else if strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA" {
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
} else if strings.ToUpper(*alg) == "SM2" {
priv, err = sm2.GenerateKey(rand.Reader)
} else if strings.ToUpper(*alg) == "RSA" {
priv, err = rsa.GenerateKey(rand.Reader, 2048)
}
if err != nil {
log.Fatalf("Failed to generate private key: %v", err)
}
keyUsage := smx509.KeyUsageDigitalSignature
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %v", err)
}
consensus := externalip.DefaultConsensus(nil, nil)
ip, _ := consensus.ExternalIP()
Mins := 12
NotAfter := time.Now().Local().Add(time.Minute * time.Duration(Mins))
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
CommonName: "",
// SerialNumber: "",
Country: []string{""},
Province: []string{""},
Locality: []string{""},
Organization: []string{""},
OrganizationalUnit: []string{""},
// StreetAddress: []string{""},
// PostalCode: []string{""},
},
EmailAddresses: []string{email},
NotBefore: time.Now(),
NotAfter: NotAfter,
KeyUsage: keyUsage,
ExtKeyUsage: []smx509.ExtKeyUsage{smx509.ExtKeyUsageClientAuth, smx509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
PermittedDNSDomainsCritical: true,
DNSNames: []string{ip.String()},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
}
template.IsCA = true
template.KeyUsage |= smx509.KeyUsageCertSign
derBytes, err := smx509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
if err != nil {
log.Fatalf("Failed to create certificate: %v", err)
}
certPEM = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
privBytes, err := smx509.MarshalPKCS8PrivateKey(priv)
if err != nil {
log.Fatalf("Unable to marshal private key: %v", err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privBytes})
} else {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
file, err = os.Open(*cert)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
certPEM = buf
}
if *tcpip == "server" {
cert, err := tls.X509KeyPair(certPEM, privPEM)
if err != nil {
log.Fatal(err)
}
cfg := tls.Config{Certificates: []tls.Certificate{cert}, ClientAuth: tls.RequireAnyClientCert, MinVersion: tls.VersionTLS12, MaxVersion: tls.VersionTLS13}
cfg.Rand = rand.Reader
port := "8081"
if *iport != "" {
port = *iport
}
ln, err := tls.Listen("tcp", ":"+port, &cfg)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Server(TLS) up and listening on port "+port)
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
defer ln.Close()
tlscon := conn.(*tls.Conn)
err = tlscon.Handshake()
if err != nil {
log.Fatalf("server: handshake failed: %s", err)
} else {
log.Print("server: conn: Handshake completed")
}
state := tlscon.ConnectionState()
for _, v := range state.PeerCertificates {
derBytes, err := smx509.MarshalPKIXPublicKey(v.PublicKey)
if err != nil {
log.Fatal(err)
}
pubPEM := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: derBytes})
fmt.Printf("%s\n", pubPEM)
}
go handleConnectionTLS(conn)
fmt.Println("Connection accepted")
for {
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Client response: " + string(message))
// newmessage := strings.ToUpper(message)
// conn.Write([]byte(newmessage + "\n"))
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
}
}
if *tcpip == "client" {
cert, err := tls.X509KeyPair(certPEM, privPEM)
if err != nil {
log.Fatal(err)
}
cfg := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true}
ipport := "127.0.0.1:8081"
if *iport != "" {
ipport = *iport
}
conn, err := tls.Dial("tcp", ipport, &cfg)
if err != nil {
log.Fatal(err)
}
certs := conn.ConnectionState().PeerCertificates
for _, cert := range certs {
fmt.Printf("Issuer: \n\t%s\n", cert.Issuer)
fmt.Printf("Subject: \n\t%s\n", cert.Subject)
fmt.Printf("Expiry: %s \n", cert.NotAfter.Format("Monday, 02-Jan-06 15:04:05 MST"))
}
if err != nil {
log.Fatal(err)
}
if conn.ConnectionState().Version == 771 {
fmt.Println("Protocol: TLS v1.2")
} else if conn.ConnectionState().Version == 772 {
fmt.Println("Protocol: TLS v1.3")
}
if conn.ConnectionState().CipherSuite == 0x1301 {
fmt.Println("CipherSuite: TLS_AES_128_GCM_SHA256")
} else if conn.ConnectionState().CipherSuite == 0x1302 {
fmt.Println("CipherSuite: TLS_AES_256_GCM_SHA384")
} else if conn.ConnectionState().CipherSuite == 0x1303 {
fmt.Println("CipherSuite: TLS_CHACHA20_POLY1305_SHA256")
}
if conn.ConnectionState().CipherSuite == 0x0005 {
fmt.Println("CipherSuite: TLS_RSA_WITH_RC4_128_SHA")
} else if conn.ConnectionState().CipherSuite == 0x000a {
fmt.Println("CipherSuite: TLS_RSA_WITH_3DES_EDE_CBC_SHA")
} else if conn.ConnectionState().CipherSuite == 0x002f {
fmt.Println("CipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA")
} else if conn.ConnectionState().CipherSuite == 0x0035 {
fmt.Println("CipherSuite: TLS_RSA_WITH_AES_256_CBC_SHA")
} else if conn.ConnectionState().CipherSuite == 0x003c {
fmt.Println("CipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA256")
} else if conn.ConnectionState().CipherSuite == 0x009c {
fmt.Println("CipherSuite: TLS_RSA_WITH_AES_128_GCM_SHA256")
} else if conn.ConnectionState().CipherSuite == 0x009d {
fmt.Println("CipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384")
} else if conn.ConnectionState().CipherSuite == 0xc007 {
fmt.Println("CipherSuite: TLS_ECDHE_ECDSA_WITH_RC4_128_SHA")
} else if conn.ConnectionState().CipherSuite == 0xc009 {
fmt.Println("CipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA")
} else if conn.ConnectionState().CipherSuite == 0xc00a {
fmt.Println("CipherSuite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA")
} else if conn.ConnectionState().CipherSuite == 0xc011 {
fmt.Println("CipherSuite: TLS_ECDHE_RSA_WITH_RC4_128_SHA")
} else if conn.ConnectionState().CipherSuite == 0xc012 {
fmt.Println("CipherSuite: TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA")
} else if conn.ConnectionState().CipherSuite == 0xc013 {
fmt.Println("CipherSuite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA")
} else if conn.ConnectionState().CipherSuite == 0xc014 {
fmt.Println("CipherSuite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA")
} else if conn.ConnectionState().CipherSuite == 0xc023 {
fmt.Println("CipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256")
} else if conn.ConnectionState().CipherSuite == 0xc027 {
fmt.Println("CipherSuite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256")
} else if conn.ConnectionState().CipherSuite == 0xc02f {
fmt.Println("CipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
} else if conn.ConnectionState().CipherSuite == 0xc02b {
fmt.Println("CipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256")
} else if conn.ConnectionState().CipherSuite == 0xc030 {
fmt.Println("CipherSuite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384")
} else if conn.ConnectionState().CipherSuite == 0xc02c {
fmt.Println("CipherSuite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384")
} else if conn.ConnectionState().CipherSuite == 0xcca8 {
fmt.Println("CipherSuite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256")
} else if conn.ConnectionState().CipherSuite == 0xcca9 {
fmt.Println("CipherSuite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256")
}
defer conn.Close()
var b bytes.Buffer
for _, cert := range conn.ConnectionState().PeerCertificates {
err := pem.Encode(&b, &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
})
if err != nil {
log.Fatal(err)
}
}
fmt.Println(b.String())
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Server response: " + message)
}
}
os.Exit(0)
}
if (*tcpip == "server" || *tcpip == "client") && strings.ToUpper(*alg) == "SM2" && *root != "" {
var sigcertPEM []byte
var sigprivPEM []byte
var enccertPEM []byte
var encprivPEM []byte
var rootPEM []byte
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
sigprivPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
sigprivPEM = buf
}
file, err = os.Open(*cert)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
sigcertPEM = buf
if *tcpip == "server" {
file, err = os.Open(*cakey)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes2 []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes2, err = DecryptPEMBlock(block, []byte(*pwd2))
if err != nil {
log.Fatal(err)
}
encprivPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes2})
} else {
encprivPEM = buf
}
file, err = os.Open(*cacert)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
enccertPEM = buf
}
file, err = os.Open(*root)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
rootPEM = buf
if *tcpip == "server" {
var sigcert tlcp.Certificate
var enccert tlcp.Certificate
sigcert, err = tlcp.X509KeyPair(sigcertPEM, sigprivPEM)
if err != nil {
log.Fatal(err)
}
enccert, err = tlcp.X509KeyPair(enccertPEM, encprivPEM)
if err != nil {
log.Fatal(err)
}
rootCert, err := smx509.ParseCertificatePEM([]byte(rootPEM))
if err != nil {
panic(err)
}
pool := smx509.NewCertPool()
pool.AddCert(rootCert)
cfg := tlcp.Config{
Certificates: []tlcp.Certificate{sigcert, enccert},
ClientAuth: tlcp.RequireAndVerifyClientCert,
ClientCAs: pool,
CipherSuites: []uint16{
tlcp.ECC_SM4_GCM_SM3,
tlcp.ECC_SM4_CBC_SM3,
},
}
cfg.Rand = rand.Reader
port := "8081"
if *iport != "" {
port = *iport
}
ln, err := tlcp.Listen("tcp", ":"+port, &cfg)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Server(TLCP) up and listening on port "+port)
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
defer ln.Close()
tlcpcon := conn.(*tlcp.Conn)
err = tlcpcon.Handshake()
if err != nil {
log.Fatalf("server: handshake failed: %s", err)
} else {
log.Print("server: conn: Handshake completed")
}
state := tlcpcon.ConnectionState()
for _, v := range state.PeerCertificates {
derBytes, err := smx509.MarshalPKIXPublicKey(v.PublicKey)
if err != nil {
log.Fatal(err)
}
pubPEM := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: derBytes})
fmt.Printf("%s\n", pubPEM)
}
go handleConnectionTLCP(conn)
fmt.Println("Connection accepted")
for {
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Client response: " + string(message))
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
}
}
if *tcpip == "client" {
var cert tlcp.Certificate
cert, err = tlcp.X509KeyPair(sigcertPEM, sigprivPEM)
if err != nil {
log.Fatal(err)
}
rootCert, err := smx509.ParseCertificatePEM([]byte(rootPEM))
if err != nil {
panic(err)
}
pool := smx509.NewCertPool()
pool.AddCert(rootCert)
cfg := tlcp.Config{
RootCAs: pool,
Certificates: []tlcp.Certificate{cert},
CipherSuites: []uint16{
tlcp.ECC_SM4_GCM_SM3,
tlcp.ECC_SM4_CBC_SM3,
},
}
ipport := "127.0.0.1:8081"
if *iport != "" {
ipport = *iport
}
conn, err := tlcp.Dial("tcp", ipport, &cfg)
if err != nil {
log.Fatal(err)
}
certa := conn.ConnectionState().PeerCertificates
for _, cert := range certa {
fmt.Printf("Issuer: \n\t%s\n", cert.Issuer)
fmt.Printf("Subject: \n\t%s\n", cert.Subject)
fmt.Printf("Expiry: %s \n", cert.NotAfter.Format("Monday, 02-Jan-06 15:04:05 MST"))
}
defer conn.Close()
fmt.Println("Protocol: TLCP")
if conn.ConnectionState().CipherSuite == 57427 {
fmt.Println("CipherSuite: ECC_SM4_GCM_SM3")
} else if conn.ConnectionState().CipherSuite == 57363 {
fmt.Println("CipherSuite: ECC_SM4_CBC_SM3")
}
var b bytes.Buffer
for _, cert := range conn.ConnectionState().PeerCertificates {
err := pem.Encode(&b, &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
})
if err != nil {
log.Fatal(err)
}
}
fmt.Println(b.String())
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Server response: " + message)
}
}
os.Exit(0)
}
if (*tcpip == "server" || *tcpip == "client") && strings.ToUpper(*alg) == "SM2" && *root == "" {
var sigcertPEM []byte
var sigprivPEM []byte
var enccertPEM []byte
var encprivPEM []byte
if *tcpip == "server" {
file, err := os.Open(*key)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
log.Fatal(err)
}
sigprivPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
sigprivPEM = buf
}
file, err = os.Open(*cert)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
sigcertPEM = buf
file, err = os.Open(*cakey)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes2 []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes2, err = DecryptPEMBlock(block, []byte(*pwd2))
if err != nil {
log.Fatal(err)
}
encprivPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes2})
} else {
encprivPEM = buf
}
file, err = os.Open(*cacert)
if err != nil {
log.Fatal(err)
}
info, err = file.Stat()
if err != nil {
log.Fatal(err)
}
buf = make([]byte, info.Size())
file.Read(buf)
enccertPEM = buf
}
if *tcpip == "server" {
var sigcert tlcp.Certificate
var enccert tlcp.Certificate
sigcert, err = tlcp.X509KeyPair(sigcertPEM, sigprivPEM)
if err != nil {
log.Fatal(err)
}
enccert, err = tlcp.X509KeyPair(enccertPEM, encprivPEM)
if err != nil {
log.Fatal(err)
}
cfg := tlcp.Config{
Certificates: []tlcp.Certificate{sigcert, enccert},
CipherSuites: []uint16{
tlcp.ECC_SM4_GCM_SM3,
tlcp.ECC_SM4_CBC_SM3,
},
}
cfg.Rand = rand.Reader
port := "8081"
if *iport != "" {
port = *iport
}
ln, err := tlcp.Listen("tcp", ":"+port, &cfg)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(os.Stderr, "Server(TLCP) up and listening on port "+port)
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
defer ln.Close()
tlcpcon := conn.(*tlcp.Conn)
err = tlcpcon.Handshake()
if err != nil {
log.Fatalf("server: handshake failed: %s", err)
} else {
log.Print("server: conn: Handshake completed")
}
state := tlcpcon.ConnectionState()
for _, v := range state.PeerCertificates {
derBytes, err := smx509.MarshalPKIXPublicKey(v.PublicKey)
if err != nil {
log.Fatal(err)
}
pubPEM := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: derBytes})
fmt.Printf("%s\n", pubPEM)
}
go handleConnectionTLCP(conn)
fmt.Println("Connection accepted")
for {
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Client response: " + string(message))
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
}
}
if *tcpip == "client" {
cfg := tlcp.Config{InsecureSkipVerify: true}
cfg.Rand = rand.Reader
ipport := "127.0.0.1:8081"
if *iport != "" {
ipport = *iport
}
conn, err := tlcp.Dial("tcp", ipport, &cfg)
if err != nil {
log.Fatal(err)
}
certa := conn.ConnectionState().PeerCertificates
for _, cert := range certa {
fmt.Printf("Issuer: \n\t%s\n", cert.Issuer)
fmt.Printf("Subject: \n\t%s\n", cert.Subject)
fmt.Printf("Expiry: %s \n", cert.NotAfter.Format("Monday, 02-Jan-06 15:04:05 MST"))
}
defer conn.Close()
fmt.Println("Protocol: TLCP")
if conn.ConnectionState().CipherSuite == 57427 {
fmt.Println("CipherSuite: ECC_SM4_GCM_SM3")
} else if conn.ConnectionState().CipherSuite == 57363 {
fmt.Println("CipherSuite: ECC_SM4_CBC_SM3")
}
var b bytes.Buffer
for _, cert := range conn.ConnectionState().PeerCertificates {
err := pem.Encode(&b, &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
})
if err != nil {
log.Fatal(err)
}
}
fmt.Println(b.String())
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to be sent: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Fprintf(conn, text+"\n")
message, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
fmt.Println(err)
os.Exit(3)
}
fmt.Print("Server response: " + message)
}
}
os.Exit(0)
}
if *change {
err := ChangePrivateKeyPassword(*key, *pwd, *pwd2)
if err != nil {
fmt.Println("Error changing the password:", err)
} else {
fmt.Println("Password changed successfully.")
}
}
if *tcpip == "ip" {
consensus := externalip.DefaultConsensus(nil, nil)
ip, _ := consensus.ExternalIP()
fmt.Println(ip.String())
os.Exit(0)
}
}
func SignatureRSA(sourceData []byte) ([]byte, error) {
msg := []byte("")
file, err := os.Open(*key)
if err != nil {
return msg, err
}
info, err := file.Stat()
if err != nil {
return msg, err
}
buf := make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
return nil, errors.New("no valid private key found")
}
var privateKey *rsa.PrivateKey
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privateKey, err = x509.ParsePKCS1PrivateKey(privKeyBytes)
if err != nil {
return nil, fmt.Errorf("could not parse DER encoded key: %v", err)
}
} else {
privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return msg, err
}
}
var myHash hash.Hash
if *md == "md5" {
myHash = md5.New()
} else if *md == "sha224" {
myHash = sha256.New224()
} else if *md == "sha256" {
myHash = sha256.New()
} else if *md == "sha384" {
myHash = sha512.New384()
} else if *md == "sha512" {
myHash = sha512.New()
} else if *md == "sha1" {
myHash = sha1.New()
} else if *md == "rmd160" || *md == "ripemd160" {
myHash = ripemd160.New()
}
myHash.Write(sourceData)
hashRes := myHash.Sum(nil)
var res []byte
if *md == "md5" {
res, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.MD5, hashRes)
if err != nil {
return msg, err
}
} else if *md == "rmd160" || *md == "ripemd160" {
res, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.RIPEMD160, hashRes)
if err != nil {
return msg, err
}
} else if *md == "sha1" {
res, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA1, hashRes)
if err != nil {
return msg, err
}
} else if *md == "sha224" {
res, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA224, hashRes)
if err != nil {
return msg, err
}
} else if *md == "sha256" {
res, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashRes)
if err != nil {
return msg, err
}
} else if *md == "sha384" {
res, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA384, hashRes)
if err != nil {
return msg, err
}
} else if *md == "sha512" {
res, err = rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA512, hashRes)
if err != nil {
return msg, err
}
}
defer file.Close()
return res, nil
}
func VerifyRSA(sourceData, signedData []byte) error {
file, err := os.Open(*key)
if err != nil {
return err
}
info, err := file.Stat()
if err != nil {
return err
}
buf := make([]byte, info.Size())
file.Read(buf)
block, _ := pem.Decode(buf)
publicInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return err
}
publicKey := publicInterface.(*rsa.PublicKey)
var mySha hash.Hash
if *md == "md5" {
mySha = md5.New()
} else if *md == "sha224" {
mySha = sha256.New224()
} else if *md == "sha256" {
mySha = sha256.New()
} else if *md == "sha384" {
mySha = sha512.New384()
} else if *md == "sha512" {
mySha = sha512.New()
} else if *md == "sha1" {
mySha = sha1.New()
} else if *md == "rmd160" || *md == "ripemd160" {
mySha = ripemd160.New()
}
mySha.Write(sourceData)
res := mySha.Sum(nil)
if *md == "md5" {
err = rsa.VerifyPKCS1v15(publicKey, crypto.MD5, res, signedData)
if err != nil {
return err
}
} else if *md == "rmd160" || *md == "ripemd160" {
err = rsa.VerifyPKCS1v15(publicKey, crypto.RIPEMD160, res, signedData)
if err != nil {
return err
}
} else if *md == "sha1" {
err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA1, res, signedData)
if err != nil {
return err
}
} else if *md == "sha224" {
err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA224, res, signedData)
if err != nil {
return err
}
} else if *md == "sha256" {
err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, res, signedData)
if err != nil {
return err
}
} else if *md == "sha384" {
err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA384, res, signedData)
if err != nil {
return err
}
} else if *md == "sha512" {
err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA512, res, signedData)
if err != nil {
return err
}
}
defer file.Close()
return nil
}
func GenerateRsaKey(bit int) error {
private, err := rsa.GenerateKey(rand.Reader, bit)
if err != nil {
return err
}
privateStream := x509.MarshalPKCS1PrivateKey(private)
block := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privateStream,
}
file, err := os.Create(*priv)
if err != nil {
return err
}
if *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
return err
}
}
public := private.PublicKey
publicStream, err := x509.MarshalPKIXPublicKey(&public)
if err != nil {
return err
}
pubblock := pem.Block{Type: "PUBLIC KEY", Bytes: publicStream}
pubfile, err := os.Create(*pub)
if err != nil {
return err
}
err = pem.Encode(pubfile, &pubblock)
if err != nil {
return err
}
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
// print("\n")
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err = os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
printKeyDetails(&pubblock)
randomArt := randomart.FromString(string(buf))
println(randomArt)
return nil
}
func EncodeSM2PrivateKey(key *sm2.PrivateKey) ([]byte, error) {
derKey, err := smx509.MarshalSM2PrivateKey(key)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeSM2PrivateKey(encodedKey []byte) (*sm2.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "EC PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *sm2.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = smx509.ParseSM2PrivateKey(privKeyBytes)
} else {
privKey, _ = smx509.ParseSM2PrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodePrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
derKey, err := x509.MarshalECPrivateKey(key)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodePrivateKey(encodedKey []byte) (*ecdsa.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "EC PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *ecdsa.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = smx509.ParseECPrivateKey(privKeyBytes)
} else {
privKey, _ = smx509.ParseECPrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodePublicKey(key *ecdsa.PublicKey) ([]byte, error) {
derBytes, err := smx509.MarshalPKIXPublicKey(key)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodePublicKey(encodedKey []byte) (*ecdsa.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := smx509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
ecdsaPub, ok := public.(*ecdsa.PublicKey)
if !ok {
return nil, errors.New("marshal: data was not an ECDSA public key")
}
return ecdsaPub, nil
}
func EncodeECKCDSAPrivateKey(key *eckcdsa.PrivateKey) ([]byte, error) {
derKey, err := kx509.MarshalPKCS8PrivateKey(key)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "ECKCDSA PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeECKCDSAPrivateKey(encodedKey []byte) (*eckcdsa.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "ECKCDSA PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *eckcdsa.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
} else {
privKeyBytes = block.Bytes
}
// Análise do PKCS8PrivateKey
parsedKey, err := kx509.ParsePKCS8PrivateKey(privKeyBytes)
if err != nil {
return nil, fmt.Errorf("failed to parse PKCS#8 private key: %v", err)
}
// Asserção do tipo
privKey, ok := parsedKey.(*eckcdsa.PrivateKey)
if !ok {
return nil, fmt.Errorf("parsed key is not of type *eckcdsa.PrivateKey")
}
return privKey, nil
}
func EncodeECKCDSAPublicKey(key *eckcdsa.PublicKey) ([]byte, error) {
derBytes, err := kx509.MarshalPKIXPublicKey(key)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "ECKCDSA PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeECKCDSAPublicKey(encodedKey []byte) (*eckcdsa.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "ECKCDSA PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
// Analisar o PKIX public key
publicKey, err := kx509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
// Asserção do tipo
eckcdsaPublicKey, ok := publicKey.(*eckcdsa.PublicKey)
if !ok {
return nil, fmt.Errorf("parsed key is not of type *eckcdsa.PublicKey")
}
return eckcdsaPublicKey, nil
}
func EncodeECGDSAPrivateKey(key *ecgdsa.PrivateKey) ([]byte, error) {
derKey, err := ecgdsa.MarshalPrivateKey(key)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "ECGDSA PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeECGDSAPrivateKey(encodedKey []byte) (*ecgdsa.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "ECGDSA PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *ecgdsa.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = ecgdsa.ParsePrivateKey(privKeyBytes)
} else {
privKey, _ = ecgdsa.ParsePrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodeECGDSAPublicKey(key *ecgdsa.PublicKey) ([]byte, error) {
derBytes, err := ecgdsa.MarshalPublicKey(key)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "ECGDSA PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeECGDSAPublicKey(encodedKey []byte) (*ecgdsa.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "ECGDSA PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := ecgdsa.ParsePublicKey(block.Bytes)
if err != nil {
return nil, err
}
return public, nil
}
func EncodeECSDSAPrivateKey(key *ecsdsa.PrivateKey) ([]byte, error) {
derKey, err := ecsdsa.MarshalPrivateKey(key)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "ECSDSA PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeECSDSAPrivateKey(encodedKey []byte) (*ecsdsa.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "ECSDSA PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *ecsdsa.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = ecsdsa.ParsePrivateKey(privKeyBytes)
} else {
privKey, _ = ecsdsa.ParsePrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodeECSDSAPublicKey(key *ecsdsa.PublicKey) ([]byte, error) {
derBytes, err := ecsdsa.MarshalPublicKey(key)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "ECSDSA PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeECSDSAPublicKey(encodedKey []byte) (*ecsdsa.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "ECSDSA PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := ecsdsa.ParsePublicKey(block.Bytes)
if err != nil {
return nil, err
}
return public, nil
}
func EncodeBIP0340PrivateKey(key *bip0340.PrivateKey) ([]byte, error) {
derKey, err := bip0340.MarshalPrivateKey(key)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "BIP0340 PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeBIP0340PrivateKey(encodedKey []byte) (*bip0340.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "BIP0340 PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *bip0340.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = bip0340.ParsePrivateKey(privKeyBytes)
} else {
privKey, _ = bip0340.ParsePrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodeBIP0340PublicKey(key *bip0340.PublicKey) ([]byte, error) {
derBytes, err := bip0340.MarshalPublicKey(key)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "BIP0340 PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeBIP0340PublicKey(encodedKey []byte) (*bip0340.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "BIP0340 PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := bip0340.ParsePublicKey(block.Bytes)
if err != nil {
return nil, err
}
return public, nil
}
func EncodeBIGNPrivateKey(key *bign.PrivateKey) ([]byte, error) {
derKey, err := bign.MarshalPrivateKey(key)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "BIGN PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeBIGNPrivateKey(encodedKey []byte) (*bign.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "BIGN PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *bign.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = bign.ParsePrivateKey(privKeyBytes)
} else {
privKey, _ = bign.ParsePrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodeBIGNPublicKey(key *bign.PublicKey) ([]byte, error) {
derBytes, err := bign.MarshalPublicKey(key)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "BIGN PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeBIGNPublicKey(encodedKey []byte) (*bign.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "BIGN PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := bign.ParsePublicKey(block.Bytes)
if err != nil {
return nil, err
}
return public, nil
}
// EncodePrivateKey encodes a NUMS private key in PEM format.
func EncodeNUMSPrivateKey(key *nums.PrivateKey) ([]byte, error) {
// curve := determineCurveFromPrivateKey(key)
derKey, err := key.MarshalPKCS8PrivateKey(key.PublicKey.Curve)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "NUMS PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeNUMSPrivateKey(encodedKey []byte) (*nums.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "NUMS PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *nums.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = nums.ParsePrivateKey(privKeyBytes)
} else {
privKey, _ = nums.ParsePrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodeNUMSPublicKey(key *nums.PublicKey) ([]byte, error) {
// curve := determineCurve(key)
curve := key.Curve
if curve == nil {
return nil, errors.New("unsupported key length")
}
derBytes, err := key.MarshalPKCS8PublicKey(curve)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "NUMS PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeNUMSPublicKey(encodedKey []byte) (*nums.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "NUMS PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := nums.ParsePublicKey(block.Bytes)
if err != nil {
return nil, err
}
return public, nil
}
// EncodePrivateKey encodes a ANSSI private key in PEM format.
func EncodeANSSIPrivateKey(key *frp256v1.PrivateKey) ([]byte, error) {
// curve := determineCurveFromPrivateKey(key)
derKey, err := key.MarshalPKCS8PrivateKey(key.PublicKey.Curve)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "ANSSI PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeANSSIPrivateKey(encodedKey []byte) (*frp256v1.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "ANSSI PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *frp256v1.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = frp256v1.ParsePrivateKey(privKeyBytes)
} else {
privKey, _ = frp256v1.ParsePrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodeANSSIPublicKey(key *frp256v1.PublicKey) ([]byte, error) {
// curve := determineCurve(key)
curve := key.Curve
if curve == nil {
return nil, errors.New("unsupported key length")
}
derBytes, err := key.MarshalPKCS8PublicKey(curve)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "ANSSI PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeANSSIPublicKey(encodedKey []byte) (*frp256v1.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "ANSSI PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := frp256v1.ParsePublicKey(block.Bytes)
if err != nil {
return nil, err
}
return public, nil
}
// EncodePrivateKey encodes a KOBLITZ private key in PEM format.
func EncodeKOBLITZPrivateKey(key *secp256k1.PrivateKey) ([]byte, error) {
// curve := determineCurveFromPrivateKey(key)
derKey, err := key.MarshalPKCS8PrivateKey(key.PublicKey.Curve)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "KOBLITZ PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeKOBLITZPrivateKey(encodedKey []byte) (*secp256k1.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "KOBLITZ PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *secp256k1.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = secp256k1.ParsePrivateKey(privKeyBytes)
} else {
privKey, _ = secp256k1.ParsePrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodeKOBLITZPublicKey(key *secp256k1.PublicKey) ([]byte, error) {
// curve := determineCurve(key)
curve := key.Curve
if curve == nil {
return nil, errors.New("unsupported key length")
}
derBytes, err := key.MarshalPKCS8PublicKey(curve)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "KOBLITZ PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeKOBLITZPublicKey(encodedKey []byte) (*secp256k1.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "KOBLITZ PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := secp256k1.ParsePublicKey(block.Bytes)
if err != nil {
return nil, err
}
return public, nil
}
// EncodePrivateKey encodes a KOBLITZ private key in PEM format.
func EncodeTomPrivateKey(key *tom.PrivateKey) ([]byte, error) {
// curve := determineCurveFromPrivateKey(key)
derKey, err := key.MarshalPKCS8PrivateKey(key.PublicKey.Curve)
if err != nil {
return nil, err
}
keyBlock := &pem.Block{
Type: "TOM PRIVATE KEY",
Bytes: derKey,
}
if *pwd != "" {
encryptedBlock, err := EncryptBlockWithCipher(rand.Reader, keyBlock.Type, keyBlock.Bytes, []byte(*pwd), *cph)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(encryptedBlock), nil
} else {
return pem.EncodeToMemory(keyBlock), nil
}
}
func DecodeTomPrivateKey(encodedKey []byte) (*tom.PrivateKey, error) {
var skippedTypes []string
var block *pem.Block
for {
block, encodedKey = pem.Decode(encodedKey)
if block == nil {
return nil, fmt.Errorf("failed to find EC PRIVATE KEY in PEM data after skipping types %v", skippedTypes)
}
if block.Type == "TOM PRIVATE KEY" {
break
} else {
skippedTypes = append(skippedTypes, block.Type)
continue
}
}
var privKey *tom.PrivateKey
var privKeyBytes []byte
var err error
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, errors.New("could not decrypt private key")
}
privKey, _ = tom.ParsePrivateKey(privKeyBytes)
} else {
privKey, _ = tom.ParsePrivateKey(block.Bytes)
}
return privKey, nil
}
func EncodeTomPublicKey(key *tom.PublicKey) ([]byte, error) {
// curve := determineCurve(key)
curve := key.Curve
if curve == nil {
return nil, errors.New("unsupported key length")
}
derBytes, err := key.MarshalPKCS8PublicKey(curve)
if err != nil {
return nil, err
}
block := &pem.Block{
Type: "TOM PUBLIC KEY",
Bytes: derBytes,
}
return pem.EncodeToMemory(block), nil
}
func DecodeTomPublicKey(encodedKey []byte) (*tom.PublicKey, error) {
block, _ := pem.Decode(encodedKey)
if block == nil || block.Type != "TOM PUBLIC KEY" {
return nil, fmt.Errorf("marshal: could not decode PEM block type %s", block.Type)
}
public, err := tom.ParsePublicKey(block.Bytes)
if err != nil {
return nil, err
}
return public, nil
}
func Hkdf(master, salt, info []byte) ([128]byte, error) {
var myHash func() hash.Hash
switch *md {
case "sha224":
myHash = sha256.New224
case "sha256":
myHash = sha256.New
case "sha384":
myHash = sha512.New384
case "sha512":
myHash = sha512.New
case "sha512-256":
myHash = sha512.New512_256
case "sha1":
myHash = sha1.New
case "rmd160", "ripemd160":
myHash = ripemd160.New
case "rmd128", "ripemd128":
myHash = ripemd.New128
case "rmd256", "ripemd256":
myHash = ripemd.New256
case "rmd320", "ripemd320":
myHash = ripemd.New320
case "sha3-224":
myHash = sha3.New224
case "sha3-256":
myHash = sha3.New256
case "sha3-384":
myHash = sha3.New384
case "sha3-512":
myHash = sha3.New512
case "keccak", "keccak256":
myHash = sha3.NewLegacyKeccak256
case "keccak512":
myHash = sha3.NewLegacyKeccak512
case "shake128":
myHash = func() hash.Hash {
return sha3.NewShake128()
}
case "shake256":
myHash = func() hash.Hash {
return sha3.NewShake256()
}
case "lsh224", "lsh256-224":
myHash = lsh256.New224
case "lsh", "lsh256", "lsh256-256":
myHash = lsh256.New
case "lsh512-256":
myHash = lsh512.New256
case "lsh512-224":
myHash = lsh512.New224
case "lsh384", "lsh512-384":
myHash = lsh512.New384
case "lsh512":
myHash = lsh512.New
case "has160":
myHash = has160.New
case "whirlpool":
myHash = whirlpool.New
case "blake2b256":
myHash = crypto.BLAKE2b_256.New
case "blake2b512":
myHash = crypto.BLAKE2b_512.New
case "blake2s256":
myHash = crypto.BLAKE2s_256.New
case "blake3":
myHash = func() hash.Hash {
return blake3.New()
}
case "md5":
myHash = md5.New
case "gost94":
myHash = func() hash.Hash {
return gost341194.New(&gost28147.SboxIdGostR341194CryptoProParamSet)
}
case "streebog", "streebog256":
myHash = gost34112012256.New
case "streebog512":
myHash = gost34112012512.New
case "sm3":
myHash = sm3.New
case "md4":
myHash = md4.New
case "cubehash", "cubehash512":
myHash = cubehash.New
case "cubehash256":
myHash = cubehash256.New
case "xoodyak", "xhash":
myHash = xoodyak.NewXoodyakHash
case "skein", "skein256":
myHash = func() hash.Hash {
return skein.New256(nil)
}
case "skein512":
myHash = func() hash.Hash {
return skein.New512(nil)
}
case "jh224":
myHash = jh.New224
case "jh", "jh256":
myHash = jh.New256
case "jh384":
myHash = jh.New384
case "jh512":
myHash = jh.New512
case "groestl224":
myHash = groestl.New224
case "groestl", "groestl256":
myHash = groestl.New256
case "groestl384":
myHash = groestl.New384
case "groestl512":
myHash = groestl.New512
case "tiger":
myHash = tiger.New
case "tiger2":
myHash = tiger.New2
case "kupyna256", "kupyna":
myHash = kupyna.New256
case "kupyna384":
myHash = kupyna.New384
case "kupyna512":
myHash = kupyna.New512
case "echo224":
myHash = echo.New224
case "echo", "echo256":
myHash = echo.New256
case "echo384":
myHash = echo.New384
case "echo512":
myHash = echo.New512
case "esch", "esch256":
myHash = esch.New256
case "esch384":
myHash = esch.New384
case "bmw224":
myHash = bmw.New224
case "bmw", "bmw256":
myHash = bmw.New256
case "bmw384":
myHash = bmw.New384
case "bmw512":
myHash = bmw.New512
case "hamsi224":
myHash = hamsi.New224
case "hamsi", "hamsi256":
myHash = hamsi.New256
case "hamsi384":
myHash = hamsi.New384
case "hamsi512":
myHash = hamsi.New512
case "fugue224":
myHash = fugue.New224
case "fugue", "fugue256":
myHash = fugue.New256
case "fugue384":
myHash = fugue.New384
case "fugue512":
myHash = fugue.New512
case "luffa224":
myHash = luffa.New224
case "luffa", "luffa256":
myHash = luffa.New256
case "luffa384":
myHash = luffa.New384
case "luffa512":
myHash = luffa.New512
case "shavite224":
myHash = shavite.New224
case "shavite", "shavite256":
myHash = shavite.New256
case "shavite384":
myHash = shavite.New384
case "shavite512":
myHash = shavite.New512
case "simd224":
myHash = simd.New224
case "simd", "simd256":
myHash = simd.New256
case "simd384":
myHash = simd.New384
case "simd512":
myHash = simd.New512
case "radiogatun", "radiogatun32":
myHash = radio_gatun.New32
case "radiogatun64":
myHash = radio_gatun.New64
case "md6-224":
myHash = md6.New224
case "md6", "md6-256":
myHash = md6.New256
case "md6-384":
myHash = md6.New384
case "md6-512":
myHash = md6.New512
case "belt":
myHash = belthash.New
case "bash224":
myHash = bash.New224
case "bash", "bash256":
myHash = bash.New256
case "bash384":
myHash = bash.New384
case "bash512":
myHash = bash.New512
case "ginga":
myHash = gingaHash.New
}
hkdf := hkdf.New(myHash, master, salt, info)
key := make([]byte, *length/8)
_, err := io.ReadFull(hkdf, key)
var result [128]byte
copy(result[:], key)
return result, err
}
func Scrypt(password, salt []byte, N, r, p, keyLen int) ([]byte, error) {
if N <= 1 || N&(N-1) != 0 {
return nil, errors.New("scrypt: N must be > 1 and a power of 2")
}
if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r {
return nil, errors.New("scrypt: parameters are too large")
}
var myHash func() hash.Hash
switch *md {
case "sha224":
myHash = sha256.New224
case "sha256":
myHash = sha256.New
case "sha384":
myHash = sha512.New384
case "sha512":
myHash = sha512.New
case "sha512-256":
myHash = sha512.New512_256
case "sha1":
myHash = sha1.New
case "rmd160", "ripemd160":
myHash = ripemd160.New
case "rmd128", "ripemd128":
myHash = ripemd.New128
case "rmd256", "ripemd256":
myHash = ripemd.New256
case "rmd320", "ripemd320":
myHash = ripemd.New320
case "sha3-224":
myHash = sha3.New224
case "sha3-256":
myHash = sha3.New256
case "sha3-384":
myHash = sha3.New384
case "sha3-512":
myHash = sha3.New512
case "keccak", "keccak256":
myHash = sha3.NewLegacyKeccak256
case "keccak512":
myHash = sha3.NewLegacyKeccak512
case "shake128":
myHash = func() hash.Hash {
return sha3.NewShake128()
}
case "shake256":
myHash = func() hash.Hash {
return sha3.NewShake256()
}
case "lsh224", "lsh256-224":
myHash = lsh256.New224
case "lsh", "lsh256", "lsh256-256":
myHash = lsh256.New
case "lsh512-256":
myHash = lsh512.New256
case "lsh512-224":
myHash = lsh512.New224
case "lsh384", "lsh512-384":
myHash = lsh512.New384
case "lsh512":
myHash = lsh512.New
case "has160":
myHash = has160.New
case "whirlpool":
myHash = whirlpool.New
case "blake2b256":
myHash = crypto.BLAKE2b_256.New
case "blake2b512":
myHash = crypto.BLAKE2b_512.New
case "blake2s256":
myHash = crypto.BLAKE2s_256.New
case "blake3":
myHash = func() hash.Hash {
return blake3.New()
}
case "md5":
myHash = md5.New
case "gost94":
myHash = func() hash.Hash {
return gost341194.New(&gost28147.SboxIdGostR341194CryptoProParamSet)
}
case "streebog", "streebog256":
myHash = gost34112012256.New
case "streebog512":
myHash = gost34112012512.New
case "sm3":
myHash = sm3.New
case "md4":
myHash = md4.New
case "cubehash", "cubehash512":
myHash = cubehash.New
case "cubehash256":
myHash = cubehash256.New
case "xoodyak", "xhash":
myHash = xoodyak.NewXoodyakHash
case "skein", "skein256":
myHash = func() hash.Hash {
return skein.New256(nil)
}
case "skein512":
myHash = func() hash.Hash {
return skein.New512(nil)
}
case "jh224":
myHash = jh.New224
case "jh", "jh256":
myHash = jh.New256
case "jh384":
myHash = jh.New384
case "jh512":
myHash = jh.New512
case "groestl224":
myHash = groestl.New224
case "groestl", "groestl256":
myHash = groestl.New256
case "groestl384":
myHash = groestl.New384
case "groestl512":
myHash = groestl.New512
case "tiger":
myHash = tiger.New
case "tiger2":
myHash = tiger.New2
case "kupyna256", "kupyna":
myHash = kupyna.New256
case "kupyna384":
myHash = kupyna.New384
case "kupyna512":
myHash = kupyna.New512
case "echo224":
myHash = echo.New224
case "echo", "echo256":
myHash = echo.New256
case "echo384":
myHash = echo.New384
case "echo512":
myHash = echo.New512
case "esch", "esch256":
myHash = esch.New256
case "esch384":
myHash = esch.New384
case "bmw224":
myHash = bmw.New224
case "bmw", "bmw256":
myHash = bmw.New256
case "bmw384":
myHash = bmw.New384
case "bmw512":
myHash = bmw.New512
case "hamsi224":
myHash = hamsi.New224
case "hamsi", "hamsi256":
myHash = hamsi.New256
case "hamsi384":
myHash = hamsi.New384
case "hamsi512":
myHash = hamsi.New512
case "fugue224":
myHash = fugue.New224
case "fugue", "fugue256":
myHash = fugue.New256
case "fugue384":
myHash = fugue.New384
case "fugue512":
myHash = fugue.New512
case "luffa224":
myHash = luffa.New224
case "luffa", "luffa256":
myHash = luffa.New256
case "luffa384":
myHash = luffa.New384
case "luffa512":
myHash = luffa.New512
case "shavite224":
myHash = shavite.New224
case "shavite", "shavite256":
myHash = shavite.New256
case "shavite384":
myHash = shavite.New384
case "shavite512":
myHash = shavite.New512
case "simd224":
myHash = simd.New224
case "simd", "simd256":
myHash = simd.New256
case "simd384":
myHash = simd.New384
case "simd512":
myHash = simd.New512
case "radiogatun", "radiogatun32":
myHash = radio_gatun.New32
case "radiogatun64":
myHash = radio_gatun.New64
case "md6-224":
myHash = md6.New224
case "md6", "md6-256":
myHash = md6.New256
case "md6-384":
myHash = md6.New384
case "md6-512":
myHash = md6.New512
case "belt":
myHash = belthash.New
case "bash224":
myHash = bash.New224
case "bash", "bash256":
myHash = bash.New256
case "bash384":
myHash = bash.New384
case "bash512":
myHash = bash.New512
case "ginga":
myHash = gingaHash.New
}
xy := make([]uint32, 64*r)
v := make([]uint32, 32*N*r)
b := pbkdf2.Key(password, salt, 1, p*128*r, myHash)
for i := 0; i < p; i++ {
smix(b[i*128*r:], r, N, v, xy)
}
return pbkdf2.Key(password, b, 1, keyLen, myHash), nil
}
const maxInt = int(^uint(0) >> 1)
func blockCopy(dst, src []uint32, n int) {
copy(dst, src[:n])
}
func blockXOR(dst, src []uint32, n int) {
for i, v := range src[:n] {
dst[i] ^= v
}
}
func salsaXOR(tmp *[16]uint32, in, out []uint32) {
w0 := tmp[0] ^ in[0]
w1 := tmp[1] ^ in[1]
w2 := tmp[2] ^ in[2]
w3 := tmp[3] ^ in[3]
w4 := tmp[4] ^ in[4]
w5 := tmp[5] ^ in[5]
w6 := tmp[6] ^ in[6]
w7 := tmp[7] ^ in[7]
w8 := tmp[8] ^ in[8]
w9 := tmp[9] ^ in[9]
w10 := tmp[10] ^ in[10]
w11 := tmp[11] ^ in[11]
w12 := tmp[12] ^ in[12]
w13 := tmp[13] ^ in[13]
w14 := tmp[14] ^ in[14]
w15 := tmp[15] ^ in[15]
x0, x1, x2, x3, x4, x5, x6, x7, x8 := w0, w1, w2, w3, w4, w5, w6, w7, w8
x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15
for i := 0; i < 8; i += 2 {
x4 ^= bits.RotateLeft32(x0+x12, 7)
x8 ^= bits.RotateLeft32(x4+x0, 9)
x12 ^= bits.RotateLeft32(x8+x4, 13)
x0 ^= bits.RotateLeft32(x12+x8, 18)
x9 ^= bits.RotateLeft32(x5+x1, 7)
x13 ^= bits.RotateLeft32(x9+x5, 9)
x1 ^= bits.RotateLeft32(x13+x9, 13)
x5 ^= bits.RotateLeft32(x1+x13, 18)
x14 ^= bits.RotateLeft32(x10+x6, 7)
x2 ^= bits.RotateLeft32(x14+x10, 9)
x6 ^= bits.RotateLeft32(x2+x14, 13)
x10 ^= bits.RotateLeft32(x6+x2, 18)
x3 ^= bits.RotateLeft32(x15+x11, 7)
x7 ^= bits.RotateLeft32(x3+x15, 9)
x11 ^= bits.RotateLeft32(x7+x3, 13)
x15 ^= bits.RotateLeft32(x11+x7, 18)
x1 ^= bits.RotateLeft32(x0+x3, 7)
x2 ^= bits.RotateLeft32(x1+x0, 9)
x3 ^= bits.RotateLeft32(x2+x1, 13)
x0 ^= bits.RotateLeft32(x3+x2, 18)
x6 ^= bits.RotateLeft32(x5+x4, 7)
x7 ^= bits.RotateLeft32(x6+x5, 9)
x4 ^= bits.RotateLeft32(x7+x6, 13)
x5 ^= bits.RotateLeft32(x4+x7, 18)
x11 ^= bits.RotateLeft32(x10+x9, 7)
x8 ^= bits.RotateLeft32(x11+x10, 9)
x9 ^= bits.RotateLeft32(x8+x11, 13)
x10 ^= bits.RotateLeft32(x9+x8, 18)
x12 ^= bits.RotateLeft32(x15+x14, 7)
x13 ^= bits.RotateLeft32(x12+x15, 9)
x14 ^= bits.RotateLeft32(x13+x12, 13)
x15 ^= bits.RotateLeft32(x14+x13, 18)
}
x0 += w0
x1 += w1
x2 += w2
x3 += w3
x4 += w4
x5 += w5
x6 += w6
x7 += w7
x8 += w8
x9 += w9
x10 += w10
x11 += w11
x12 += w12
x13 += w13
x14 += w14
x15 += w15
out[0], tmp[0] = x0, x0
out[1], tmp[1] = x1, x1
out[2], tmp[2] = x2, x2
out[3], tmp[3] = x3, x3
out[4], tmp[4] = x4, x4
out[5], tmp[5] = x5, x5
out[6], tmp[6] = x6, x6
out[7], tmp[7] = x7, x7
out[8], tmp[8] = x8, x8
out[9], tmp[9] = x9, x9
out[10], tmp[10] = x10, x10
out[11], tmp[11] = x11, x11
out[12], tmp[12] = x12, x12
out[13], tmp[13] = x13, x13
out[14], tmp[14] = x14, x14
out[15], tmp[15] = x15, x15
}
func blockMix(tmp *[16]uint32, in, out []uint32, r int) {
blockCopy(tmp[:], in[(2*r-1)*16:], 16)
for i := 0; i < 2*r; i += 2 {
salsaXOR(tmp, in[i*16:], out[i*8:])
salsaXOR(tmp, in[i*16+16:], out[i*8+r*16:])
}
}
func integer(b []uint32, r int) uint64 {
j := (2*r - 1) * 16
return uint64(b[j]) | uint64(b[j+1])<<32
}
func smix(b []byte, r, N int, v, xy []uint32) {
var tmp [16]uint32
R := 32 * r
x := xy
y := xy[R:]
j := 0
for i := 0; i < R; i++ {
x[i] = binary.LittleEndian.Uint32(b[j:])
j += 4
}
for i := 0; i < N; i += 2 {
blockCopy(v[i*R:], x, R)
blockMix(&tmp, x, y, r)
blockCopy(v[(i+1)*R:], y, R)
blockMix(&tmp, y, x, r)
}
for i := 0; i < N; i += 2 {
j := int(integer(x, r) & uint64(N-1))
blockXOR(x, v[j*R:], R)
blockMix(&tmp, x, y, r)
j = int(integer(y, r) & uint64(N-1))
blockXOR(y, v[j*R:], R)
blockMix(&tmp, y, x, r)
}
j = 0
for _, v := range x[:R] {
binary.LittleEndian.PutUint32(b[j:], v)
j += 4
}
}
func PfxGen() error {
var certPEM []byte
file, err := os.Open(*cert)
if err != nil {
return err
}
info, err := file.Stat()
if err != nil {
return err
}
buf := make([]byte, info.Size())
file.Read(buf)
certPEM = buf
var certPemBlock, _ = pem.Decode([]byte(certPEM))
var certificate, _ = smx509.ParseCertificate(certPemBlock.Bytes)
var privPEM []byte
file, err = os.Open(*key)
if err != nil {
return err
}
info, err = file.Stat()
if err != nil {
return err
}
buf = make([]byte, info.Size())
file.Read(buf)
var block *pem.Block
block, _ = pem.Decode(buf)
if block == nil {
errors.New("no valid private key found")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
privKeyBytes, err = DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return err
}
privPEM = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privKeyBytes})
} else {
privPEM = buf
}
var privateKeyPemBlock, _ = pem.Decode([]byte(privPEM))
scanner := bufio.NewScanner(os.Stdin)
print("PFX Certificate Passphrase: ")
scanner.Scan()
psd := scanner.Text()
var pfxBytes []byte
if strings.ToUpper(*alg) == "RSA" {
var privKey, _ = smx509.ParsePKCS1PrivateKey(privateKeyPemBlock.Bytes)
if err := privKey.Validate(); err != nil {
panic("error validating the private key: " + err.Error())
}
pfxBytes, err = pkcs12.Encode(rand.Reader, privKey, certificate, []*smx509.Certificate{}, psd)
} else if strings.ToUpper(*alg) == "EC" || strings.ToUpper(*alg) == "ECDSA" {
var privKey, _ = smx509.ParseECPrivateKey(privateKeyPemBlock.Bytes)
pfxBytes, err = pkcs12.Encode(rand.Reader, privKey, certificate, []*smx509.Certificate{}, psd)
} else if strings.ToUpper(*alg) == "SM2" {
var privKey, _ = smx509.ParseSM2PrivateKey(privateKeyPemBlock.Bytes)
pfxBytes, err = pkcs12.Encode(rand.Reader, privKey, certificate, []*smx509.Certificate{}, psd)
}
if err != nil {
return err
}
if _, _, err := pkcs12.Decode(pfxBytes, psd); err != nil {
return err
}
certname := strings.Split(*cert, ".")
if err := ioutil.WriteFile(
certname[0]+".pfx",
pfxBytes,
os.ModePerm,
); err != nil {
return err
}
fmt.Printf("The certificate has been generated: %s\n", certname[0]+".pfx")
return nil
}
func PfxParse() error {
pfxBytes, err := os.ReadFile(*cert)
if err != nil {
return err
}
_, certificate, err := pkcs12.Decode(pfxBytes, *pwd)
if err != nil {
return err
}
pemCert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certificate.Raw})
fmt.Printf("%s", pemCert)
PEM, err := pkcs12.ToPEM(pfxBytes, *pwd)
if err != nil {
return err
}
// fmt.Printf("%s", pem.EncodeToMemory(PEM[1]))
_, err = smx509.ParsePKCS1PrivateKey(PEM[1].Bytes)
if err != nil {
ecdsaPublicKey := certificate.PublicKey.(*ecdsa.PublicKey)
publicStream, err := smx509.MarshalPKIXPublicKey(ecdsaPublicKey)
if err != nil {
return err
}
pubblock := pem.Block{Type: "PUBLIC KEY", Bytes: publicStream}
fmt.Printf("%s", pem.EncodeToMemory(&pubblock))
} else {
rsaPublicKey := certificate.PublicKey.(*rsa.PublicKey)
publicStream, err := smx509.MarshalPKIXPublicKey(rsaPublicKey)
if err != nil {
return err
}
pubblock := pem.Block{Type: "PUBLIC KEY", Bytes: publicStream}
fmt.Printf("%s", pem.EncodeToMemory(&pubblock))
}
fmt.Printf("Expiry: %s \n", certificate.NotAfter.Format("Monday, 02-Jan-06 15:04:05 MST"))
fmt.Printf("Common Name: %s \n", certificate.Subject.CommonName)
fmt.Printf("Issuer: %s \n", certificate.Issuer)
fmt.Printf("Subject: %s \n", certificate.Subject)
fmt.Printf("EmailAddresses: %s \n", certificate.EmailAddresses)
fmt.Printf("SerialNumber: %x \n", certificate.SerialNumber)
fmt.Printf("AuthorityKeyId: %x \n", certificate.AuthorityKeyId)
print("Enter PEM Passphrase: ")
pass, _ := gopass.GetPasswd()
psd := string(pass)
_, err = smx509.ParsePKCS1PrivateKey(PEM[1].Bytes)
if err != nil {
keyBlock := &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: PEM[1].Bytes,
}
if psd != "" {
keyBlock, err = EncryptBlockWithCipher(rand.Reader, keyBlock.Type, PEM[1].Bytes, []byte(psd), *cph)
if err != nil {
return err
}
}
// fmt.Printf("%s", pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBlock.Bytes}))
fmt.Printf("%s", pem.EncodeToMemory(keyBlock))
} else {
keyBlock := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: PEM[1].Bytes,
}
if psd != "" {
keyBlock, err = EncryptBlockWithCipher(rand.Reader, keyBlock.Type, PEM[1].Bytes, []byte(psd), *cph)
if err != nil {
return err
}
}
// fmt.Printf("%s", pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: PEM[1].Bytes}))
fmt.Printf("%s", pem.EncodeToMemory(keyBlock))
}
return nil
}
func csrToCrt() error {
// caPublicKeyFile, err := ioutil.ReadFile(*cert)
caPublicKeyFile, err := ioutil.ReadFile(*root)
if err != nil {
return err
}
pemBlock, _ := pem.Decode(caPublicKeyFile)
if pemBlock == nil {
panic("pem.Decode failed")
}
caCRT, err := smx509.ParseCertificate(pemBlock.Bytes)
if err != nil {
return err
}
// Verify if the certificate is a CA (has the IsCA flag set)
if !caCRT.BasicConstraintsValid || !caCRT.IsCA {
return fmt.Errorf("root certificate is not a valid CA")
}
caPrivateKeyFile, err := ioutil.ReadFile(*key)
if err != nil {
return err
}
pemBlock, _ = pem.Decode(caPrivateKeyFile)
if pemBlock == nil {
panic("pem.Decode failed")
}
var der []byte
if IsEncryptedPEMBlock(pemBlock) {
der, err = DecryptPEMBlock(pemBlock, []byte(*pwd))
if err != nil {
return err
}
} else {
der = pemBlock.Bytes
}
// clientCSRFile, err := ioutil.ReadFile(flag.Arg(0))
clientCSRFile, err := ioutil.ReadFile(*cert)
if err != nil {
return err
}
pemBlock, _ = pem.Decode(clientCSRFile)
if pemBlock == nil {
panic("pem.Decode failed")
}
clientCSR, err := smx509.ParseCertificateRequest(pemBlock.Bytes)
if err != nil {
return err
}
if err = clientCSR.CheckSignature(); err != nil {
return err
}
var validity string
// Check if the 'days' flag was provided
if *days > 0 {
// If provided, use the value from the flag
validity = fmt.Sprintf("%d", *days)
} else {
// Otherwise, prompt the user for input
println("Digital certificates are valid for up to three years:")
fmt.Print("Validity (in Days): ")
fmt.Scanln(&validity)
}
intVar, err := strconv.Atoi(validity)
if err != nil {
log.Fatal(err)
}
NotAfter := time.Now().AddDate(0, 0, intVar)
var spki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
var apki struct {
Algorithm pkix.AlgorithmIdentifier
SubjectPublicKey asn1.BitString
}
derBytes, err := smx509.MarshalPKIXPublicKey(clientCSR.PublicKey)
if err != nil {
log.Fatal(err)
}
_, err = asn1.Unmarshal(derBytes, &spki)
if err != nil {
return err
}
skid := sha1.Sum(spki.SubjectPublicKey.Bytes)
derBytes, err = smx509.MarshalPKIXPublicKey(caCRT.PublicKey)
if err != nil {
log.Fatal(err)
}
_, err = asn1.Unmarshal(derBytes, &apki)
if err != nil {
return err
}
akid := sha1.Sum(apki.SubjectPublicKey.Bytes)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 160)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %v", err)
}
clientCRTTemplate := x509.Certificate{
Signature: clientCSR.Signature,
SignatureAlgorithm: clientCSR.SignatureAlgorithm,
PublicKeyAlgorithm: clientCSR.PublicKeyAlgorithm,
PublicKey: clientCSR.PublicKey,
SerialNumber: serialNumber,
Issuer: caCRT.Subject,
Subject: clientCSR.Subject,
SubjectKeyId: skid[:],
EmailAddresses: clientCSR.EmailAddresses,
NotBefore: time.Now(),
NotAfter: NotAfter,
KeyUsage: x509.KeyUsageDigitalSignature,
AuthorityKeyId: akid[:],
BasicConstraintsValid: *isca,
IsCA: *isca,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
}
if strings.ToUpper(*alg) == "RSA" {
if *md == "sha256" {
clientCRTTemplate.SignatureAlgorithm = smx509.SHA256WithRSA
} else if *md == "sha384" {
clientCRTTemplate.SignatureAlgorithm = smx509.SHA384WithRSA
} else if *md == "sha512" {
clientCRTTemplate.SignatureAlgorithm = smx509.SHA512WithRSA
} else if *md == "sha1" {
clientCRTTemplate.SignatureAlgorithm = smx509.SHA1WithRSA
}
}
var clientCRTRaw []byte
if strings.ToUpper(*alg) == "RSA" {
caPrivateKey, err := x509.ParsePKCS1PrivateKey(der)
if err != nil {
return err
}
clientCRTRaw, err = x509.CreateCertificate(rand.Reader, &clientCRTTemplate, caCRT.ToX509(), clientCSR.PublicKey, caPrivateKey)
if err != nil {
log.Fatal(err)
}
} else if strings.ToUpper(*alg) == "ED25519" {
caPrivateKey, err := x509.ParsePKCS8PrivateKey(der)
if err != nil {
return err
}
clientCRTRaw, err = x509.CreateCertificate(rand.Reader, &clientCRTTemplate, caCRT.ToX509(), clientCSR.PublicKey, caPrivateKey)
if err != nil {
log.Fatal(err)
}
} else if strings.ToUpper(*alg) == "ECDSA" || strings.ToUpper(*alg) == "EC" {
caPrivateKey, err := x509.ParseECPrivateKey(der)
if err != nil {
return err
}
clientCRTRaw, err = x509.CreateCertificate(rand.Reader, &clientCRTTemplate, caCRT.ToX509(), clientCSR.PublicKey, caPrivateKey)
if err != nil {
log.Fatal(err)
}
} else if strings.ToUpper(*alg) == "SM2" {
caPrivateKey, err := smx509.ParseSM2PrivateKey(der)
if err != nil {
return err
}
clientCRTRaw, err = smx509.CreateCertificate(rand.Reader, &clientCRTTemplate, caCRT.ToX509(), clientCSR.PublicKey, caPrivateKey)
if err != nil {
log.Fatal(err)
}
}
if err != nil {
return err
}
var output *os.File
if flag.Arg(0) == "" {
output = os.Stdout
} else {
file, err := os.Create(flag.Arg(0))
if err != nil {
log.Fatal(err)
}
defer file.Close()
output = file
}
pem.Encode(output, &pem.Block{Type: "CERTIFICATE", Bytes: clientCRTRaw})
return err
}
func csrToCrt2() error {
caPublicKeyFile, err := ioutil.ReadFile(*root)
if err != nil {
return err
}
pemBlock, _ := pem.Decode(caPublicKeyFile)
if pemBlock == nil {
panic("pem.Decode failed")
}
caCRT, err := x509.ParseCertificate(pemBlock.Bytes)
if err != nil {
return err
}
if !caCRT.BasicConstraintsValid || !caCRT.IsCA {
return fmt.Errorf("root certificate is not a valid CA")
}
caPrivateKeyFile, err := ioutil.ReadFile(*key)
if err != nil {
return err
}
pemBlock, _ = pem.Decode(caPrivateKeyFile)
if pemBlock == nil {
panic("pem.Decode failed")
}
var der []byte
if IsEncryptedPEMBlock(pemBlock) {
der, err = DecryptPEMBlock(pemBlock, []byte(*pwd))
if err != nil {
return err
}
} else {
der = pemBlock.Bytes
}
clientCSRFile, err := ioutil.ReadFile(*cert)
if err != nil {
return err
}
pemBlock, _ = pem.Decode(clientCSRFile)
if pemBlock == nil {
panic("pem.Decode failed")
}
clientCSR, err := x509.ParseCertificateRequest(pemBlock.Bytes)
if err != nil {
return err
}
if err = clientCSR.CheckSignature(); err != nil {
return err
}
var validity string
// Check if the 'days' flag was provided
if *days > 0 {
// If provided, use the value from the flag
validity = fmt.Sprintf("%d", *days)
} else {
// Otherwise, prompt the user for input
println("Digital certificates are valid for up to three years:")
fmt.Print("Validity (in Days): ")
fmt.Scanln(&validity)
}
intVar, err := strconv.Atoi(validity)
if err != nil {
log.Fatal(err)
}
NotAfter := time.Now().AddDate(0, 0, intVar)
hasher := gost34112012256.New()
if _, err = hasher.Write(clientCSR.PublicKey.(*gost3410.PublicKey).Raw()); err != nil {
log.Fatalln(err)
}
spki := hasher.Sum(nil)
spki = spki[:20]
hasher = gost34112012256.New()
if _, err = hasher.Write(caCRT.PublicKey.(*gost3410.PublicKey).Raw()); err != nil {
log.Fatalln(err)
}
akid := hasher.Sum(nil)
akid = akid[:20]
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 160)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %v", err)
}
clientCRTTemplate := x509.Certificate{
Signature: clientCSR.Signature,
SignatureAlgorithm: clientCSR.SignatureAlgorithm,
PublicKeyAlgorithm: clientCSR.PublicKeyAlgorithm,
PublicKey: clientCSR.PublicKey,
SerialNumber: serialNumber,
Issuer: caCRT.Subject,
Subject: clientCSR.Subject,
// SubjectKeyId: skid[:],
SubjectKeyId: spki,
EmailAddresses: clientCSR.EmailAddresses,
NotBefore: time.Now(),
NotAfter: NotAfter,
AuthorityKeyId: akid[:],
BasicConstraintsValid: *isca,
IsCA: *isca,
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageContentCommitment | x509.KeyUsageKeyEncipherment | x509.KeyUsageDataEncipherment | x509.KeyUsageKeyAgreement | x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
}
var clientCRTRaw []byte
caPrivateKey, err := x509.ParsePKCS8PrivateKey(der)
if err != nil {
return err
}
clientCRTRaw, err = x509.CreateCertificate(rand.Reader, &clientCRTTemplate, caCRT, clientCSR.PublicKey, &gost3410.PrivateKeyReverseDigest{Prv: caPrivateKey.(*gost3410.PrivateKey)})
if err != nil {
return err
}
var output *os.File
if flag.Arg(0) == "" {
output = os.Stdout
} else {
file, err := os.Create(flag.Arg(0))
if err != nil {
log.Fatal(err)
}
defer file.Close()
output = file
}
pem.Encode(output, &pem.Block{Type: "CERTIFICATE", Bytes: clientCRTRaw})
return err
}
func parsePrivateKeyAndCert(keyPEM, certPEM []byte) (crypto.Signer, *x509.Certificate, error) {
keyBlock, _ := pem.Decode(keyPEM)
if keyBlock == nil {
return nil, nil, fmt.Errorf("Failed to decode private key")
}
var decryptedKeyBytes []byte
var err error
if x509.IsEncryptedPEMBlock(keyBlock) {
decryptedKeyBytes, err = DecryptPEMBlock(keyBlock, []byte(*pwd))
if err != nil {
return nil, nil, fmt.Errorf("Failed to decrypt private key: %w", err)
}
keyBlock.Bytes = decryptedKeyBytes
}
key, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
if err != nil {
key, err = x509.ParsePKCS1PrivateKey(keyBlock.Bytes)
if err != nil {
key, err = x509.ParseECPrivateKey(keyBlock.Bytes)
if err != nil {
return nil, nil, fmt.Errorf("Failed to parse private key: %w", err)
}
}
}
signer, ok := key.(crypto.Signer)
if !ok {
return nil, nil, fmt.Errorf("Invalid private key type")
}
certBlock, _ := pem.Decode(certPEM)
if certBlock == nil {
return nil, nil, fmt.Errorf("Failed to decode certificate")
}
cert, err := x509.ParseCertificate(certBlock.Bytes)
if err != nil {
return nil, nil, fmt.Errorf("Failed to parse certificate: %w", err)
}
return signer, cert, nil
}
func parsePrivateKeyAndCertSM2(keyPEM, certPEM []byte) (crypto.Signer, *smx509.Certificate, error) {
keyBlock, _ := pem.Decode(keyPEM)
if keyBlock == nil {
return nil, nil, fmt.Errorf("Failed to decode private key")
}
var decryptedKeyBytes []byte
var err error
if x509.IsEncryptedPEMBlock(keyBlock) {
decryptedKeyBytes, err = DecryptPEMBlock(keyBlock, []byte(*pwd))
if err != nil {
return nil, nil, fmt.Errorf("Failed to decrypt private key: %w", err)
}
keyBlock.Bytes = decryptedKeyBytes
}
sm2key, err := smx509.ParseSM2PrivateKey(keyBlock.Bytes)
if err != nil {
return nil, nil, fmt.Errorf("Failed to parse private key: %w", err)
}
var signer crypto.Signer = sm2key
certBlock, _ := pem.Decode(certPEM)
if certBlock == nil {
return nil, nil, fmt.Errorf("Failed to decode certificate")
}
cert, err := smx509.ParseCertificate(certBlock.Bytes)
if err != nil {
return nil, nil, fmt.Errorf("Failed to parse certificate: %w", err)
}
return signer, cert, nil
}
func isCertificateRevoked(cert *x509.Certificate, crl *pkix.CertificateList) (bool, time.Time) {
for _, revokedCert := range crl.TBSCertList.RevokedCertificates {
if revokedCert.SerialNumber.Cmp(cert.SerialNumber) == 0 {
return true, revokedCert.RevocationTime
}
}
return false, time.Time{}
}
func isCertificateRevokedSM2(cert *smx509.Certificate, crl *pkix.CertificateList) (bool, time.Time) {
for _, revokedCert := range crl.TBSCertList.RevokedCertificates {
if revokedCert.SerialNumber.Cmp(cert.SerialNumber) == 0 {
return true, revokedCert.RevocationTime
}
}
return false, time.Time{}
}
type authorityKeyIdentifier struct {
Raw asn1.RawContent
ID []byte `asn1:"optional,tag:0"`
KeyIdentifier []byte `asn1:"optional,tag:1"`
AuthorityCertIssuer []byte `asn1:"optional,tag:2"`
AuthorityCertSerial []byte `asn1:"optional,tag:3"`
}
func getAuthorityKeyIdentifierFromCRL(crl *x509.RevocationList) []byte {
for _, extension := range crl.Extensions {
if extension.Id.Equal(asn1.ObjectIdentifier{2, 5, 29, 35}) {
var akid authorityKeyIdentifier
_, err := asn1.Unmarshal(extension.Value, &akid)
if err == nil {
return akid.ID
}
}
}
return nil
}
var oidToAlgo = map[string]string{
"1.2.643.7.1.1.3.2": "GOST R 34.11-2012 with GOST R 34.10-2012",
"1.2.643.7.1.1.3.3": "GOST R 34.11-2012 with GOST R 34.10-2012 (512 bits)",
"1.2.840.113549.1.1.11": "RSA",
"1.3.101.112": "Ed25519",
"1.2.840.10045.2.1": "ECDSA (prime256v1)",
"1.2.840.10045.4.3.2": "ECDSA (prime256v1)",
"1.2.840.10045.3.1.1": "ECDSA (prime224v1)",
"1.2.840.10045.4.3.3": "ECDSA (prime384v1)",
"1.2.840.10045.4.3.4": "ECDSA (prime521v1)",
"1.2.156.10197.1.501": "SM2 (sm2p256v1)",
}
func printVersion(version int, buf *bytes.Buffer) {
hexVersion := version - 1
if hexVersion < 0 {
hexVersion = 0
}
buf.WriteString(fmt.Sprintf("%8sVersion: %d (%#x)\n", "", version, hexVersion))
}
func printName(names []pkix.AttributeTypeAndValue, buf *bytes.Buffer) []string {
values := []string{}
for _, name := range names {
oid := name.Type
switch {
case len(oid) == 4 && oid[0] == 2 && oid[1] == 5 && oid[2] == 4:
switch oid[3] {
case 3:
values = append(values, fmt.Sprintf("CN=%s", name.Value))
case 5:
values = append(values, fmt.Sprintf("SERIALNUMBER=%s", name.Value))
case 6:
values = append(values, fmt.Sprintf("C=%s", name.Value))
case 7:
values = append(values, fmt.Sprintf("L=%s", name.Value))
case 8:
values = append(values, fmt.Sprintf("ST=%s", name.Value))
case 9:
values = append(values, fmt.Sprintf("STREET=%s", name.Value))
case 10:
values = append(values, fmt.Sprintf("O=%s", name.Value))
case 11:
values = append(values, fmt.Sprintf("OU=%s", name.Value))
case 17:
values = append(values, fmt.Sprintf("POSTALCODE=%s", name.Value))
default:
values = append(values, fmt.Sprintf("UnknownOID=%s", name.Type.String()))
}
case oid.Equal(oidEmailAddress):
values = append(values, fmt.Sprintf("emailAddress=%s", name.Value))
case oid.Equal(oidDomainComponent):
values = append(values, fmt.Sprintf("DC=%s", name.Value))
case oid.Equal(oidUserID):
values = append(values, fmt.Sprintf("UID=%s", name.Value))
default:
values = append(values, fmt.Sprintf("UnknownOID=%s", name.Type.String()))
}
}
if len(values) > 0 {
buf.WriteString(values[0])
for i := 1; i < len(values); i++ {
buf.WriteString("," + values[i])
}
buf.WriteString("\n")
}
return values
}
func printSignature(sigAlgo x509.SignatureAlgorithm, sig []byte, buf *bytes.Buffer) {
buf.WriteString(fmt.Sprintf("%4sSignature Algorithm: %s", "", sigAlgo))
for i, val := range sig {
if (i % 18) == 0 {
buf.WriteString(fmt.Sprintf("\n%9s", ""))
}
buf.WriteString(fmt.Sprintf("%02x", val))
if i != len(sig)-1 {
buf.WriteString(":")
}
}
buf.WriteString("\n")
}
func getAlgorithmName(oid string) string {
if algo, ok := oidToAlgo[oid]; ok {
return algo
}
return "Unknown Algorithm"
}
var (
name, number, country, province, locality, organization, organizationunit, street, email, postalcode string
)
func parseSubjectString(subject string) (name, number, country, province, locality, organization, organizationunit, street, email, postalcode string, err error) {
parts := strings.Split(subject, "/")
if len(parts) < 6 || len(parts) > 10 {
return "", "", "", "", "", "", "", "", "", "", errors.New("invalid subject string format")
}
for _, part := range parts {
kv := strings.SplitN(part, "=", 2)
if len(kv) != 2 {
continue
}
key := kv[0]
value := kv[1]
switch key {
case "C":
country = value
case "ST":
province = value
case "L":
locality = value
case "O":
organization = value
case "OU":
organizationunit = value
case "CN":
name = value
case "emailAddress":
email = value
case "postalCode":
postalcode = value
case "STREET":
street = value
}
}
return name, number, country, province, locality, organization, organizationunit, street, email, postalcode, nil
}
func PKCS7Padding(ciphertext []byte) []byte {
// padding := aes.BlockSize - len(ciphertext)%aes.BlockSize
var padding int
if (*cph == "aes" || *cph == "aria" || *cph == "grasshopper" || *cph == "kuznechik" || *cph == "camellia" || *cph == "twofish" || *cph == "lea" || *cph == "seed" || *cph == "sm4" || *cph == "anubis" || *cph == "serpent" || *cph == "rc6" || *cph == "ginga" || *cph == "magenta" || *cph == "crypton" || *cph == "noekeon" || *cph == "loki97" || *cph == "mars" || *cph == "e2" || *cph == "clefia" || *cph == "kalyna128_128" || *cph == "kalyna128_256" || *cph == "cast256" || *cph == "cast6" || *cph == "belt") {
padding = 16 - len(ciphertext) % 16
} else if (*cph == "blowfish" || *cph == "cast5" || *cph == "des" || *cph == "3des" || *cph == "magma" || *cph == "gost89" || *cph == "idea" || *cph == "rc2" || *cph == "rc5" || *cph == "hight" || *cph == "misty1" || *cph == "khazad" || *cph == "present" || *cph == "twine" || *cph == "saferplus" || *cph == "safer+") {
padding = 8 - len(ciphertext) % 8
} else if (*cph == "threefish" || *cph == "threefish256" || *cph == "kalyna256_256" || *cph == "kalyna256_512" || *cph == "shacal2") {
padding = 32 - len(ciphertext) % 32
} else if (*cph == "threefish512" || *cph == "kalyna512_512") {
padding = 64 - len(ciphertext) % 64
} else if (*cph == "threefish1024") {
padding = 128 - len(ciphertext) % 128
} else if (*cph == "curupira") {
padding = 12 - len(ciphertext) % 12
}
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS7UnPadding(plantText []byte) []byte {
length := len(plantText)
unpadding := int(plantText[length-1])
return plantText[:(length - unpadding)]
}
func reverseBytes(d []byte) {
for i, j := 0, len(d)-1; i < j; i, j = i+1, j-1 {
d[i], d[j] = d[j], d[i]
}
}
func SplitSubN(s string, n int) []string {
sub := ""
subs := []string{}
runes := bytes.Runes([]byte(s))
l := len(runes)
for i, r := range runes {
sub = sub + string(r)
if (i+1)%n == 0 {
subs = append(subs, sub)
sub = ""
} else if (i + 1) == l {
subs = append(subs, sub)
}
}
return subs
}
func split(s string, size int) []string {
ss := make([]string, 0, len(s)/size+1)
for len(s) > 0 {
if len(s) < size {
size = len(s)
}
ss, s = append(ss, s[:size]), s[size:]
}
return ss
}
func encodeAscii85(data []byte) string {
var encoded strings.Builder
encoder := ascii85.NewEncoder(&encoded)
encoder.Write(data)
encoder.Close()
return encoded.String()
}
func printChunks(s string, size int) {
for i := 0; i < len(s); i += size {
end := i + size
if end > len(s) {
end = len(s)
}
fmt.Println(s[i:end])
}
}
func byte32(s []byte) (a *[32]byte) {
if len(a) <= len(s) {
a = (*[len(a)]byte)(unsafe.Pointer(&s[0]))
}
return a
}
func byte16(s []byte) (a *[16]byte) {
if len(a) <= len(s) {
a = (*[len(a)]byte)(unsafe.Pointer(&s[0]))
}
return a
}
func byte10(s []byte) (a *[10]byte) {
if len(a) <= len(s) {
a = (*[len(a)]byte)(unsafe.Pointer(&s[0]))
}
return a
}
func byte8(s []byte) (a *[8]byte) {
if len(a) <= len(s) {
a = (*[len(a)]byte)(unsafe.Pointer(&s[0]))
}
return a
}
func calculateFingerprint(key []byte) string {
hash := sha256.Sum256(key)
fingerprint := base64.StdEncoding.EncodeToString(hash[:])
return fingerprint
}
func calculateFingerprintGOST(key []byte) string {
hasher := gost34112012256.New()
if _, err := hasher.Write(key); err != nil {
log.Fatalln(err)
}
hash := hasher.Sum(nil)
fingerprint := base64.StdEncoding.EncodeToString(hash)
return fingerprint
}
// Função auxiliar para calcular fingerprint do formato ASN1
func calculateFingerprintFromASN1(key []byte) string {
// Calcula hash SHA256
hash := sha256.Sum256(key)
fingerprint := base64.StdEncoding.EncodeToString(hash[:])
return fingerprint
}
func NewMGMAC(block cipher.Block, length int, nonce, data []byte) ([]byte, error) {
aead, err := mgm.NewMGM(block, length)
if err != nil {
return nil, err
}
mgmac := aead.Seal(nil, nonce, nil, data)
return mgmac, nil
}
func printKeyDetails(block *pem.Block) {
var err error
parsers := []func([]byte) (interface{}, error){
func(b []byte) (interface{}, error) {
return smx509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
return x509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
return nums.ParsePublicKey(b)
},
func(b []byte) (interface{}, error) {
pub, err := ed448.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := x448.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
return kx509.ParsePKIXPublicKey(b)
},
func(b []byte) (interface{}, error) {
pub, err := ecgdsa.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := ecsdsa.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := bip0340.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := bign.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := frp256v1.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := secp256k1.ParsePublicKey(b)
return pub, err
},
func(b []byte) (interface{}, error) {
pub, err := tom.ParsePublicKey(b)
return pub, err
},
}
var publicInterface interface{}
for _, parser := range parsers {
publicInterface, err = parser(block.Bytes)
if err == nil {
break
}
}
if err != nil {
log.Fatal("Failed to parse public key:", err)
}
switch publicInterface.(type) {
case *rsa.PublicKey:
publicKey := publicInterface.(*rsa.PublicKey)
fmt.Fprintf(os.Stderr, "RSA (%v-bit)\n", publicKey.N.BitLen())
case *ecdsa.PublicKey:
publicKey := publicInterface.(*ecdsa.PublicKey)
fmt.Fprintf(os.Stderr, "ECDSA (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *eckcdsa.PublicKey:
publicKey := publicInterface.(*eckcdsa.PublicKey)
fmt.Fprintf(os.Stderr, "ECKCDSA (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *ecgdsa.PublicKey:
publicKey := publicInterface.(*ecgdsa.PublicKey)
fmt.Fprintf(os.Stderr, "ECGDSA (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *ecsdsa.PublicKey:
publicKey := publicInterface.(*ecsdsa.PublicKey)
fmt.Fprintf(os.Stderr, "ECSDSA (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *bip0340.PublicKey:
publicKey := publicInterface.(*bip0340.PublicKey)
fmt.Fprintf(os.Stderr, "BIP0340 (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *ecdh.PublicKey:
fmt.Fprintln(os.Stderr, "X25519 (256-bit)")
case ed25519.PublicKey:
fmt.Fprintln(os.Stderr, "Ed25519 (256-bit)")
case ed448.PublicKey:
fmt.Fprintln(os.Stderr, "Ed448 (448-bit)")
case x448.PublicKey:
fmt.Fprintln(os.Stderr, "X448 (448-bit)")
case *gost3410.PublicKey:
publicKey := publicInterface.(*gost3410.PublicKey)
fmt.Fprintf(os.Stderr, "GOST2012 (%v-bit)\n", len(publicKey.Raw())*4)
case *bign.PublicKey:
publicKey := publicInterface.(*bign.PublicKey)
fmt.Fprintf(os.Stderr, "BIGN (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *frp256v1.PublicKey:
publicKey := publicInterface.(*frp256v1.PublicKey)
fmt.Fprintf(os.Stderr, "ANSSI (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *secp256k1.PublicKey:
publicKey := publicInterface.(*secp256k1.PublicKey)
fmt.Fprintf(os.Stderr, "KOBLITZ (%v-bit)\n", publicKey.Curve.Params().BitSize)
case *tom.PublicKey:
publicKey := publicInterface.(*tom.PublicKey)
fmt.Fprintf(os.Stderr, "Tom (%v-bit)\n", publicKey.Curve.Params().BitSize)
default:
log.Fatal("unknown type of public key")
}
}
func savePEMKey(filename string, keyBytes []byte, blockType string) error {
block := &pem.Block{
Type: blockType,
Bytes: keyBytes,
}
return savePEMToFile(filename, block, true)
}
func savePEMPublicKey(filename string, keyBytes []byte) error {
block := &pem.Block{
Type: "SLH-DSA PUBLIC KEY",
Bytes: keyBytes,
}
return savePEMToFile(filename, block, false)
}
func generateKeyPair(privPath, pubPath string) {
params := parameters.MakeSphincsPlusSHAKE256256fRobust(true)
fmt.Printf("SLH-DSA Parameters\nN=%d, W=%d, Hprime=%d, H=%d, D=%d, K=%d, T=%d, LogT=%d, A=%d\n", params.N, params.W, params.Hprime,
params.H, params.D, params.K, params.T, params.LogT, params.A)
sk, pk := sphincs.Spx_keygen(params)
serializedSK, err := sk.SerializeSK()
if err != nil {
log.Fatal(err)
}
serializedPK, err := pk.SerializePK()
if err != nil {
log.Fatal(err)
}
err = savePEMKey(privPath, serializedSK, "SLH-DSA SECRET KEY")
if err != nil {
log.Fatal(err)
}
err = savePEMPublicKey(pubPath, serializedPK)
if err != nil {
log.Fatal(err)
}
absPrivPath, err := filepath.Abs(*priv)
if err != nil {
log.Fatal("Failed to get absolute path for private key:", err)
}
absPubPath, err := filepath.Abs(*pub)
if err != nil {
log.Fatal("Failed to get absolute path for public key:", err)
}
println("Private key saved to:", absPrivPath)
println("Public key saved to:", absPubPath)
file, err := os.Open(*pub)
if err != nil {
log.Fatal(err)
}
info, err := file.Stat()
if err != nil {
log.Fatal(err)
}
buf := make([]byte, info.Size())
file.Read(buf)
fingerprint := calculateFingerprint(buf)
print("Fingerprint: ")
println(fingerprint)
println("SLH-DSA (256-bit)")
randomArt := randomart.FromString(string(buf))
println(randomArt)
}
func signMessage(input io.Reader, keyPath string) {
messageBytes, err := ioutil.ReadAll(input)
if err != nil {
log.Fatal(err)
}
params := parameters.MakeSphincsPlusSHAKE256256fRobust(true)
privateKeyBytes, err := readKeyFromPEM(keyPath, true)
if err != nil {
log.Fatal(err)
}
deserializedSK, err := sphincs.DeserializeSK(params, privateKeyBytes)
if err != nil {
log.Fatal(err)
}
sk := deserializedSK
signature := sphincs.Spx_sign(params, messageBytes, sk)
serializedSignature, err := signature.SerializeSignature()
if err != nil {
log.Fatal(err)
}
/*
if *sig != "" {
base64Signature := base64.StdEncoding.EncodeToString(serializedSignature)
err = ioutil.WriteFile(*sig, []byte(base64Signature), 0644)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Signature saved to %s\n", *sig)
} else {
base64Signature := base64.StdEncoding.EncodeToString(serializedSignature)
fmt.Printf("%s\n", base64Signature)
}
*/
block := &pem.Block{
Type: "SLH-DSA SIGNATURE",
Bytes: serializedSignature,
}
pemSignature := pem.EncodeToMemory(block)
if *sig != "" {
err = ioutil.WriteFile(*sig, []byte(pemSignature), 0644)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Signature saved to %s\n", *sig)
} else {
fmt.Printf("%s\n", pemSignature)
}
}
func verifySignature(input io.Reader, keyPath, sigPath string) {
messageBytes, err := ioutil.ReadAll(input)
if err != nil {
log.Fatal(err)
}
params := parameters.MakeSphincsPlusSHAKE256256fRobust(true)
publicKeyBytes, err := readKeyFromPEM(keyPath, false)
if err != nil {
log.Fatal(err)
}
deserializedPK, err := sphincs.DeserializePK(params, publicKeyBytes)
if err != nil {
log.Fatal(err)
}
pk := deserializedPK
signatureBytes, err := ioutil.ReadFile(sigPath)
if err != nil {
log.Fatal(err)
}
/*
decodedSignature, err := base64.StdEncoding.DecodeString(string(signatureBytes))
if err != nil {
log.Fatal(err)
}
deserializedSignature, err := sphincs.DeserializeSignature(params, decodedSignature)
if err != nil {
log.Fatal(err)
}
*/
decodedSignature, _ := pem.Decode(signatureBytes)
deserializedSignature, err := sphincs.DeserializeSignature(params, decodedSignature.Bytes)
if err != nil {
log.Fatal(err)
}
signature := deserializedSignature
if sphincs.Spx_verify(params, messageBytes, signature, pk) {
fmt.Println("Verified: true")
} else {
fmt.Println("Verified: false")
os.Exit(1)
}
}
// SignSLH signs the message using the provided secret key (SLH-DSA / Sphincs+ SHAKE256)
func SignSLH(sk []byte, msgInput io.Reader) ([]byte, error) {
// Read the message to be signed
msg, err := ioutil.ReadAll(msgInput)
if err != nil {
return nil, err
}
// Initialize parameters for SLH-DSA (Sphincs+ SHAKE256)
params := parameters.MakeSphincsPlusSHAKE256256fRobust(true)
// Deserialize the secret key (private key)
deserializedSK, err := sphincs.DeserializeSK(params, sk)
if err != nil {
return nil, fmt.Errorf("error deserializing secret key: %v", err)
}
// Sign the message using the secret key
signature := sphincs.Spx_sign(params, msg, deserializedSK)
// Serialize the signature
serializedSignature, err := signature.SerializeSignature()
if err != nil {
return nil, fmt.Errorf("error serializing signature: %v", err)
}
return serializedSignature, nil
}
// VerifySLH verifies the signature against the provided public key and message
func VerifySLH(pk []byte, signature []byte, msg []byte) error {
// Initialize parameters for SLH-DSA (Sphincs+ SHAKE256)
params := parameters.MakeSphincsPlusSHAKE256256fRobust(true)
// Deserialize the public key
deserializedPK, err := sphincs.DeserializePK(params, pk)
if err != nil {
return fmt.Errorf("error deserializing public key: %v", err)
}
// Deserialize the signature
deserializedSignature, err := sphincs.DeserializeSignature(params, signature)
if err != nil {
return fmt.Errorf("error deserializing signature: %v", err)
}
// Verify the signature
verified := sphincs.Spx_verify(params, msg, deserializedSignature, deserializedPK)
if !verified {
return fmt.Errorf("signature verification failed")
}
return nil
}
func printPublicKeyParams(pk *sphincs.SPHINCS_PK) {
fmt.Printf("PKseed=%X\n", pk.PKseed)
fmt.Printf("PKroot=%X\n", pk.PKroot)
}
func printPrivateKeyParams(sk *sphincs.SPHINCS_SK) {
// fmt.Printf("SKseed=%X\n", sk.SKseed)
// fmt.Printf("SKprf=%X\n", sk.SKprf)
fmt.Printf("PKseed=%X\n", sk.PKseed)
fmt.Printf("PKroot=%X\n", sk.PKroot)
}
func printKeyParams(keyBytes []byte, isPrivateKey bool) error {
var (
pk *sphincs.SPHINCS_PK
sk *sphincs.SPHINCS_SK
)
var params = parameters.MakeSphincsPlusSHAKE256256fRobust(true)
if isPrivateKey {
var err error
sk, err = sphincs.DeserializeSK(params, keyBytes)
if err != nil {
return err
}
printPrivateKeyParams(sk)
os.Exit(0)
} else {
var err error
pk, err = sphincs.DeserializePK(params, keyBytes)
if err != nil {
return err
}
printPublicKeyParams(pk)
os.Exit(0)
}
return nil
}
func printPublicKeyParamsFull(pk *sphincs.SPHINCS_PK) {
serializedPK, err := pk.SerializePK()
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "SLH-DSA PUBLIC KEY",
Bytes: serializedPK,
}
pem.Encode(os.Stdout, block)
fmt.Printf("PublicKey: (256-bit)\n")
fmt.Printf("PK: \n")
splitz := SplitSubN(hex.EncodeToString(serializedPK), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("PKseed: \n")
splitz = SplitSubN(hex.EncodeToString(pk.PKseed), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("PKroot: \n")
splitz = SplitSubN(hex.EncodeToString(pk.PKroot), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("ASN.1 OID: SLH-DSA")
skid := sha3.Sum256(serializedPK)
fmt.Printf("\nKeyID: %x \n", skid[:20])
}
func printPrivateKeyParamsFull(sk *sphincs.SPHINCS_SK) {
serializedSK, err := sk.SerializeSK()
if err != nil {
log.Fatal(err)
}
block := &pem.Block{
Type: "SLH-DSA SECRET KEY",
Bytes: serializedSK,
}
pem.Encode(os.Stdout, block)
fmt.Printf("SecretKey: (256-bit)\n")
/*
fmt.Printf("SK: \n")
splitz := SplitSubN(hex.EncodeToString(serializedSK), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
*/
fmt.Printf("SKseed: \n")
splitz := SplitSubN(hex.EncodeToString(sk.SKseed), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("SKprf: \n")
splitz = SplitSubN(hex.EncodeToString(sk.SKprf), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("PKseed: \n")
splitz = SplitSubN(hex.EncodeToString(sk.PKseed), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Printf("PKroot: \n")
splitz = SplitSubN(hex.EncodeToString(sk.PKroot), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
fmt.Println("ASN.1 OID: SLH-DSA")
c := append(sk.PKseed, sk.PKroot...)
skid := sha3.Sum256(c)
fmt.Printf("\nKeyID: %x \n", skid[:20])
}
func printKeyParamsFull(keyBytes []byte, isPrivateKey bool) error {
var (
pk *sphincs.SPHINCS_PK
sk *sphincs.SPHINCS_SK
)
var params = parameters.MakeSphincsPlusSHAKE256256fRobust(true)
if isPrivateKey {
var err error
sk, err = sphincs.DeserializeSK(params, keyBytes)
if err != nil {
return err
}
printPrivateKeyParamsFull(sk)
os.Exit(0)
} else {
var err error
pk, err = sphincs.DeserializePK(params, keyBytes)
if err != nil {
return err
}
printPublicKeyParamsFull(pk)
os.Exit(0)
}
return nil
}
type PEMCipher int
const (
_ PEMCipher = iota
PEMCipherDES
PEMCipher3DES
PEMCipherAES128
PEMCipherAES192
PEMCipherAES256
PEMCipherSM4
PEMCipherARIA128
PEMCipherARIA192
PEMCipherARIA256
PEMCipherLEA128
PEMCipherLEA192
PEMCipherLEA256
PEMCipherBETL128
PEMCipherBETL192
PEMCipherBETL256
PEMCipherCAMELLIA128
PEMCipherCAMELLIA192
PEMCipherCAMELLIA256
PEMCipherIDEA
PEMCipherSEED
PEMCipherGOST
PEMCipherCAST
PEMCipherANUBIS
PEMCipherSERPENT128
PEMCipherSERPENT192
PEMCipherSERPENT256
PEMCipherRC6128
PEMCipherRC6192
PEMCipherRC6256
PEMCipherMAGENTA128
PEMCipherMAGENTA192
PEMCipherMAGENTA256
PEMCipherCRYPTON128
PEMCipherCRYPTON192
PEMCipherCRYPTON256
PEMCipherE2128
PEMCipherE2192
PEMCipherE2256
PEMCipherLOKI97128
PEMCipherLOKI97192
PEMCipherLOKI97256
PEMCipherMARS128
PEMCipherMARS192
PEMCipherMARS256
PEMCipherNOEKEON
PEMCipherCAST256_128
PEMCipherCAST256_192
PEMCipherCAST256_256
PEMCipherTWOFISH128
PEMCipherTWOFISH192
PEMCipherTWOFISH256
PEMCipherKALYNA128_128
PEMCipherKALYNA128_256
PEMCipherCURUPIRA96
PEMCipherCURUPIRA144
PEMCipherCURUPIRA192
PEMCipherBELT128
PEMCipherBELT192
PEMCipherBELT256
)
type rfc1423Algo struct {
cipher PEMCipher
name string
cipherFunc func(key []byte) (cipher.Block, error)
keySize int
blockSize int
}
var rfc1423Algos = []rfc1423Algo{{
cipher: PEMCipherGOST,
name: "KUZNECHIK-CBC",
cipherFunc: kuznechik.NewCipher,
keySize: 32,
blockSize: kuznechik.BlockSize,
}, {
cipher: PEMCipherDES,
name: "DES-CBC",
cipherFunc: des.NewCipher,
keySize: 8,
blockSize: des.BlockSize,
}, {
cipher: PEMCipher3DES,
name: "DES-EDE3-CBC",
cipherFunc: des.NewTripleDESCipher,
keySize: 24,
blockSize: des.BlockSize,
}, {
cipher: PEMCipherAES128,
name: "AES-128-CBC",
cipherFunc: aes.NewCipher,
keySize: 16,
blockSize: aes.BlockSize,
}, {
cipher: PEMCipherAES192,
name: "AES-192-CBC",
cipherFunc: aes.NewCipher,
keySize: 24,
blockSize: aes.BlockSize,
}, {
cipher: PEMCipherAES256,
name: "AES-256-CBC",
cipherFunc: aes.NewCipher,
keySize: 32,
blockSize: aes.BlockSize,
}, {
cipher: PEMCipherSM4,
name: "SM4-CBC",
cipherFunc: sm4.NewCipher,
keySize: 16,
blockSize: sm4.BlockSize,
}, {
cipher: PEMCipherARIA128,
name: "ARIA-128-CBC",
cipherFunc: aria.NewCipher,
keySize: 16,
blockSize: aria.BlockSize,
}, {
cipher: PEMCipherARIA192,
name: "ARIA-192-CBC",
cipherFunc: aria.NewCipher,
keySize: 24,
blockSize: aria.BlockSize,
}, {
cipher: PEMCipherARIA256,
name: "ARIA-256-CBC",
cipherFunc: aria.NewCipher,
keySize: 32,
blockSize: aria.BlockSize,
}, {
cipher: PEMCipherLEA128,
name: "LEA-128-CBC",
cipherFunc: lea.NewCipher,
keySize: 16,
blockSize: lea.BlockSize,
}, {
cipher: PEMCipherLEA192,
name: "LEA-192-CBC",
cipherFunc: lea.NewCipher,
keySize: 24,
blockSize: lea.BlockSize,
}, {
cipher: PEMCipherLEA256,
name: "LEA-256-CBC",
cipherFunc: lea.NewCipher,
keySize: 32,
blockSize: lea.BlockSize,
}, {
cipher: PEMCipherCAMELLIA128,
name: "CAMELLIA-128-CBC",
cipherFunc: camellia.NewCipher,
keySize: 16,
blockSize: camellia.BlockSize,
}, {
cipher: PEMCipherCAMELLIA192,
name: "CAMELLIA-192-CBC",
cipherFunc: camellia.NewCipher,
keySize: 24,
blockSize: camellia.BlockSize,
}, {
cipher: PEMCipherCAMELLIA256,
name: "CAMELLIA-256-CBC",
cipherFunc: camellia.NewCipher,
keySize: 32,
blockSize: camellia.BlockSize,
}, {
cipher: PEMCipherIDEA,
name: "IDEA-CBC",
cipherFunc: idea.NewCipher,
keySize: 16,
blockSize: 8,
}, {
cipher: PEMCipherSEED,
name: "SEED-CBC",
cipherFunc: krcrypt.NewSEED,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherSEED,
name: "SEED-CBC",
cipherFunc: krcrypt.NewSEED,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherCAST,
name: "CAST-CBC",
cipherFunc: cast5.NewCAST,
keySize: 16,
blockSize: 8,
}, {
cipher: PEMCipherANUBIS,
name: "ANUBIS-CBC",
cipherFunc: anubis.New,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherSERPENT128,
name: "SERPENT-128-CBC",
cipherFunc: serpent.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherSERPENT192,
name: "SERPENT-192-CBC",
cipherFunc: serpent.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherSERPENT256,
name: "SERPENT-256-CBC",
cipherFunc: serpent.NewCipher,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherRC6128,
name: "RC6-128-CBC",
cipherFunc: rc6.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherRC6192,
name: "RC6-192-CBC",
cipherFunc: rc6.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherRC6256,
name: "RC6-256-CBC",
cipherFunc: rc6.NewCipher,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherMAGENTA128,
name: "MAGENTA-128-CBC",
cipherFunc: magenta.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherMAGENTA192,
name: "MAGENTA-192-CBC",
cipherFunc: magenta.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherMAGENTA256,
name: "MAGENTA-256-CBC",
cipherFunc: magenta.NewCipher,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherCRYPTON128,
name: "CRYPTON-128-CBC",
cipherFunc: crypton1.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherCRYPTON192,
name: "CRYPTON-192-CBC",
cipherFunc: crypton1.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherCRYPTON256,
name: "CRYPTON-256-CBC",
cipherFunc: crypton1.NewCipher,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherE2128,
name: "E2-128-CBC",
cipherFunc: e2.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherE2192,
name: "E2-192-CBC",
cipherFunc: e2.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherE2256,
name: "E2-256-CBC",
cipherFunc: e2.NewCipher,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherLOKI97128,
name: "LOKI97-128-CBC",
cipherFunc: loki97.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherLOKI97192,
name: "LOKI97-192-CBC",
cipherFunc: loki97.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherLOKI97256,
name: "LOKI97-256-CBC",
cipherFunc: loki97.NewCipher,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherMARS128,
name: "MARS-128-CBC",
cipherFunc: mars.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherMARS192,
name: "MARS-192-CBC",
cipherFunc: mars.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherMARS256,
name: "MARS-256-CBC",
cipherFunc: mars.NewCipher,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherNOEKEON,
name: "NOEKEON-CBC",
cipherFunc: noekeon.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherCAST256_128,
name: "CAST256-128-CBC",
cipherFunc: cast256.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherCAST256_192,
name: "CAST256-192-CBC",
cipherFunc: cast256.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherCAST256_256,
name: "CAST256-256-CBC",
cipherFunc: cast256.NewCipher,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherTWOFISH128,
name: "TWOFISH-128-CBC",
cipherFunc: twofishCipherFunc,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherTWOFISH192,
name: "TWOFISH-192-CBC",
cipherFunc: twofishCipherFunc,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherTWOFISH256,
name: "TWOFISH-256-CBC",
cipherFunc: twofishCipherFunc,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherKALYNA128_128,
name: "KALYNA128_128-CBC",
cipherFunc: kalyna.NewCipher128_128,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherKALYNA128_256,
name: "KALYNA128_256-CBC",
cipherFunc: kalyna.NewCipher128_256,
keySize: 32,
blockSize: 16,
}, {
cipher: PEMCipherCURUPIRA96,
name: "CURUPIRA-96-CBC",
cipherFunc: curupiraCipherFunc,
keySize: 12,
blockSize: 12,
}, {
cipher: PEMCipherCURUPIRA144,
name: "CURUPIRA-144-CBC",
cipherFunc: curupiraCipherFunc,
keySize: 18,
blockSize: 12,
}, {
cipher: PEMCipherCURUPIRA192,
name: "CURUPIRA-192-CBC",
cipherFunc: curupiraCipherFunc,
keySize: 24,
blockSize: 12,
}, {
cipher: PEMCipherBELT128,
name: "BELT-128-CBC",
cipherFunc: belt.NewCipher,
keySize: 16,
blockSize: 16,
}, {
cipher: PEMCipherBELT192,
name: "BELT-192-CBC",
cipherFunc: belt.NewCipher,
keySize: 24,
blockSize: 16,
}, {
cipher: PEMCipherBELT256,
name: "BELT-256-CBC",
cipherFunc: belt.NewCipher,
keySize: 32,
blockSize: 16,
},
}
func twofishCipherFunc(key []byte) (cipher.Block, error) {
ciph, err := twofish.NewCipher(key)
if err != nil {
return nil, err
}
return ciph, nil
}
func curupiraCipherFunc(key []byte) (cipher.Block, error) {
ciph, err := curupira1.NewCipher(key)
if err != nil {
return nil, err
}
return ciph, nil
}
func (c rfc1423Algo) deriveKey(password, salt []byte) []byte {
hash := md5.New()
out := make([]byte, c.keySize)
var digest []byte
for i := 0; i < len(out); i += len(digest) {
hash.Reset()
hash.Write(digest)
hash.Write(password)
hash.Write(salt)
digest = hash.Sum(digest[:0])
copy(out[i:], digest)
}
return out
}
func IsEncryptedPEMBlock(b *pem.Block) bool {
_, ok := b.Headers["DEK-Info"]
return ok
}
var IncorrectPasswordError = errors.New("x509: decryption password incorrect")
func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) {
dek, ok := b.Headers["DEK-Info"]
if !ok {
return nil, errors.New("x509: no DEK-Info header in block")
}
idx := strings.Index(dek, ",")
if idx == -1 {
return nil, errors.New("x509: malformed DEK-Info header")
}
mode, hexIV := dek[:idx], dek[idx+1:]
ciph := cipherByName(mode)
if ciph == nil {
return nil, errors.New("x509: unknown encryption mode")
}
iv, err := hex.DecodeString(hexIV)
if err != nil {
return nil, err
}
if len(iv) != ciph.blockSize {
return nil, errors.New("x509: incorrect IV size")
}
key := ciph.deriveKey(password, iv[:8])
block, err := ciph.cipherFunc(key)
if err != nil {
return nil, err
}
if len(b.Bytes)%block.BlockSize() != 0 {
return nil, errors.New("x509: encrypted PEM data is not a multiple of the block size")
}
data := make([]byte, len(b.Bytes))
dec := cipher.NewCBCDecrypter(block, iv)
dec.CryptBlocks(data, b.Bytes)
dlen := len(data)
if dlen == 0 || dlen%ciph.blockSize != 0 {
return nil, errors.New("x509: invalid padding")
}
last := int(data[dlen-1])
if dlen < last {
return nil, IncorrectPasswordError
}
if last == 0 || last > ciph.blockSize {
return nil, IncorrectPasswordError
}
for _, val := range data[dlen-last:] {
if int(val) != last {
return nil, IncorrectPasswordError
}
}
return data[:dlen-last], nil
}
func EncryptPEMBlock(rand io.Reader, blockType string, data, password []byte, algo PEMCipher) (*pem.Block, error) {
ciph := cipherByKey(algo)
if ciph == nil {
return nil, errors.New("x509: unknown encryption mode")
}
iv := make([]byte, ciph.blockSize)
if _, err := io.ReadFull(rand, iv); err != nil {
return nil, errors.New("x509: cannot generate IV: " + err.Error())
}
key := ciph.deriveKey(password, iv[:8])
block, err := ciph.cipherFunc(key)
if err != nil {
return nil, err
}
enc := cipher.NewCBCEncrypter(block, iv)
pad := ciph.blockSize - len(data)%ciph.blockSize
encrypted := make([]byte, len(data), len(data)+pad)
copy(encrypted, data)
for i := 0; i < pad; i++ {
encrypted = append(encrypted, byte(pad))
}
enc.CryptBlocks(encrypted, encrypted)
return &pem.Block{
Type: blockType,
Headers: map[string]string{
"Proc-Type": "4,ENCRYPTED",
"DEK-Info": ciph.name + "," + hex.EncodeToString(iv),
},
Bytes: encrypted,
}, nil
}
func cipherByName(name string) *rfc1423Algo {
for i := range rfc1423Algos {
alg := &rfc1423Algos[i]
if alg.name == name {
return alg
}
}
return nil
}
func cipherByKey(key PEMCipher) *rfc1423Algo {
for i := range rfc1423Algos {
alg := &rfc1423Algos[i]
if alg.cipher == key {
return alg
}
}
return nil
}
func EncryptAndWriteBlock(cph string, block *pem.Block, pwd []byte, file *os.File) error {
var cipher PEMCipher
var err error
// Mapping between strings and PEMCipher values
cipherMap := map[string]PEMCipher{
"aes128": PEMCipherAES128,
"aes192": PEMCipherAES192,
"aes256": PEMCipherAES256,
"aes": PEMCipherAES256,
"3des": PEMCipher3DES,
"des": PEMCipherDES,
"sm4": PEMCipherSM4,
"gost": PEMCipherGOST,
"idea": PEMCipherIDEA,
"camellia128": PEMCipherCAMELLIA128,
"camellia192": PEMCipherCAMELLIA192,
"camellia256": PEMCipherCAMELLIA256,
"camellia": PEMCipherCAMELLIA256,
"aria128": PEMCipherARIA128,
"aria192": PEMCipherARIA192,
"aria256": PEMCipherARIA256,
"aria": PEMCipherARIA256,
"lea128": PEMCipherLEA128,
"lea192": PEMCipherLEA192,
"lea256": PEMCipherLEA256,
"lea": PEMCipherLEA256,
"seed": PEMCipherSEED,
"cast5": PEMCipherCAST,
"anubis": PEMCipherANUBIS,
"serpent128": PEMCipherSERPENT128,
"serpent192": PEMCipherSERPENT192,
"serpent256": PEMCipherSERPENT256,
"serpent": PEMCipherSERPENT256,
"rc6-128": PEMCipherRC6128,
"rc6-192": PEMCipherRC6192,
"rc6-256": PEMCipherRC6256,
"rc6": PEMCipherRC6256,
"magenta-128": PEMCipherMAGENTA128,
"magenta-192": PEMCipherMAGENTA192,
"magenta-256": PEMCipherMAGENTA256,
"magenta": PEMCipherMAGENTA256,
"crypton128": PEMCipherCRYPTON128,
"crypton192": PEMCipherCRYPTON192,
"crypton256": PEMCipherCRYPTON256,
"crypton": PEMCipherCRYPTON256,
"cast256-128": PEMCipherCAST256_128,
"cast256-192": PEMCipherCAST256_192,
"cast256-256": PEMCipherCAST256_256,
"cast256": PEMCipherCAST256_256,
"e2-128": PEMCipherE2128,
"e2-192": PEMCipherE2192,
"e2-256": PEMCipherE2256,
"e2": PEMCipherE2256,
"loki97-128": PEMCipherLOKI97128,
"loki97-192": PEMCipherLOKI97192,
"loki97-256": PEMCipherLOKI97256,
"loki97": PEMCipherLOKI97256,
"mars128": PEMCipherMARS128,
"mars192": PEMCipherMARS192,
"mars256": PEMCipherMARS256,
"mars": PEMCipherMARS256,
"noekeon": PEMCipherNOEKEON,
"twofish128": PEMCipherTWOFISH128,
"twofish192": PEMCipherTWOFISH192,
"twofish256": PEMCipherTWOFISH256,
"twofish": PEMCipherTWOFISH256,
"kalyna128_128": PEMCipherKALYNA128_128,
"kalyna128_256": PEMCipherKALYNA128_256,
"kalyna128": PEMCipherKALYNA128_256,
"kalyna": PEMCipherKALYNA128_256,
"kuznechik": PEMCipherGOST,
"grasshopper": PEMCipherGOST,
"curupira96": PEMCipherCURUPIRA96,
"curupira144": PEMCipherCURUPIRA144,
"curupira192": PEMCipherCURUPIRA192,
"curupira": PEMCipherCURUPIRA192,
"belt128": PEMCipherBELT128,
"belt192": PEMCipherBELT192,
"belt256": PEMCipherBELT256,
"belt": PEMCipherBELT256,
}
// Check if the cph string corresponds to a valid entry in the map
if val, ok := cipherMap[cph]; ok {
cipher = val
} else {
return errors.New("unsupported cipher algorithm")
}
// Call the EncryptPEMBlock function with the corresponding cipher value
block, err = EncryptPEMBlock(rand.Reader, block.Type, block.Bytes, pwd, cipher)
if err != nil {
return err
}
// Encode and write the block to the file
if err := pem.Encode(file, block); err != nil {
return err
}
return nil
}
func EncryptBlockWithCipher(rand io.Reader, blockType string, blockBytes, password []byte, cipherName string) (*pem.Block, error) {
var cipher PEMCipher
switch cipherName {
case "aes128":
cipher = PEMCipherAES128
case "aes192":
cipher = PEMCipherAES192
case "aes", "aes256":
cipher = PEMCipherAES256
case "3des":
cipher = PEMCipher3DES
case "des":
cipher = PEMCipherDES
case "sm4":
cipher = PEMCipherSM4
case "seed":
cipher = PEMCipherSEED
case "gost":
cipher = PEMCipherGOST
case "idea":
cipher = PEMCipherIDEA
case "camellia128":
cipher = PEMCipherCAMELLIA128
case "camellia192":
cipher = PEMCipherCAMELLIA192
case "camellia", "camellia256":
cipher = PEMCipherCAMELLIA256
case "aria128":
cipher = PEMCipherARIA128
case "aria192":
cipher = PEMCipherARIA192
case "aria", "aria256":
cipher = PEMCipherARIA256
case "lea128":
cipher = PEMCipherLEA128
case "lea192":
cipher = PEMCipherLEA192
case "lea", "lea256":
cipher = PEMCipherLEA256
case "cast5":
cipher = PEMCipherCAST
case "anubis":
cipher = PEMCipherANUBIS
case "serpent128":
cipher = PEMCipherSERPENT128
case "serpent192":
cipher = PEMCipherSERPENT192
case "serpent", "serpent256":
cipher = PEMCipherSERPENT256
case "rc6128":
cipher = PEMCipherRC6128
case "rc6192":
cipher = PEMCipherRC6192
case "rc6", "rc6256":
cipher = PEMCipherMAGENTA256
case "magenta128":
cipher = PEMCipherMAGENTA128
case "magenta192":
cipher = PEMCipherMAGENTA192
case "magenta", "magenta256":
cipher = PEMCipherMAGENTA256
case "crypton128":
cipher = PEMCipherCRYPTON128
case "crypton192":
cipher = PEMCipherCRYPTON192
case "crypton256", "crypton":
cipher = PEMCipherCRYPTON256
case "cast256-128":
cipher = PEMCipherCAST256_128
case "cast256-192":
cipher = PEMCipherCAST256_192
case "cast256-256", "cast256":
cipher = PEMCipherCAST256_256
case "e2-128":
cipher = PEMCipherE2128
case "e2-192":
cipher = PEMCipherE2192
case "e2-256", "e2":
cipher = PEMCipherE2256
case "loki97-128":
cipher = PEMCipherLOKI97128
case "loki97-192":
cipher = PEMCipherLOKI97192
case "loki97-256", "loki97":
cipher = PEMCipherLOKI97256
case "mars128":
cipher = PEMCipherMARS128
case "mars192":
cipher = PEMCipherMARS192
case "mars256", "mars":
cipher = PEMCipherMARS256
case "noekeon":
cipher = PEMCipherNOEKEON
case "twofish128":
cipher = PEMCipherTWOFISH128
case "twofish192":
cipher = PEMCipherTWOFISH192
case "twofish", "twofish256":
cipher = PEMCipherTWOFISH256
case "kalyna128_128":
cipher = PEMCipherKALYNA128_128
case "kalyna128", "kalyna128_256":
cipher = PEMCipherKALYNA128_256
case "kuznechik", "grasshopper":
cipher = PEMCipherGOST
case "curupira96":
cipher = PEMCipherCURUPIRA96
case "curupira144":
cipher = PEMCipherCURUPIRA144
case "curupira192", "curupira":
cipher = PEMCipherCURUPIRA192
case "belt128":
cipher = PEMCipherBELT128
case "belt192":
cipher = PEMCipherBELT192
case "belt", "belt256":
cipher = PEMCipherBELT256
default:
return nil, errors.New("unsupported cipher algorithm")
}
encryptedBlock, err := EncryptPEMBlock(rand, blockType, blockBytes, password, cipher)
if err != nil {
return nil, err
}
return encryptedBlock, nil
}
func setup(privateKey *big.Int, g, p *big.Int) *big.Int {
publicKey := new(big.Int).Exp(g, privateKey, p)
return publicKey
}
type PublicKey struct {
P, G, Y *big.Int
}
type PrivateKey struct {
PublicKey
X *big.Int
}
type elgamalEncrypt struct {
C1, C2 *big.Int
}
// Encrypt Asn1
func EncryptASN1(random io.Reader, pub *PublicKey, message []byte) ([]byte, error) {
c1, c2, err := EncryptLegacy(random, pub, message)
if err != nil {
return nil, err
}
return asn1.Marshal(elgamalEncrypt{
C1: c1,
C2: c2,
})
}
// Decrypt Asn1
func DecryptASN1(priv *PrivateKey, cipherData []byte) ([]byte, error) {
var enc elgamalEncrypt
_, err := asn1.Unmarshal(cipherData, &enc)
if err != nil {
return nil, err
}
return DecryptLegacy(priv, enc.C1, enc.C2)
}
// EncryptLegacy
func EncryptLegacy(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) {
m := new(big.Int).SetBytes(msg)
k, err := rand.Int(random, pub.P)
if err != nil {
return
}
c1 = new(big.Int).Exp(pub.G, k, pub.P)
s := new(big.Int).Exp(pub.Y, k, pub.P)
c2 = s.Mul(s, m)
c2.Mod(c2, pub.P)
return
}
// DecryptLegacy
func DecryptLegacy(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
s := new(big.Int).Exp(c1, priv.X, priv.P)
if s.ModInverse(s, priv.P) == nil {
return nil, errors.New("elgamal: invalid private key")
}
s.Mul(s, c2)
s.Mod(s, priv.P)
em := s.Bytes()
return em, nil
}
var (
zero = big.NewInt(0)
one = big.NewInt(1)
two = big.NewInt(2)
)
// Sign hash
func sign(random io.Reader, priv *PrivateKey, hash []byte) (*big.Int, *big.Int, error) {
k := new(big.Int)
gcd := new(big.Int)
var err error
// choosing random integer k from {1...(p-2)}, such that
// gcd(k,(p-1)) should be equal to 1.
for {
k, err = rand.Int(random, new(big.Int).Sub(priv.P, two))
if err != nil {
return nil, nil, err
}
if k.Cmp(one) == 0 {
continue
}
gcd = gcd.GCD(nil, nil, k, new(big.Int).Sub(priv.P, one))
if gcd.Cmp(one) == 0 {
break
}
}
// m as H(m)
m := new(big.Int).SetBytes(hash)
// r = g^k mod p
r := new(big.Int).Exp(priv.G, k, priv.P)
// xr = x * r
xr := new(big.Int).Mod(
new(big.Int).Mul(r, priv.X),
new(big.Int).Sub(priv.P, one),
)
// hmxr = [H(m)-xr]
hmxr := new(big.Int).Sub(m, xr)
// kInv = k^(-1)
kInv := k.ModInverse(k, new(big.Int).Sub(priv.P, one))
// s = [H(m) -xr]k^(-1) mod (p-1)
s := new(big.Int).Mul(hmxr, kInv)
s.Mod(s, new(big.Int).Sub(priv.P, one))
return r, s, nil
}
// Verify hash
func verify(pub *PublicKey, hash []byte, r, s *big.Int) (bool, error) {
// verify that 0 < r < p
signr := new(big.Int).Set(r)
if signr.Cmp(zero) == -1 {
return false, errors.New("elgamal: r is smaller than zero")
} else if signr.Cmp(pub.P) == +1 {
return false, errors.New("elgamal: r is larger than public key p")
}
signs := new(big.Int).Set(s)
if signs.Cmp(zero) == -1 {
return false, errors.New("elgamal: s is smaller than zero")
} else if signs.Cmp(new(big.Int).Sub(pub.P, one)) == +1 {
return false, errors.New("elgamal: s is larger than public key p")
}
// m as H(m)
m := new(big.Int).SetBytes(hash)
// ghashm = g^[H(m)] mod p
ghashm := new(big.Int).Exp(pub.G, m, pub.P)
// y^r * r*s mod p
YrRs := new(big.Int).Mod(
new(big.Int).Mul(
new(big.Int).Exp(pub.Y, signr, pub.P),
new(big.Int).Exp(signr, signs, pub.P),
),
pub.P,
)
// g^H(m) y^r * r*s mod p
if ghashm.Cmp(YrRs) == 0 {
return true, nil
}
return false, errors.New("elgamal: signature is not verified")
}
// r and s data
type elgamalSignature struct {
R, S *big.Int
}
// SignASN1 signs a hash (which should be the result of hashing a larger message)
// using the private key, priv. If the hash is longer than the bit-length of the
// private key's curve order, the hash will be truncated to that length. It
// returns the ASN.1 encoded signature.
func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
r, s, err := sign(rand, priv, hash)
if err != nil {
return nil, err
}
return asn1.Marshal(elgamalSignature{
R: r,
S: s,
})
}
// VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the
// public key, pub. Its return value records whether the signature is valid.
func VerifyASN1(pub *PublicKey, hash, sig []byte) (bool, error) {
var sign elgamalSignature
_, err := asn1.Unmarshal(sig, &sign)
if err != nil {
return false, err
}
return verify(pub, hash, sign.R, sign.S)
}
func encodePrivateKeyPEM(privPEM *PrivateKey) ([]byte, error) {
privBytes, err := MarshalPKCS8PrivateKey(privPEM)
if err != nil {
return nil, err
}
return privBytes, nil
}
func savePrivateKeyToPEM(fileName string, privKey *PrivateKey) error {
privBytes, err := MarshalPKCS8PrivateKey(privKey)
if err != nil {
return err
}
privPEM := &pem.Block{
Type: "ELGAMAL PRIVATE KEY",
Bytes: privBytes,
}
return savePEMToFile(fileName, privPEM, *pwd != "")
}
func readPrivateKeyFromPEM(fileName string) (*PrivateKey, error) {
pemData, err := ioutil.ReadFile(fileName)
if err != nil {
return nil, err
}
block, _ := pem.Decode(pemData)
if block == nil {
return nil, errors.New("failed to decode PEM block")
}
if block.Type != "ELGAMAL PRIVATE KEY" {
return nil, errors.New("unexpected PEM block type")
}
if block.Headers["Proc-Type"] == "4,ENCRYPTED" {
if *pwd == "" {
return nil, fmt.Errorf("private key is encrypted, but no decryption key provided")
}
// Descriptografa o bloco PEM
decryptedBlock, err := DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, err
}
block.Bytes = decryptedBlock
}
privKey, err := ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return privKey, nil
}
func savePublicKeyToPEM(fileName string, pubKey *PublicKey) error {
pubBytes, err := MarshalPKCS8PublicKey(pubKey)
if err != nil {
return err
}
pubPEM := &pem.Block{
Type: "ELGAMAL PUBLIC KEY",
Bytes: pubBytes,
}
return savePEMToFile(fileName, pubPEM, false)
}
func readPublicKeyFromPEM(fileName string) (*PublicKey, error) {
pemData, err := ioutil.ReadFile(fileName)
if err != nil {
return nil, err
}
block, _ := pem.Decode(pemData)
if block == nil {
return nil, errors.New("failed to decode PEM block")
}
pubKey, err := ParsePKCS8PublicKey(block.Bytes)
if err != nil {
return nil, err
}
return pubKey, nil
}
func generateRandomX(p *big.Int) (*big.Int, error) {
x, err := rand.Int(rand.Reader, new(big.Int).Sub(p, big.NewInt(2)))
if err != nil {
return nil, err
}
return x, nil
}
// isPrime checks if a number is prime using Miller-Rabin primality test.
func isPrime(n *big.Int) bool {
// Perform Miller-Rabin primality test with 20 iterations
return n.ProbablyPrime(20)
}
// generatePrime generates a prime number with exactly n bits.
func generatePrime(length int) (*big.Int, error) {
for {
// Generate a random number with at least n bits
randomBits := make([]byte, length/8)
_, err := rand.Read(randomBits)
if err != nil {
return nil, err
}
// Set the most significant and least significant bits to ensure an odd number
randomBits[0] |= 1
randomBits[len(randomBits)-1] |= 1
// Create a big integer from the generated bytes
prime := new(big.Int).SetBytes(randomBits)
// Adjust to exactly n bits
prime.SetBit(prime, length-1, 1)
// Check if the generated number is prime using Miller-Rabin test
if isPrime(prime) {
return prime, nil
}
// Print a dot to the console every second
print(".")
}
}
/*
// generateGenerator generates a generator in the range [2, p-2]
func generateGenerator(p *big.Int) (*big.Int, error) {
// Calculate the safe prime factor q of p
q := new(big.Int).Rsh(p, 1)
for {
// Choose a random generator G in the range [2, p-2]
g, err := rand.Int(rand.Reader, p)
if err != nil {
return nil, fmt.Errorf("error generating G: %v", err)
}
// Check if g is a valid generator for Zp*
temp := new(big.Int).Exp(g, q, p)
if temp.Cmp(big.NewInt(1)) != 0 {
return g, nil
}
}
}
*/
// generateGenerator generates a generator in the range [2, p-2]
func generateGenerator(p *big.Int) (*big.Int, error) {
// Calculate the safe prime factor q of p
q := new(big.Int).Rsh(p, 1)
// Define the upper limit for generating the generator
max := new(big.Int).Sub(p, two)
for {
// Choose a random generator g in the range [2, p-2]
g, err := rand.Int(rand.Reader, max)
if err != nil {
return nil, fmt.Errorf("error generating G: %v", err)
}
// Check if g^2 mod p != 1 and g^q mod p != 1
if g.Cmp(two) == 1 && new(big.Int).Exp(g, two, p).Cmp(one) != 0 && new(big.Int).Exp(g, q, p).Cmp(one) != 0 {
return g, nil
}
}
}
// ElGamalParams contains parameters for the ElGamal system
type ElGamalParams struct {
P *big.Int
G *big.Int
}
// generateElGamalParams generates parameters for the ElGamal system
func generateElGamalParams() (*ElGamalParams, error) {
// Desired size for the large prime number (P)
pSize := *length
// Generate the large prime number P with exactly pSize bits
p, err := generatePrime(pSize)
if err != nil {
return nil, fmt.Errorf("error generating P: %v", err)
}
// Generate a generator G in the range [2, P-2]
g, err := generateGenerator(p)
if err != nil {
return nil, fmt.Errorf("error generating G: %v", err)
}
return &ElGamalParams{
P: p,
G: g,
}, nil
}
func init() {
// Register ElGamalParams with the gob package
gob.Register(&ElGamalParams{})
}
// paramsToBytes encodes ElGamalParams to bytes.
func paramsToBytes(params *ElGamalParams) ([]byte, error) {
if params == nil {
return nil, errors.New("cannot encode nil ElGamalParams pointer")
}
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
err := enc.Encode(params)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// bytesToParams decodes bytes to ElGamalParams.
func bytesToParams(data []byte) (*ElGamalParams, error) {
var params ElGamalParams
dec := gob.NewDecoder(bytes.NewReader(data))
err := dec.Decode(&params)
if err != nil {
return nil, err
}
return &params, nil
}
// Save ElGamal parameters to a single PEM file or stdout
func saveElGamalParamsToPEM(fileName string, params *ElGamalParams) error {
var file *os.File
var err error
print("\n")
if fileName == "" {
// If fileName is empty, write to stdout
file = os.Stdout
} else {
// Otherwise, open the specified file
file, err = os.Create(fileName)
if err != nil {
return err
}
defer file.Close()
}
// Get the ElGamal parameters bytes
paramsBytes, err := paramsToBytes(params)
if err != nil {
return err
}
// Write the ElGamal parameters to a single PEM block
err = pem.Encode(file, &pem.Block{
Type: "ELGAMAL PARAMETERS",
Bytes: paramsBytes,
})
if err != nil {
return err
}
return nil
}
// readElGamalParamsFromPEM reads ElGamal parameters from a PEM file.
func readElGamalParamsFromPEM(fileName string) (*ElGamalParams, error) {
file, err := os.Open(fileName)
if err != nil {
return nil, err
}
defer file.Close()
pemData, err := io.ReadAll(file)
if err != nil {
return nil, err
}
block, _ := pem.Decode(pemData)
if block == nil {
return nil, errors.New("failed to decode PEM block")
}
return bytesToParams(block.Bytes)
}
func savePEMToFile(fileName string, block *pem.Block, isPrivateKey bool) error {
file, err := os.Create(fileName)
if err != nil {
return err
}
defer file.Close()
if isPrivateKey && *pwd != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
return err
}
}
return nil
}
func savePEMToFile2(fileName string, block *pem.Block, isPrivateKey bool) error {
file, err := os.Create(fileName)
if err != nil {
return err
}
defer file.Close()
if isPrivateKey && *pwd2 != "" {
err = EncryptAndWriteBlock(*cph, block, []byte(*pwd2), file)
if err != nil {
log.Fatal(err)
}
} else {
err = pem.Encode(file, block)
if err != nil {
return err
}
}
return nil
}
func readKeyFromPEM(fileName string, isPrivateKey bool) ([]byte, error) {
fileData, err := ioutil.ReadFile(fileName)
if err != nil {
return nil, err
}
block, _ := pem.Decode(fileData)
if block == nil {
return nil, fmt.Errorf("failed to decode PEM block")
}
if isPrivateKey && *pwd != "" {
decryptedBlock, err := DecryptPEMBlock(block, []byte(*pwd))
if err != nil {
return nil, fmt.Errorf("error decrypting PEM block: %v", err)
}
return decryptedBlock, nil
}
return block.Bytes, nil
}
// GenerateKyber generates a random seed and keys based on the specified key size.
func GenerateKyber(size int) ([]byte, []byte, error) {
// Generate a random seed
seed := make([]byte, 32)
if _, err := rand.Read(seed); err != nil {
return nil, nil, err
}
var d *kyber.Kyber
switch size {
case 512:
d = kyber.NewKyber512()
case 768:
d = kyber.NewKyber768()
case 1024:
d = kyber.NewKyber1024()
default:
return nil, nil, fmt.Errorf("invalid key size: %d. Valid sizes are: 512, 768 or 1024-bit.", size)
}
// Generate key pair
pk, sk := d.KeyGen(seed)
return pk, sk, nil
}
// WrapKey encapsulates a random shared secret using the recipient's public key
func WrapKey(pk []byte) error {
// Initialize Kyber instance
var k *kyber.Kyber
switch len(pk) {
case 800:
k = kyber.NewKyber512()
case 1184:
k = kyber.NewKyber768()
case 1568:
k = kyber.NewKyber1024()
default:
return fmt.Errorf("invalid public key size: %d", len(pk))
}
// Generate a random seed
seed := make([]byte, 32)
rand.Read(seed)
// Encapsulate a shared secret using the recipient's public key
ciphertext, ss := k.Encaps(pk, seed)
// Encode ciphertext to PEM format
ciphertextBlock := &pem.Block{
Type: "ML-KEM ENCAPSULATED KEY",
Bytes: ciphertext,
}
var writer io.Writer
if *cph == "" {
// Print to stdout
writer = os.Stdout
} else {
// Save to file
file, err := os.Create(*cph)
if err != nil {
return fmt.Errorf("error opening file %s: %v", *cph, err)
}
defer file.Close()
writer = file
}
// Encode to PEM and print to stdout
err := pem.Encode(writer, ciphertextBlock)
if err != nil {
return fmt.Errorf("error encoding ciphertext to PEM: %v", err)
}
fmt.Println("Shared=", hex.EncodeToString(ss))
return nil
}
// UnwrapKey unwraps the wrapped key using the recipient's secret key
func UnwrapKey(sk []byte, cipherFile string) ([]byte, error) {
// Read wrapped key from file
ciphertext, err := ioutil.ReadFile(cipherFile)
if err != nil {
return nil, fmt.Errorf("error reading wrapped key file: %v", err)
}
// Decode the PEM block
block, _ := pem.Decode(ciphertext)
if block == nil {
return nil, fmt.Errorf("failed to decode PEM block")
}
// Initialize Kyber instance
var k *kyber.Kyber
switch len(sk) {
case 1632:
k = kyber.NewKyber512()
case 2400:
k = kyber.NewKyber768()
case 3168:
k = kyber.NewKyber1024()
default:
return nil, fmt.Errorf("invalid public key size: %d", len(sk))
}
// Decapsulate the shared secret using the recipient's secret key
unwrappedSecret := k.Decaps(sk, block.Bytes)
return unwrappedSecret, nil
}
const (
Dilithium2Size = 2048
Dilithium3Size = 3072
Dilithium5Size = 4096
)
func GetDilithium(size int) *dilithium.Dilithium {
switch size {
case Dilithium2Size:
return dilithium.NewDilithium2()
case Dilithium3Size:
return dilithium.NewDilithium3()
case Dilithium5Size:
return dilithium.NewDilithium5()
default:
return nil
}
}
// Generate generates a random seed and keys based on the specified key size
func GenerateDilithium(length int) ([]byte, []byte, error) {
// Generate a random seed
seed := make([]byte, 32)
if _, err := rand.Read(seed); err != nil {
return nil, nil, err
}
// Generate key pair based on the specified length
d := GetDilithium(length)
if d == nil {
return nil, nil, fmt.Errorf("invalid key size: %d. Valid sizes are: 2048, 3072 or 4096-bit.", length)
}
pk, sk := d.KeyGen(seed)
return pk, sk, nil
}
// Sign signs the message using the provided secret key
func Sign(sk []byte, msgInput io.Reader) ([]byte, error) {
// Read message from input
msg, err := ioutil.ReadAll(msgInput)
if err != nil {
return nil, err
}
var d *dilithium.Dilithium
switch len(sk) {
case 2528:
d = dilithium.NewDilithium2()
case 4000:
d = dilithium.NewDilithium3()
case 4864:
d = dilithium.NewDilithium5()
default:
return nil, fmt.Errorf("invalid secret key size: %d", len(sk))
}
// Sign the message
signature := d.Sign(sk, msg)
return signature, nil
}
// Verify verifies the signature against the provided public key and message
func Verify(pk []byte, signatureFile string, msg []byte) error {
// Read the signature from the specified file
signatureBytes, err := ioutil.ReadFile(signatureFile)
if err != nil {
return err
}
// Decode the signature PEM block
block, _ := pem.Decode(signatureBytes)
if block == nil {
return fmt.Errorf("failed to decode PEM block")
}
// Ensure that the type of the PEM block is "ML-DSA SIGNATURE"
if block.Type != "ML-DSA SIGNATURE" {
return fmt.Errorf("unexpected PEM block type: %s", block.Type)
}
// Extract the signature bytes
signature := block.Bytes
var d *dilithium.Dilithium
switch len(pk) {
case 1312:
d = dilithium.NewDilithium2()
case 1952:
d = dilithium.NewDilithium3()
case 2592:
d = dilithium.NewDilithium5()
default:
return fmt.Errorf("invalid public key size: %d", len(pk))
}
// Verify the signature
verified := d.Verify(pk, msg, signature)
if !verified {
return fmt.Errorf("verification failed")
}
return nil
}
// Verify verifies the signature against the provided public key and message
func VerifyBytes(pk []byte, signature []byte, msg []byte) error {
var d *dilithium.Dilithium
switch len(pk) {
case 1312:
d = dilithium.NewDilithium2()
case 1952:
d = dilithium.NewDilithium3()
case 2592:
d = dilithium.NewDilithium5()
default:
return fmt.Errorf("invalid public key size: %d", len(pk))
}
// Verify the signature
verified := d.Verify(pk, msg, signature)
if !verified {
return fmt.Errorf("verification failed")
}
return nil
}
// SaveSignatureToPEM saves signature to pem file or prints to stdout if filename is empty
func SaveSignatureToPEM(signature []byte, filename string) error {
signatureBlock := &pem.Block{
Type: "ML-DSA SIGNATURE",
Bytes: signature,
}
if filename == "" {
// If filename is empty, encode the signature block to PEM and print to stdout
err := pem.Encode(os.Stdout, signatureBlock)
if err != nil {
return fmt.Errorf("error encoding signature to PEM: %v", err)
}
return nil
}
// Otherwise, save the signature to the specified file
return savePEMToFile(filename, signatureBlock, false)
}
type PKCS8Key struct{}
func NewPKCS8Key() PKCS8Key {
return PKCS8Key{}
}
func (this PKCS8Key) MarshalPublicKey(key *PublicKey) ([]byte, error) {
var publicKeyBytes []byte
var err error
// params
paramBytes, err := asn1.Marshal(ElGamalParams{
G: key.G,
P: key.P,
})
if err != nil {
return nil, errors.New("elgamal: failed to marshal algo param: " + err.Error())
}
publicKeyBytes = append(publicKeyBytes, paramBytes...)
yBytes := key.Y.Bytes()
publicKeyBytes = append(publicKeyBytes, yBytes...)
return publicKeyBytes, nil
}
func MarshalPKCS8PublicKey(pub *PublicKey) ([]byte, error) {
return NewPKCS8Key().MarshalPublicKey(pub)
}
func (this PKCS8Key) ParsePublicKey(der []byte) (*PublicKey, error) {
var pubKey PublicKey
var algoParams ElGamalParams
rest, err := asn1.Unmarshal(der, &algoParams)
if err != nil {
return nil, err
}
pubKey.G = algoParams.G
pubKey.P = algoParams.P
pubKey.Y = new(big.Int).SetBytes(rest)
return &pubKey, nil
}
func ParsePKCS8PublicKey(derBytes []byte) (*PublicKey, error) {
return NewPKCS8Key().ParsePublicKey(derBytes)
}
func (this PKCS8Key) MarshalPrivateKey(key *PrivateKey) ([]byte, error) {
var privateKeyBytes []byte
var err error
// params
paramBytes, err := asn1.Marshal(ElGamalParams{
G: key.G,
P: key.P,
})
if err != nil {
return nil, errors.New("elgamal: failed to marshal algo param: " + err.Error())
}
privateKeyBytes = append(privateKeyBytes, paramBytes...)
xBytes := key.X.Bytes()
privateKeyBytes = append(privateKeyBytes, xBytes...)
return privateKeyBytes, nil
}
func MarshalPKCS8PrivateKey(key *PrivateKey) ([]byte, error) {
return NewPKCS8Key().MarshalPrivateKey(key)
}
func (this PKCS8Key) ParsePrivateKey(der []byte) (key *PrivateKey, err error) {
var privKey PrivateKey
var algoParams ElGamalParams
rest, err := asn1.Unmarshal(der, &algoParams)
if err != nil {
return nil, err
}
privKey.G = algoParams.G
privKey.P = algoParams.P
privKey.X = new(big.Int).SetBytes(rest)
return &privKey, nil
}
func ParsePKCS8PrivateKey(derBytes []byte) (key *PrivateKey, err error) {
return NewPKCS8Key().ParsePrivateKey(derBytes)
}
// Ciphertext struct to store C1 and C2 for ASN.1 encoding
type Ciphertext struct {
C1 []byte
C2 []byte
}
type privateKeyMarshal struct {
Value []byte `bare:"value"`
Curve []byte `bare:"curve"`
}
type encryptionKeyMarshal struct {
Value []byte `bare:"value"`
Curve []byte `bare:"curve"`
}
// encrypt encrypts the value x using the public key Y and returns the components K and C.
func encrypt(c *curves.Curve, x *big.Int, G curves.Point, Y curves.Point) (K *big.Int, C curves.Point) {
if c == nil || G == nil || Y == nil || x == nil {
panic("one or more input parameters are null")
}
r := c.Scalar.Random(rand.Reader)
rY := Y.Mul(r)
rG := G.Mul(r)
rYval := new(big.Int).SetBytes(rY.ToAffineUncompressed())
K = new(big.Int).Add(rYval, x)
C = rG
return
}
// decrypt decrypts the components K and C using the private key y and returns the original value.
func decrypt(y curves.Scalar, K *big.Int, C curves.Point) *big.Int {
yC := C.Mul(y)
yCval := new(big.Int).SetBytes(yC.ToAffineUncompressed())
p := new(big.Int).Sub(K, yCval)
return p
}
// Função de criptografia (modificada para usar hash.Hash)
func encryptBN(message string, publicKey *bn256i.G2, hashFunc func() hash.Hash) (*bn256i.G1, *big.Int, []byte) {
// Converter a mensagem para um array de bytes
messageBytes := []byte(message)
// Gerar um valor aleatório k
k, err := rand.Int(rand.Reader, bn256i.Order)
if err != nil {
log.Fatal(err)
}
// Calcular k * G (ponto C1)
C1 := new(bn256i.G1).ScalarBaseMult(k)
// Derivar a chave de sessão a partir do paring (k * P)
pairingResult := bn256i.Pair(C1, publicKey)
// Criar a instância de hash
hashInstance := hashFunc()
// Calcular o hash do resultado do pairing
hashInstance.Write(pairingResult.Marshal())
sessionKey := hashInstance.Sum(nil)
// Criptografar a mensagem usando a chave de sessão derivada via XOR
encryptedMessage := make([]byte, len(messageBytes))
for i := range messageBytes {
encryptedMessage[i] = messageBytes[i] ^ sessionKey[i%len(sessionKey)]
}
// Calcular o hash da mensagem para integridade
hashInstance.Reset()
hashInstance.Write(messageBytes)
hashInstance.Write(sessionKey[:])
hash := hashInstance.Sum(nil)
return C1, new(big.Int).SetBytes(hash), encryptedMessage
}
// Função de descriptografia (modificada para usar hash.Hash)
func decryptBN(C1 *bn256i.G1, C2 *big.Int, encryptedMessage []byte, privateKey *big.Int, hashFunc func() hash.Hash) string {
// Calcular d * C1 (ponto C1MulPrivate)
C1MulPrivate := new(bn256i.G1).ScalarMult(C1, privateKey)
// Derivar a chave de sessão a partir do paring (d * C1)
pairingResult := bn256i.Pair(C1MulPrivate, new(bn256i.G2).ScalarBaseMult(big.NewInt(1)))
// Criar a instância de hash
hashInstance := hashFunc()
// Calcular o hash do resultado do pairing
hashInstance.Write(pairingResult.Marshal())
sessionKey := hashInstance.Sum(nil)
// Descriptografar a mensagem usando a chave de sessão derivada via XOR
decryptedMessage := make([]byte, len(encryptedMessage))
for i := range encryptedMessage {
decryptedMessage[i] = encryptedMessage[i] ^ sessionKey[i%len(sessionKey)]
}
// Verificar a integridade da mensagem usando o hash
hashInstance.Reset()
hashInstance.Write(decryptedMessage)
hashInstance.Write(sessionKey[:])
hash := hashInstance.Sum(nil)
if new(big.Int).SetBytes(C2.Bytes()).Cmp(new(big.Int).SetBytes(hash)) != 0 {
log.Fatal("Message integrity has been compromised!")
}
// Converter a mensagem de volta para string
return string(decryptedMessage)
}
// ASN.1 Serialization structures
type CiphertextBN struct {
C1 []byte
C2 *big.Int
C3 []byte
}
// Serialize the ciphertext components into ASN.1 format
func serializeToASN1(C1 *bn256i.G1, C2 *big.Int, encryptedMessage []byte) ([]byte, error) {
// Marshal C1 to bytes
C1Bytes := C1.Marshal()
// Prepare the structure to hold the ciphertext components
cipher := CiphertextBN{
C1: C1Bytes,
C2: C2,
C3: encryptedMessage,
}
// Serialize using ASN.1 encoding
serialized, err := asn1.Marshal(cipher)
if err != nil {
return nil, err
}
return serialized, nil
}
// Deserialize the ASN.1 format back into the ciphertext components
func deserializeFromASN1(serialized []byte) (*bn256i.G1, *big.Int, []byte, error) {
var cipher CiphertextBN
// Deserialize from ASN.1 format
_, err := asn1.Unmarshal(serialized, &cipher)
if err != nil {
return nil, nil, nil, err
}
// Unmarshal C1 from bytes back into bn256.G1
C1 := new(bn256i.G1)
_, err = C1.Unmarshal(cipher.C1)
if err != nil {
return nil, nil, nil, err
}
// Return the components of the ciphertext
return C1, cipher.C2, cipher.C3, nil
}
// Função de criptografia usando BLS12-381
func encryptBLS(message string, publicKey *bls12381.G2, hashFunc func() hash.Hash) (*bls12381.G1, *big.Int, []byte) {
// Converter a mensagem para um array de bytes
messageBytes := []byte(message)
// Gerar um valor aleatório k
order := new(big.Int).SetBytes(bls12381.Order())
k, err := rand.Int(rand.Reader, order)
if err != nil {
log.Fatal(err)
}
// Converter k para *ff.Scalar
kScalar := new(ff.Scalar)
kScalar.SetBytes(k.Bytes())
baseG1 := bls12381.G1Generator()
// Calcular k * G (ponto C1)
C1 := new(bls12381.G1)
C1.ScalarMult(kScalar, baseG1)
// Derivar a chave de sessão a partir do paring (k * G1, publicKey)
pairingResult := bls12381.Pair(C1, publicKey)
// Criar a instância de hash
hashInstance := hashFunc()
pariringResultBytes, err := pairingResult.MarshalBinary()
if err != nil {
log.Fatal(err)
}
// Calcular o hash do resultado do pairing
hashInstance.Write(pariringResultBytes)
sessionKey := hashInstance.Sum(nil)
// Criptografar a mensagem usando a chave de sessão derivada via XOR
encryptedMessage := make([]byte, len(messageBytes))
for i := range messageBytes {
encryptedMessage[i] = messageBytes[i] ^ sessionKey[i%len(sessionKey)]
}
// Calcular o hash da mensagem para integridade
hashInstance.Reset()
hashInstance.Write(messageBytes)
hashInstance.Write(sessionKey[:])
hash := hashInstance.Sum(nil)
return C1, new(big.Int).SetBytes(hash), encryptedMessage
}
// Função de descriptografia usando BLS12-381
func decryptBLS(C1 *bls12381.G1, C2 *big.Int, encryptedMessage []byte, privateKey *big.Int, hashFunc func() hash.Hash) string {
// Converter a chave privada de *big.Int para *ff.Scalar
skScalar := new(bls12381.Scalar)
skScalar.SetBytes(privateKey.Bytes())
// Calcular d * C1 (ponto C1MulPrivate) usando a chave privada
C1MulPrivate := new(bls12381.G1)
C1MulPrivate.ScalarMult(skScalar, C1)
// Derivar a chave de sessão a partir do paring (C1MulPrivate, G2)
pairingResult := bls12381.Pair(C1MulPrivate, bls12381.G2Generator())
// Criar a instância de hash
hashInstance := hashFunc()
pariringResultBytes, err := pairingResult.MarshalBinary()
if err != nil {
log.Fatal(err)
}
// Calcular o hash do resultado do pairing
hashInstance.Write(pariringResultBytes)
sessionKey := hashInstance.Sum(nil)
// Descriptografar a mensagem usando a chave de sessão derivada via XOR
decryptedMessage := make([]byte, len(encryptedMessage))
for i := range encryptedMessage {
decryptedMessage[i] = encryptedMessage[i] ^ sessionKey[i%len(sessionKey)]
}
// Verificar a integridade da mensagem usando o hash
hashInstance.Reset()
hashInstance.Write(decryptedMessage)
hashInstance.Write(sessionKey[:])
hash := hashInstance.Sum(nil)
if new(big.Int).SetBytes(C2.Bytes()).Cmp(new(big.Int).SetBytes(hash)) != 0 {
log.Fatal("Message integrity has been compromised!")
}
// Converter a mensagem de volta para string
return string(decryptedMessage)
}
// ASN.1 Serialization structures para BLS12-381
type CiphertextBLS struct {
C1 []byte
C2 *big.Int
C3 []byte
}
// Serialize the ciphertext components into ASN.1 format
func serializeToASN1BLS(C1 *bls12381.G1, C2 *big.Int, encryptedMessage []byte) ([]byte, error) {
// Marshal C1 to bytes
C1Bytes := C1.Bytes()
// Prepare the structure to hold the ciphertext components
cipher := CiphertextBLS{
C1: C1Bytes,
C2: C2,
C3: encryptedMessage,
}
// Serialize using ASN.1 encoding
serialized, err := asn1.Marshal(cipher)
if err != nil {
return nil, err
}
return serialized, nil
}
// Deserialize the ASN.1 format back into the ciphertext components
func deserializeFromASN1BLS(serialized []byte) (*bls12381.G1, *big.Int, []byte, error) {
var cipher CiphertextBLS
// Deserialize from ASN.1 format
_, err := asn1.Unmarshal(serialized, &cipher)
if err != nil {
return nil, nil, nil, err
}
// Unmarshal C1 from bytes back into bls12381.G1
C1 := new(bls12381.G1)
_ = C1.SetBytes(cipher.C1)
if err != nil {
return nil, nil, nil, err
}
// Return the components of the ciphertext
return C1, cipher.C2, cipher.C3, nil
}
// Certificate represents a digital certificate
type Certificate struct {
SerialNumber *big.Int `asn1:"explicit,tag:0"`
Subject pkix.Name `asn1:"explicit,tag:1"`
Issuer pkix.Name `asn1:"explicit,tag:2"`
NotBefore time.Time `asn1:"explicit,tag:3"`
NotAfter time.Time `asn1:"explicit,tag:4"`
PublicKey []byte `asn1:"explicit,tag:5"`
SubjectKeyID []byte `asn1:"explicit,tag:6"`
AuthorityKeyID []byte `asn1:"explicit,tag:7"`
SubjectEmail string `asn1:"explicit,tag:8"`
IsCA bool `asn1:"explicit,tag:9"`
Signature []byte `asn1:"explicit,tag:10"`
}
// CA represents a Certificate Authority
type CA struct {
PrivateKey []byte
Certificate Certificate
}
// IssueCertificate issues a new certificate for a subject
func (ca *CA) IssueCertificate(subject pkix.Name, email string, publicKey, privateKey []byte, isCA bool, validityDays string) (*Certificate, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 160)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %v", err)
}
// Generate SKID (using SHA-1 hash of the public key)
hash := sha3.Sum256(publicKey)
subjectKeyID := hash[:20]
// Use the CA's public key to create AKID (assuming CA.PublicKey is accessible)
caHash := sha3.Sum256(ca.Certificate.PublicKey)
authorityKeyID := caHash[:20]
validity, err := strconv.Atoi(validityDays)
if err != nil {
log.Fatalf("Invalid validity: %v", err)
}
notAfter := time.Now().Add(time.Duration(validity) * 24 * time.Hour)
cert := &Certificate{
SerialNumber: serialNumber,
Subject: subject,
SubjectEmail: email,
// Issuer: ca.Certificate.Subject,
Issuer: subject,
NotBefore: time.Now(),
NotAfter: notAfter,
PublicKey: publicKey,
SubjectKeyID: subjectKeyID,
AuthorityKeyID: authorityKeyID,
IsCA: isCA,
}
if !isCA {
cert.Issuer = ca.Certificate.Subject
}
if *isca {
cert.IsCA = true
}
// Creating structure with the data to be signed
TBS := struct {
SerialNumber *big.Int `asn1:"explicit,tag:0"`
Subject pkix.Name `asn1:"explicit,tag:1"`
Issuer pkix.Name `asn1:"explicit,tag:2"`
NotBefore time.Time `asn1:"explicit,tag:3"`
NotAfter time.Time `asn1:"explicit,tag:4"`
PublicKey []byte `asn1:"explicit,tag:5"`
SubjectKeyID []byte `asn1:"explicit,tag:6"`
AuthorityKeyID []byte `asn1:"explicit,tag:7"`
SubjectEmail string `asn1:"explicit,tag:8"`
IsCA bool `asn1:"explicit,tag:9"`
}{
SerialNumber: cert.SerialNumber,
Subject: cert.Subject,
Issuer: cert.Issuer,
NotBefore: cert.NotBefore,
NotAfter: cert.NotAfter,
PublicKey: publicKey,
SubjectKeyID: subjectKeyID,
AuthorityKeyID: authorityKeyID,
SubjectEmail: email,
IsCA: cert.IsCA,
}
// Serialize only the necessary fields using ASN.1
certData, err := asn1.Marshal(TBS)
if err != nil {
return nil, fmt.Errorf("error serializing the data for signing: %v", err)
}
var signature []byte
switch strings.ToUpper(*alg) {
case "ML-DSA":
signature, err = Sign(privateKey, bytes.NewReader(certData))
if err != nil {
return nil, fmt.Errorf("failed to sign with ML-DSA: %v", err)
}
case "SLH-DSA":
signature, err = SignSLH(privateKey, bytes.NewReader(certData))
if err != nil {
return nil, fmt.Errorf("failed to sign with SLH-DSA: %v", err)
}
case "BN256I":
skBigInt := new(big.Int).SetBytes(privateKey)
hash := bn256i.HashG1(certData, []byte(*salt))
signatureBN := hash.ScalarMult(hash, skBigInt)
if err != nil {
return nil, fmt.Errorf("failed to sign with BN256: %v", err)
}
signature = signatureBN.Marshal()
case "BLS12381I":
var privKey bls.PrivateKey[bls.G2]
privKey.UnmarshalBinary(privateKey)
signature = bls.Sign(&privKey, certData)
if err != nil {
return nil, fmt.Errorf("failed to sign with BLS12381: %v", err)
}
default:
return nil, fmt.Errorf("unsupported algorithm: %s", *alg)
}
cert.Signature = signature
return cert, nil
}
// SaveCertificateToPEM saves the certificate to a PEM file or prints to stdout
func SaveCertificateToPEM(cert *Certificate, filename string) error {
// Serialize only the necessary fields using ASN.1
certData, err := asn1.Marshal(*cert)
if err != nil {
return fmt.Errorf("error serializing the certificate: %v", err)
}
// Create the PEM block
certBlock := &pem.Block{
Type: strings.ToUpper(*alg) + " CERTIFICATE",
Bytes: certData,
}
// If filename is "stdout", print to stdout
if filename == "stdout" {
// Print the PEM block directly to stdout
err := pem.Encode(os.Stdout, certBlock)
if err != nil {
return fmt.Errorf("error printing the certificate to stdout: %v", err)
}
} else {
// Otherwise, create the file and write the certificate to it
file, err := os.Create(filename)
if err != nil {
return fmt.Errorf("error creating the file: %v", err)
}
defer file.Close()
// Write the PEM block to the file
err = pem.Encode(file, certBlock)
if err != nil {
return fmt.Errorf("error writing the certificate to the file: %v", err)
}
}
return nil
}
// NewCA creates a new Certificate Authority
func NewCA(privateKey, publicKey []byte, validityDays string) *CA {
validity, err := strconv.Atoi(validityDays)
if err != nil {
log.Fatalf("Invalid validity: %v", err)
}
notAfter := time.Now().Add(time.Duration(validity) * 24 * time.Hour)
return &CA{
PrivateKey: privateKey,
Certificate: Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{},
Issuer: pkix.Name{},
NotBefore: time.Now(),
NotAfter: notAfter,
PublicKey: publicKey,
},
}
}
// VerifyCertificate verifica se a chave pública corresponde ao certificado
func VerifyCertificate(cert *Certificate, publicKey []byte) error {
TBS := struct {
SerialNumber *big.Int `asn1:"explicit,tag:0"`
Subject pkix.Name `asn1:"explicit,tag:1"`
Issuer pkix.Name `asn1:"explicit,tag:2"`
NotBefore time.Time `asn1:"explicit,tag:3"`
NotAfter time.Time `asn1:"explicit,tag:4"`
PublicKey []byte `asn1:"explicit,tag:5"`
SubjectKeyID []byte `asn1:"explicit,tag:6"`
AuthorityKeyID []byte `asn1:"explicit,tag:7"`
SubjectEmail string `asn1:"explicit,tag:8"`
IsCA bool `asn1:"explicit,tag:9"`
}{
SerialNumber: cert.SerialNumber,
Subject: cert.Subject,
Issuer: cert.Issuer,
NotBefore: cert.NotBefore,
NotAfter: cert.NotAfter,
PublicKey: cert.PublicKey,
SubjectKeyID: cert.SubjectKeyID,
AuthorityKeyID: cert.AuthorityKeyID,
SubjectEmail: cert.SubjectEmail,
IsCA: cert.IsCA,
}
// Serialize the certificate data with ASN.1
certData, err := asn1.Marshal(TBS)
if err != nil {
return fmt.Errorf("error serializing the certificate data: %v", err)
}
signature := cert.Signature
switch strings.ToUpper(*alg) {
case "ML-DSA":
return VerifyBytes(publicKey, signature, certData)
case "SLH-DSA":
return VerifySLH(publicKey, signature, certData)
case "BN256I":
return VerifyBN(publicKey, signature, certData, []byte(*salt))
case "BLS12381I":
return VerifyBLS(publicKey, signature, certData)
default:
return fmt.Errorf("unsupported algorithm: %s", *alg)
}
}
// ReadCertificateFromPEM lê um certificado de um arquivo PEM
func ReadCertificateFromPEM(filename string) (*Certificate, error) {
certBytes, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
block, _ := pem.Decode(certBytes)
if block == nil {
return nil, errors.New("failed to decode PEM block")
}
if block.Type != strings.ToUpper(*alg) + " CERTIFICATE" {
return nil, errors.New("unexpected PEM block type")
}
var cert Certificate
_, err = asn1.Unmarshal(block.Bytes, &cert)
if err != nil {
return nil, fmt.Errorf("error deserializing the certificate (ASN.1): %v", err)
}
return &cert, nil
}
// IsValid checks if the certificate is currently valid
func (cert *Certificate) IsValid() bool {
now := time.Now()
return now.After(cert.NotBefore) && now.Before(cert.NotAfter)
}
// PrintInfo can print the certificate info or CSR info based on the type
func PrintInfo(certOrCsr interface{}) {
switch v := certOrCsr.(type) {
case *Certificate:
PrintCertificateInfo(v)
case *CSR:
PrintCSRInfo(v)
default:
fmt.Println("Unknown type!")
}
}
// PrintCertificateInfo displays the attributes of a digital certificate
func PrintCertificateInfo(cert *Certificate) {
fmt.Printf("Certificate:\n")
fmt.Printf(" Data:\n")
fmt.Printf(" Serial Number: %s (0x%x)\n", cert.SerialNumber.String(), cert.SerialNumber)
fmt.Printf(" Issuer: %s\n", cert.Issuer)
fmt.Printf(" Authority Key ID: %x\n", cert.AuthorityKeyID)
fmt.Printf(" Validity\n")
fmt.Printf(" Not Before: %s\n", cert.NotBefore.Format(time.RFC3339))
fmt.Printf(" Not After : %s\n", cert.NotAfter.Format(time.RFC3339))
fmt.Printf(" Subject: %s\n", cert.Subject)
fmt.Printf(" Subject Key ID: %x\n", cert.SubjectKeyID)
fmt.Printf(" Subject Email: %s\n", cert.SubjectEmail)
if cert.IsCA == true {
fmt.Printf(" IsCA: %v\n", cert.IsCA)
}
fmt.Printf(" Signature Algorithm: %s\n", strings.ToUpper(*alg))
fmt.Printf(" Public Key:\n")
// Verifica se o algoritmo é "SLH-DSA" ou "ML-DSA"
if strings.ToUpper(*alg) == "SLH-DSA" || strings.ToUpper(*alg) == "ML-DSA" {
// Exibe apenas os primeiros 128 bits (16 bytes) da chave pública
splitz := SplitSubN(hex.EncodeToString(cert.PublicKey[:64]), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
} else {
// Exibe a chave pública inteira
splitz := SplitSubN(hex.EncodeToString(cert.PublicKey), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
}
if strings.ToUpper(*alg) == "ML-DSA" {
fmt.Println(" [...]")
}
fmt.Printf(" Signature:\n")
// Verificar se o algoritmo é BLS12381
if strings.ToUpper(*alg) == "BLS12381I" {
// Exibe a assinatura inteira para BLS12381
splitz := SplitSubN(hex.EncodeToString(cert.Signature), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
} else {
// Para outros algoritmos, exibe apenas os primeiros 64 bytes da assinatura
splitz := SplitSubN(hex.EncodeToString(cert.Signature[:64]), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
}
if strings.ToUpper(*alg) == "ML-DSA" || strings.ToUpper(*alg) == "SLH-DSA" {
fmt.Println(" [...]")
}
fmt.Printf("IsValid: %t\n", cert.IsValid())
}
// PrintCSRInfo displays the attributes of a CSR
func PrintCSRInfo(csr *CSR) {
fmt.Printf("CSR:\n")
fmt.Printf(" Data:\n")
fmt.Printf(" Subject: %s\n", csr.Subject)
fmt.Printf(" Email: %s\n", csr.Email)
fmt.Printf(" Algorithm: %s\n", strings.ToUpper(*alg))
fmt.Printf(" Public Key:\n")
// Verifica se o algoritmo é "SLH-DSA" ou "ML-DSA"
if strings.ToUpper(*alg) == "SLH-DSA" || strings.ToUpper(*alg) == "ML-DSA" {
// Exibe apenas os primeiros 128 bits (16 bytes) da chave pública
splitz := SplitSubN(hex.EncodeToString(csr.PublicKey[:64]), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
} else {
// Exibe a chave pública inteira
splitz := SplitSubN(hex.EncodeToString(csr.PublicKey), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
}
if strings.ToUpper(*alg) == "ML-DSA" {
fmt.Println(" [...]")
}
fmt.Printf(" Signature:\n")
// Verificar se o algoritmo é BLS12381
if strings.ToUpper(*alg) == "BLS12381I" {
// Exibe a assinatura inteira para BLS12381
splitz := SplitSubN(hex.EncodeToString(csr.Signature), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
} else {
// Para outros algoritmos, exibe apenas os primeiros 64 bytes da assinatura
splitz := SplitSubN(hex.EncodeToString(csr.Signature[:64]), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
}
if strings.ToUpper(*alg) == "ML-DSA" || strings.ToUpper(*alg) == "SLH-DSA" {
fmt.Println(" [...]")
}
}
type CSR struct {
Subject pkix.Name `asn1:"explicit,tag:0"`
PublicKey []byte `asn1:"explicit,tag:1"`
Email string `asn1:"explicit,tag:2"`
Signature []byte `asn1:"explicit,tag:3"`
}
func CreateCSR(subject pkix.Name, email string, publicKey, privateKey []byte) (*CSR, error) {
csr := &CSR{
Subject: subject,
PublicKey: publicKey,
Email: email,
}
// Usando ASN.1
TBS := struct {
Subject pkix.Name `asn1:"explicit,tag:0"`
PublicKey []byte `asn1:"explicit,tag:1"`
Email string `asn1:"explicit,tag:2"`
}{
Subject: csr.Subject,
PublicKey: csr.PublicKey,
Email: csr.Email,
}
// Serialize the data to sign
certData, err := asn1.Marshal(TBS)
if err != nil {
return nil, fmt.Errorf("error serializing CSR data: %v", err)
}
var signature []byte
switch strings.ToUpper(*alg) {
case "ML-DSA":
signature, err = Sign(privateKey, bytes.NewReader(certData))
if err != nil {
return nil, fmt.Errorf("failed to sign with ML-DSA: %v", err)
}
case "SLH-DSA":
signature, err = SignSLH(privateKey, bytes.NewReader(certData))
if err != nil {
return nil, fmt.Errorf("failed to sign with SLH-DSA: %v", err)
}
case "BN256I":
skBigInt := new(big.Int).SetBytes(privateKey)
hash := bn256i.HashG1(certData, []byte(*salt))
signatureBN := hash.ScalarMult(hash, skBigInt)
if err != nil {
return nil, fmt.Errorf("failed to sign with BN256: %v", err)
}
signature = signatureBN.Marshal()
case "BLS12381I":
var privKey bls.PrivateKey[bls.G2]
privKey.UnmarshalBinary(privateKey)
signature = bls.Sign(&privKey, certData)
if err != nil {
return nil, fmt.Errorf("failed to sign with BLS12381: %v", err)
}
default:
return nil, fmt.Errorf("unsupported algorithm: %s", *alg)
}
// Assign the signature to the CSR
csr.Signature = signature
return csr, nil
}
func SignCSR(csr *CSR, ca *CA, privateKey []byte, validityDays string) (*Certificate, error) {
// Verifica se o certificado da CA é realmente uma CA
if !ca.Certificate.IsCA {
return nil, fmt.Errorf("the CA certificate is not a valid CA, cannot sign CSR")
}
// Use a função IssueCertificate da CA para gerar o certificado, passando a validade
err := VerifyCSR(csr)
if err != nil {
return nil, fmt.Errorf("CSR verification failed: %v", err)
}
signedCert, err := ca.IssueCertificate(csr.Subject, csr.Email, csr.PublicKey, privateKey, false, validityDays)
if err != nil {
return nil, fmt.Errorf("failed to issue certificate: %v", err)
}
return signedCert, nil
}
// VerifyCSR verifica se a chave pública corresponde ao certificado
func VerifyCSR(csr *CSR) error {
// Usando ASN.1 diretamente, sem JSON
TBS := struct {
Subject pkix.Name `asn1:"explicit,tag:0"`
PublicKey []byte `asn1:"explicit,tag:1"`
Email string `asn1:"explicit,tag:2"`
}{
Subject: csr.Subject,
PublicKey: csr.PublicKey,
Email: csr.Email,
}
// Serializa a estrutura para DER (ASN.1)
certData, err := asn1.Marshal(TBS)
if err != nil {
return fmt.Errorf("error serializing the certificate data (ASN.1): %v", err)
}
// Verificação de assinatura com base no algoritmo
switch strings.ToUpper(*alg) {
case "ML-DSA":
return VerifyBytes(csr.PublicKey, csr.Signature, certData)
case "SLH-DSA":
return VerifySLH(csr.PublicKey, csr.Signature, certData)
case "BN256I":
return VerifyBN(csr.PublicKey, csr.Signature, certData, []byte(*salt))
case "BLS12381I":
return VerifyBLS(csr.PublicKey, csr.Signature, certData)
default:
return fmt.Errorf("unsupported algorithm: %s", *alg)
}
}
func VerifyBN(publicKey []byte, signature []byte, certData []byte, salt []byte) error {
// Desserializar chave pública
var pubKey bn256i.G2
_, err := pubKey.Unmarshal(publicKey)
if err != nil {
return fmt.Errorf("error deserializing public key: %v", err)
}
// Desserializar a assinatura
var sig bn256i.G1
sig.Unmarshal(signature)
// Verificação da assinatura
h := bn256i.HashG1(certData, salt)
rhs := bn256i.Pair(h, &pubKey)
lhs := bn256i.Pair(&sig, new(bn256i.G2).ScalarBaseMult(big.NewInt(1)))
if bytes.Equal(rhs.Marshal(), lhs.Marshal()) {
// fmt.Println("Verified: true")
return nil
} else {
// fmt.Println("Verified: false")
return fmt.Errorf("signature verification failed")
}
}
// VerifyBLS verifica a assinatura BLS12381 com a chave pública fornecida.
func VerifyBLS(publicKey []byte, signature []byte, certData []byte) error {
// Desserializar chave pública
var pubKey bls.PublicKey[bls.G2]
err := pubKey.UnmarshalBinary(publicKey)
if err != nil {
return fmt.Errorf("error unmarshaling public key: %v", err)
}
// Verificar a assinatura com a chave pública
valid := bls.Verify(&pubKey, certData, signature)
if valid {
// Assinatura válida
return nil
} else {
// Assinatura inválida
return fmt.Errorf("signature verification failed")
}
}
// SaveCSRToPEM salva o CSR em um arquivo PEM usando ASN.1 ao invés de JSON
func SaveCSRToPEM(csr *CSR, filename string) error {
// Usando ASN.1 para serializar o CSR
csrData, err := asn1.Marshal(*csr)
if err != nil {
return fmt.Errorf("error serializing CSR to DER (ASN.1): %v", err)
}
// Cria um bloco PEM com os dados ASN.1 do CSR
csrBlock := &pem.Block{
Type: strings.ToUpper(*alg) + "CERTIFICATE REQUEST",
Bytes: csrData,
}
// Cria o arquivo de saída
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
// Codifica o bloco PEM e escreve no arquivo
return pem.Encode(file, csrBlock)
}
// ReadCSRFromPEM lê um CSR de um arquivo PEM e o converte de volta para a estrutura CSR
func ReadCSRFromPEM(filename string) (*CSR, error) {
// Lê o arquivo PEM
csrBytes, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
// Decodifica o bloco PEM
block, _ := pem.Decode(csrBytes)
if block == nil {
return nil, errors.New("failed to decode PEM block")
}
// Verifica se o tipo do bloco PEM é "CERTIFICATE REQUEST"
if block.Type != strings.ToUpper(*alg) + "CERTIFICATE REQUEST" {
return nil, errors.New("unexpected PEM block type")
}
// Usa ASN.1 para deserializar os dados do CSR
var csr CSR
_, err = asn1.Unmarshal(block.Bytes, &csr)
if err != nil {
return nil, fmt.Errorf("error deserializing CSR from ASN.1: %v", err)
}
// Retorna o CSR
return &csr, nil
}
// CRL (Certificate Revocation List) estrutura com tags ASN.1
type CRL struct {
Issuer pkix.Name `asn1:"explicit,tag:0"`
NotBefore time.Time `asn1:"explicit,tag:1"`
NotAfter time.Time `asn1:"explicit,tag:2"`
RawData []byte `asn1:"explicit,tag:3"`
SerialNumber *big.Int `asn1:"explicit,tag:4"`
AuthorityKeyID []byte `asn1:"explicit,tag:5"`
RevokedCertificates []RevokedCertificate `asn1:"explicit,tag:6"`
Signature []byte `asn1:"explicit,tag:7"`
}
// RevokedCertificate estrutura com tags ASN.1
type RevokedCertificate struct {
SerialNumber *big.Int `asn1:"explicit,tag:0"`
RevocationTime time.Time `asn1:"explicit,tag:1"`
}
func NewCRL(ca *CA, oldCRLFile string, validityDays string) (*CRL, error) {
var revokedCertificates []RevokedCertificate
validity, err := strconv.Atoi(validityDays)
if err != nil {
log.Fatalf("Invalid validity: %v", err)
}
notAfter := time.Now().Add(time.Duration(validity) * 24 * time.Hour)
// Se um arquivo de CRL antiga for passado, leia os dados dela
if oldCRLFile != "" {
oldCRL, err := ReadCRLFromPEM(oldCRLFile)
if err != nil {
return nil, fmt.Errorf("error reading the old CRL: %v", err)
}
revokedCertificates = oldCRL.RevokedCertificates
}
// Crie uma nova CRL com os certificados revogados existentes
newCRL := &CRL{
RevokedCertificates: revokedCertificates,
Issuer: ca.Certificate.Subject,
NotBefore: time.Now(),
NotAfter: notAfter,
SerialNumber: big.NewInt(1),
AuthorityKeyID: ca.Certificate.AuthorityKeyID,
}
return newCRL, nil
}
func (crl *CRL) RevokeCertificate(serialNumber *big.Int) {
crl.RevokedCertificates = append(crl.RevokedCertificates, RevokedCertificate{
SerialNumber: serialNumber,
RevocationTime: time.Now(),
})
}
// Sign assina o CRL com a chave privada da CA
func (crl *CRL) Sign(ca *CA, cert *Certificate) error {
// Assign the Authority Key ID from the certificate
crl.AuthorityKeyID = cert.AuthorityKeyID
// Set the Issuer from the certificate
crl.Issuer = cert.Issuer
// Assign a new Serial Number for the CRL
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 80)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return fmt.Errorf("error generating the serial number for the CRL: %v", err)
}
crl.SerialNumber = serialNumber
// Cria a estrutura TBS (To Be Signed) com os campos que serão assinados
TBS := struct {
Issuer pkix.Name `asn1:"explicit,tag:0"`
NotBefore time.Time `asn1:"explicit,tag:1"`
NotAfter time.Time `asn1:"explicit,tag:2"`
SerialNumber *big.Int `asn1:"explicit,tag:3"`
AuthorityKeyID []byte `asn1:"explicit,tag:4"`
RevokedCertificates []RevokedCertificate `asn1:"explicit,tag:5"`
}{
Issuer: crl.Issuer,
NotBefore: crl.NotBefore,
NotAfter: crl.NotAfter,
SerialNumber: crl.SerialNumber,
AuthorityKeyID: crl.AuthorityKeyID,
RevokedCertificates: crl.RevokedCertificates,
}
// Serializa o CRL para ASN.1 (DER)
crlData, err := asn1.Marshal(TBS)
if err != nil {
return fmt.Errorf("error serializing CRL data: %v", err)
}
// Assinando o CRL com a chave privada da CA
var signature []byte
switch strings.ToUpper(*alg) {
case "ML-DSA":
signature, err = Sign(ca.PrivateKey, bytes.NewReader(crlData))
if err != nil {
return fmt.Errorf("failed to sign with ML-DSA: %v", err)
}
case "SLH-DSA":
signature, err = SignSLH(ca.PrivateKey, bytes.NewReader(crlData))
if err != nil {
return fmt.Errorf("failed to sign with SLH-DSA: %v", err)
}
case "BN256I":
skBigInt := new(big.Int).SetBytes(ca.PrivateKey)
hash := bn256i.HashG1(crlData, []byte(*salt))
signatureBN := hash.ScalarMult(hash, skBigInt)
if err != nil {
return fmt.Errorf("failed to sign with BN256: %v", err)
}
signature = signatureBN.Marshal()
case "BLS12381I":
var privKey bls.PrivateKey[bls.G2]
privKey.UnmarshalBinary(ca.PrivateKey)
signature = bls.Sign(&privKey, crlData)
if err != nil {
return fmt.Errorf("failed to sign with BLS12381: %v", err)
}
default:
return fmt.Errorf("unsupported algorithm: %s", *alg)
}
// Atribui a assinatura ao CRL
crl.Signature = signature
crl.RawData = crlData
return nil
}
func SaveCRLToPEM(crl *CRL, filename string) error {
crlData, err := asn1.Marshal(*crl)
if err != nil {
return fmt.Errorf("error serializing CRL: %v", err)
}
crlBlock := &pem.Block{
Type: strings.ToUpper(*alg) + " CRL",
Bytes: crlData,
}
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
return pem.Encode(file, crlBlock)
}
func ReadCRLFromPEM(filename string) (*CRL, error) {
crlBytes, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
block, _ := pem.Decode(crlBytes)
if block == nil {
return nil, errors.New("failed to decode PEM block")
}
if block.Type != strings.ToUpper(*alg) + " CRL" {
return nil, errors.New("unexpected PEM block type")
}
var crl CRL
_, err = asn1.Unmarshal(block.Bytes, &crl)
if err != nil {
return nil, fmt.Errorf("error deserializing CRL: %v", err)
}
return &crl, nil
}
func (crl *CRL) IsRevoked(serialNumber *big.Int) bool {
for _, revoked := range crl.RevokedCertificates {
if revoked.SerialNumber.Cmp(serialNumber) == 0 {
return true
}
}
return false
}
// Function to read revoked serial numbers from a text file
func readRevokedSerials(filename string) ([]*big.Int, error) {
var serials []*big.Int
data, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
lines := strings.Split(string(data), "\n")
for _, line := range lines {
if line != "" {
serial, ok := new(big.Int).SetString(line, 10)
if ok {
serials = append(serials, serial)
} else {
fmt.Printf("Invalid serial number format: %s\n", line)
}
}
}
return serials, nil
}
// CheckCRL verifica a assinatura do CRL usando a chave pública da CA
func CheckCRL(crl *CRL, publicKey []byte) error {
// Verificar a assinatura usando o algoritmo adequado
switch strings.ToUpper(*alg) {
case "ML-DSA":
if err := VerifyBytes(publicKey, crl.Signature, crl.RawData); err != nil {
return fmt.Errorf("CRL signature verification failed using ML-DSA: %v", err)
}
case "SLH-DSA":
if err := VerifySLH(publicKey, crl.Signature, crl.RawData); err != nil {
return fmt.Errorf("CRL signature verification failed using SLH-DSA: %v", err)
}
case "BN256I":
if err := VerifyBN(publicKey, crl.Signature, crl.RawData, []byte(*salt)); err != nil {
return fmt.Errorf("CRL signature verification failed using BN256: %v", err)
}
case "BLS12381I":
if err := VerifyBLS(publicKey, crl.Signature, crl.RawData); err != nil {
return fmt.Errorf("CRL signature verification failed using BLS12381: %v", err)
}
default:
return fmt.Errorf("unsupported algorithm: %s", *alg)
}
return nil
}
// PrintCRLInfo displays the attributes of a Certificate Revocation List (CRL)
func PrintCRLInfo(crl *CRL) {
fmt.Printf("CRL:\n")
fmt.Printf(" Data:\n")
fmt.Printf(" Number : %s (%X)\n", crl.SerialNumber.String(), crl.SerialNumber)
fmt.Printf(" Last Update : %s\n", crl.NotBefore.Format(time.RFC3339))
fmt.Printf(" Next Update : %s\n", crl.NotAfter.Format(time.RFC3339))
fmt.Printf(" Issuer\n")
fmt.Printf(" %s\n", crl.Issuer)
fmt.Printf(" Authority Key ID : %x\n", crl.AuthorityKeyID)
fmt.Printf(" Signature Algorithm: %s\n", strings.ToUpper(*alg))
fmt.Printf(" Signature:\n")
// Verificar se o algoritmo é BLS12381
if strings.ToUpper(*alg) == "BLS12381I" {
// Exibe a assinatura inteira para BLS12381
splitz := SplitSubN(hex.EncodeToString(crl.Signature), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
} else {
// Para outros algoritmos, exibe apenas os primeiros 64 bytes da assinatura
splitz := SplitSubN(hex.EncodeToString(crl.Signature[:64]), 2)
for _, chunk := range split(strings.Trim(fmt.Sprint(splitz), "[]"), 45) {
fmt.Printf(" %-10s\n", strings.ReplaceAll(chunk, " ", ":"))
}
}
if strings.ToUpper(*alg) == "ML-DSA" || strings.ToUpper(*alg) == "SLH-DSA" {
fmt.Println(" [...]")
}
fmt.Printf(" Revoked Certificates:\n")
for _, revoked := range crl.RevokedCertificates {
fmt.Printf(" - Serial Number: %s\n", revoked.SerialNumber.String())
fmt.Printf(" Revocation Time: %s\n", revoked.RevocationTime.Format(time.RFC3339))
}
}
// ChangePrivateKeyPassword troca a senha da chave privada de assinatura ou criptografia
func ChangePrivateKeyPassword(keyFile, oldPassword, newPassword string) error {
// Ler o arquivo que contém a chave privada
fileContent, err := ioutil.ReadFile(keyFile)
if err != nil {
return fmt.Errorf("error reading private key file: %w", err)
}
// Decodificar o bloco PEM
block, _ := pem.Decode(fileContent)
if block == nil {
return fmt.Errorf("failed to decode PEM block")
}
var privKeyBytes []byte
if IsEncryptedPEMBlock(block) {
// Descriptografar a chave privada
privKeyBytes, err = DecryptPEMBlock(block, []byte(oldPassword))
if err != nil {
return fmt.Errorf("error decrypting private key: %w", err)
}
} else {
privKeyBytes = block.Bytes
}
// Criar um novo bloco PEM com a chave privada
newBlock := &pem.Block{
Type: block.Type,
Bytes: privKeyBytes,
}
// Salvar a chave privada com a nova senha, se fornecida
file, err := os.Create(keyFile)
if err != nil {
return fmt.Errorf("error creating private key file: %w", err)
}
defer file.Close()
if newPassword != "" {
// Salvar a chave privada criptografada com a nova senha
err = EncryptAndWriteBlock(*cph, newBlock, []byte(newPassword), file)
if err != nil {
return fmt.Errorf("error saving private key with new password: %w", err)
}
} else {
// Salvar a chave privada sem criptografia
if err := pem.Encode(file, newBlock); err != nil {
return fmt.Errorf("error encoding PEM block: %w", err)
}
}
return nil
}
// Função para mapear o ID de um usuário para um valor numérico
func hashToPoint(id string) *big.Int {
// Usando SHA256 para gerar um número a partir do ID
hash := bmw.Sum256([]byte(id))
hashInt := new(big.Int).SetBytes(hash[:])
// Retornar o valor inteiro correspondente ao hash
return hashInt
}
// Gerar a chave pública mestra a partir de uma chave mestra
func generateMasterPublicKey(masterKey *big.Int) *bn256i.G2 {
// Multiplicação escalar da chave mestra com o gerador da curva
publicKey := new(bn256i.G2)
publicKey.ScalarBaseMult(masterKey)
return publicKey
}
// Gerar a chave privada de um usuário com base na chave mestra e no ID
func generatePrivateKey(masterKey *big.Int, userID string) *big.Int {
// Gerar um valor a partir do ID
idInt := hashToPoint(userID)
// A chave privada do usuário é derivada pela multiplicação da chave mestra com o valor do ID
privateKey := new(big.Int)
privateKey.Mul(masterKey, idInt)
return privateKey
}
// Gerar a chave pública de um usuário com base na chave pública mestra e ID
func generatePublicKeyForUser(masterPublicKey *bn256i.G2, userID string) *bn256i.G2 {
// Gerar um valor a partir do ID
idInt := hashToPoint(userID)
// Multiplicar a chave pública mestra (G2) pelo valor do ID (big.Int)
// O resultado será um ponto de tipo G2
publicKey := new(bn256i.G2)
publicKey.ScalarMult(masterPublicKey, idInt)
return publicKey
}
// Função para assinar uma mensagem com a chave privada
func signMessageBN(privateKey *big.Int, message string) *bn256i.G1 {
// Calcular o hash da mensagem
hash := bn256i.HashG1([]byte(message), []byte(*salt))
// A assinatura é calculada como σ = sk ⋅ H(m)
signature := hash.ScalarMult(hash, privateKey)
return signature
}
// Função para verificar a assinatura utilizando a chave pública do usuário
func verifySignatureBN(userPublicKey *bn256i.G2, message string, signature *bn256i.G1) bool {
// Calcular o hash da mensagem
hash := bn256i.HashG1([]byte(message), []byte(*salt))
// Verify if the signature is valid using bilinear pairing
rhs := bn256i.Pair(hash, userPublicKey)
lhs := bn256i.Pair(signature, new(bn256i.G2).ScalarBaseMult(big.NewInt(1)))
// Compare the results of the pairings
return bytes.Equal(rhs.Marshal(), lhs.Marshal())
}
// Função para calcular a chave secreta compartilhada usando emparelhamento bilinear
func computeSharedSecret(privateKey *big.Int, publicKey *bn256i.G2) *big.Int {
// Definir um ponto base arbitrário em G1 (isso pode ser feito de acordo com a aplicação)
baseG1 := new(bn256i.G1).ScalarBaseMult(big.NewInt(1048576))
// Calcular o emparelhamento entre o ponto base e a chave pública do usuário
pairing := bn256i.Pair(baseG1, publicKey)
// Agora, multiplicar o emparelhamento pela chave privada do usuário
sharedKey := new(bn256i.GT)
sharedKey.ScalarMult(pairing, privateKey)
// Retornar a chave compartilhada como um valor numérico
sharedSecret := new(big.Int)
sharedSecret.SetBytes(sharedKey.Marshal())
return sharedSecret
}
// Função hashToScalar - Converte um ID para um valor escalar
func hashToScalar(ID string) *ff.Scalar {
// Usamos SHA-256 para criar um hash do ID
hash := bmw.Sum256([]byte(ID))
hashInt := new(big.Int).SetBytes(hash[:])
// Convertendo o valor inteiro para um Scalar
scalar := new(ff.Scalar)
scalar.SetBytes(hashInt.Bytes())
return scalar
}
// Função para gerar a chave privada de um usuário com base na chave mestra e ID
func generatePrivateKeyForUserBLS(masterKey *ff.Scalar, userID string) *ff.Scalar {
// Gerar um valor a partir do ID
userScalar := hashToScalar(userID)
// A chave privada do usuário agora é a multiplicação da chave mestra pelo valor escalar derivado do ID
privateKey := new(ff.Scalar)
privateKey.Mul(masterKey, userScalar)
return privateKey
}
// Função para gerar a chave pública de um usuário com base na chave pública mestra e ID
func generatePublicKeyForUserBLS(masterPublicKey *bls12381.G2, userID string) *bls12381.G2 {
// Gerar o valor escalar do ID
userScalar := hashToScalar(userID)
// A chave pública do usuário é a multiplicação da chave pública mestra pelo valor derivado do ID
publicKey := new(bls12381.G2)
publicKey.ScalarMult(userScalar, masterPublicKey)
return publicKey
}
// Função para gerar a chave pública de um usuário com base na chave pública mestra e ID
func generatePublicKeyForUserBLSG1(masterPublicKey *bls12381.G1, userID string) *bls12381.G1 {
// Gerar o valor escalar do ID
userScalar := hashToScalar(userID)
// A chave pública do usuário é a multiplicação da chave pública mestra pelo valor derivado do ID
publicKey := new(bls12381.G1)
publicKey.ScalarMult(userScalar, masterPublicKey)
return publicKey
}
// Função para assinar uma mensagem
func signMessageBLS(message []byte, privKey *ff.Scalar) *bls12381.G1 {
// Gerar um ponto a partir da mensagem
hashMessage := new(bls12381.G1)
hashMessage.Hash(message, nil)
// Multiplicar o ponto pela chave privada
signature := new(bls12381.G1)
signature.ScalarMult(privKey, hashMessage)
return signature
}
// Função para verificar a assinatura
func verifySignatureBLS(message []byte, signature *bls12381.G1, pubKey *bls12381.G2) bool {
// Gerar o ponto a partir da mensagem
hashMessage := new(bls12381.G1)
hashMessage.Hash(message, nil)
// Verificar se a assinatura é válida
e1 := bls12381.Pair(signature, bls12381.G2Generator())
e2 := bls12381.Pair(hashMessage, pubKey)
return e1.IsEqual(e2)
}
// Função para calcular a chave compartilhada entre duas partes usando o emparelhamento bilinear
func computeSharedSecretBLS(privateKey *ff.Scalar, publicKey *bls12381.G2) *bls12381.Gt {
// Emparelhamento: G1 x G2 -> Gt
basePointG1 := bls12381.G1Generator()
// Realiza o paring entre o ponto base G1 e a chave pública
pairingResult := bls12381.Pair(basePointG1, publicKey)
// Multiplicação do paring pelo escalar da chave privada
sharedKey := new(bls12381.Gt)
sharedKey.Exp(pairingResult, privateKey)
return sharedKey
}
// Função para agregar assinaturas
func aggregateSignatures(signatures []*bls12381.G1) *bls12381.G1 {
aggSig := new(bls12381.G1)
aggSig.SetIdentity()
// Soma todas as assinaturas (usando multiplicação de escalar interna, pois a adição de grupos não é implementada diretamente)
for _, sig := range signatures {
aggSig.Add(aggSig, sig)
}
return aggSig
}
// Ajuste na função verifyAggregateSignature
func verifyAggregateSignature(pubKeys [][]byte, msgs [][]byte, aggSig *bls12381.G1) bool {
// 1. Hash das mensagens e converte-as para G1
hashMessages := make([]*bls12381.G1, len(msgs))
for i, msg := range msgs {
// Cria um ponto G1 a partir do hash da mensagem
hashMessages[i] = new(bls12381.G1)
hashMessages[i].Hash(msg, nil)
}
// 2. Inicializa o pairing das mensagens e chaves públicas
var pubKeysG2 []*bls12381.G2
for _, pubKeyBytes := range pubKeys {
// Desserializa a chave pública de cada usuário (já passada como G2)
var pubKey bls12381.G2
pubKey.SetBytes(pubKeyBytes)
pubKeysG2 = append(pubKeysG2, &pubKey)
}
// 3. Verifica a assinatura agregada utilizando pairing
e1 := bls12381.Pair(aggSig, bls12381.G2Generator())
// 4. Inicializa o pairing das mensagens e chaves públicas
e2 := bls12381.Pair(hashMessages[0], pubKeysG2[0])
// 5. Multiplica o pairing das mensagens restantes com as chaves públicas correspondentes
for i := 1; i < len(msgs); i++ {
e2.Mul(e2, bls12381.Pair(hashMessages[i], pubKeysG2[i]))
}
// 6. Compara os dois pairings e verifica se a assinatura agregada é válida
return e1.IsEqual(e2)
}
// Gera um escalar aleatório seguro
func randomScalar() *ff.Scalar {
scalar := new(ff.Scalar)
buf := make([]byte, 32)
_, err := rand.Read(buf)
if err != nil {
log.Fatal("Error generating random number.")
}
scalar.SetBytes(buf)
return scalar
}
// Gera fator de cegamento aleatório
func generateBlindFactor() *ff.Scalar {
return randomScalar()
}
// Cegar a mensagem (multiplicar por um fator aleatório)
func blindMessage(originalG1 *bls12381.G1, blindFactor *ff.Scalar) *bls12381.G1 {
blindedMessage := new(bls12381.G1)
blindedMessage.ScalarMult(blindFactor, originalG1)
return blindedMessage
}
// Descega a mensagem cegada
func unblindMessage(blindedMessage *bls12381.G1, blindFactor *ff.Scalar) *bls12381.G1 {
inverseBlindFactor := new(ff.Scalar)
inverseBlindFactor.Inv(blindFactor)
originalMessage := new(bls12381.G1)
originalMessage.ScalarMult(inverseBlindFactor, blindedMessage)
return originalMessage
}
// Converte mensagem para um ponto na curva G1
func hashToG1(message []byte) *bls12381.G1 {
hashMessage := new(bls12381.G1)
hashMessage.Hash(message, nil)
return hashMessage
}
// Verifica assinatura agregada com as mensagens cegadas
func verifyAggregateSignatureVote(blindedMessages []*bls12381.G1, aggSignature *bls12381.G1, pubKeys []*bls12381.G2) bool {
hashMessages := make([]*bls12381.G1, len(blindedMessages))
for i, msg := range blindedMessages {
hashMessages[i] = new(bls12381.G1)
hashMessages[i].Hash(msg.Bytes(), nil)
}
e1 := bls12381.Pair(aggSignature, bls12381.G2Generator())
e2 := bls12381.Pair(hashMessages[0], pubKeys[0])
for i := 1; i < len(hashMessages); i++ {
e2.Mul(e2, bls12381.Pair(hashMessages[i], pubKeys[i]))
}
return e1.IsEqual(e2)
}
// Função para gerar um compromisso (commitment) com base na chave secreta
func generateCommitment(secret *ff.Scalar, generator *bls12381.G2) *bls12381.G2 {
commitment := new(bls12381.G2)
commitment.ScalarMult(secret, generator)
return commitment
}
// Função para gerar o desafio (challenge) a partir do compromisso e do hash da mensagem
func generateChallenge(commitment *bls12381.G2, message []byte) *ff.Scalar {
// Gerar o hash da mensagem concatenada com o compromisso
hash := bmw.New256()
hash.Write(commitment.Bytes())
hash.Write(message)
challenge := new(ff.Scalar)
challenge.SetBytes(hash.Sum(nil))
return challenge
}
// Função para gerar a resposta (response) à prova
func generateResponse(secret *ff.Scalar, challenge *ff.Scalar) *ff.Scalar {
response := new(ff.Scalar)
response.Mul(secret, challenge)
return response
}
/*
// Verificar prova ZKP
func verifyProof(commitment *bls12381.G2, challenge *ff.Scalar, response *ff.Scalar, publicKey *bls12381.G2) bool {
left := new(bls12381.G2)
left.ScalarMult(response, bls12381.G2Generator())
leftPair := bls12381.Pair(bls12381.G1Generator(), left)
right := new(bls12381.G2)
right.Add(commitment, new(bls12381.G2))
right.ScalarMult(challenge, publicKey)
rightPair := bls12381.Pair(bls12381.G1Generator(), right)
return leftPair.IsEqual(rightPair)
}
*/
// Verificar prova ZKP
func verifyProof(commitment *bls12381.G2, challenge *ff.Scalar, response *ff.Scalar, publicKey *bls12381.G2) bool {
left := new(bls12381.G1)
left.ScalarMult(response, bls12381.G1Generator())
leftPair := bls12381.Pair(left, bls12381.G2Generator())
right := new(bls12381.G2)
right.Add(commitment, new(bls12381.G2))
right.ScalarMult(challenge, publicKey)
rightPair := bls12381.Pair(bls12381.G1Generator(), right)
return leftPair.IsEqual(rightPair)
}
// Estrutura para armazenar votos codificados
type EncodedVotes struct {
Votes [][]byte
}
// Função para codificar um voto
func encodeVote(vote string, candidates []string) []*bls12381.G1 {
votes := make([]*bls12381.G1, len(candidates))
// Inicializa os votos como valores neutros
for i := range candidates {
votes[i] = new(bls12381.G1)
votes[i].SetIdentity()
}
// Define um único voto para o candidato escolhido
for i, candidate := range candidates {
if strings.EqualFold(vote, candidate) {
scalar := new(ff.Scalar)
scalar.SetUint64(1)
votes[i].ScalarMult(scalar, bls12381.G1Generator())
break
}
}
return votes
}
// Função para somar os votos
func addVotes(existingVotes [][]*bls12381.G1) []*bls12381.G1 {
numCandidates := len(existingVotes[0])
sums := make([]*bls12381.G1, numCandidates)
for i := 0; i < numCandidates; i++ {
sums[i] = new(bls12381.G1)
sums[i].SetIdentity()
}
for _, vote := range existingVotes {
for i := 0; i < numCandidates; i++ {
sums[i].Add(sums[i], vote[i])
}
}
return sums
}
// Codifica os votos em ASN.1
func encodeVotesToASN1(votes []*bls12381.G1) (string, error) {
encoded := EncodedVotes{Votes: make([][]byte, len(votes))}
for i, vote := range votes {
encoded.Votes[i] = vote.Bytes()
}
data, err := asn1.Marshal(encoded)
if err != nil {
return "", err
}
return fmt.Sprintf("%x", data), nil
}
// Decodifica os votos de ASN.1
func decodeVotesFromASN1(encodedStr string) (*EncodedVotes, error) {
encodedBytes := make([]byte, len(encodedStr)/2)
_, err := fmt.Sscanf(encodedStr, "%x", &encodedBytes)
if err != nil {
return nil, err
}
var decoded EncodedVotes
_, err = asn1.Unmarshal(encodedBytes, &decoded)
if err != nil {
return nil, err
}
return &decoded, nil
}
// Decodifica os votos e converte para contagem de votos
func decodeSum(sums []*bls12381.G1) []int {
basePair := bls12381.Pair(bls12381.G1Generator(), bls12381.G2Generator())
decode := func(sum *bls12381.G1) int {
pairSum := bls12381.Pair(sum, bls12381.G2Generator())
testSum := new(bls12381.Gt)
testSum.SetIdentity()
for i := 0; i < 1000000; i++ {
if testSum.IsEqual(pairSum) {
return i
}
testSum.Mul(testSum, basePair)
}
return 0
}
votes := make([]int, len(sums))
for i, sum := range sums {
votes[i] = decode(sum)
}
return votes
}
// Generates a random salt of the given size (16 bytes)
func generateSalt(size int) ([]byte, error) {
salt := make([]byte, size)
_, err := rand.Read(salt)
if err != nil {
return nil, err
}
return salt, nil
}
/*
// Derives the encryption key using Lyra2RE2
func deriveKey(password string, salt []byte) ([]byte, error) {
data := append([]byte(password), salt...)
hash, err := lyra2re2.Sum(data)
if err != nil {
return nil, err
}
return hash[:24], nil
}
*/
// Derives the encryption key using Lyra2RE2
func deriveKey(password string, salt []byte) ([]byte, error) {
data := append([]byte(password), salt...)
// for i := 0; i < 32768; i++ {
for i := 0; i < 65536; i++ {
// Derivar a chave utilizando Lyra2RE2
hash, err := lyra2re2.Sum(data)
if err != nil {
return nil, err
}
// Usar o hash como o dado para a próxima iteração
data = hash
}
return data[:24], nil
}
// Encrypts the symmetric key and embeds the salt in the ciphertext using Curupira
func encryptKey(plainKey []byte, password string) (string, error) {
// Generate a random salt (16 bytes)
salt := make([]byte, 16)
if _, err := rand.Read(salt); err != nil {
return "", err
}
// Derive key from password
encryptionKey, err := deriveKey(password, salt)
if err != nil {
return "", err
}
if len(encryptionKey) != 12 && len(encryptionKey) != 18 && len(encryptionKey) != 24 {
return "", errors.New("invalid key size for Curupira (must be 96, 144, or 192 bits)")
}
// Create Curupira cipher
cipher, err := curupira1.NewCipher(encryptionKey)
if err != nil {
return "", err
}
// Create LetterSoup AEAD mode
aead := curupira1.NewLetterSoup(cipher)
// Generate a nonce (12 bytes)
nonce := make([]byte, 12)
if _, err := rand.Read(nonce); err != nil {
return "", err
}
aead.SetIV(nonce)
// Encrypt the data
ciphertext := make([]byte, len(plainKey))
aead.Encrypt(ciphertext, plainKey)
// Generate authentication tag (12 bytes)
tag := aead.GetTag(nil, 96)
// Concatenate salt + nonce + tag + ciphertext
finalCiphertext := append(salt, nonce...)
finalCiphertext = append(finalCiphertext, tag...)
finalCiphertext = append(finalCiphertext, ciphertext...)
// Return base64 encoded string
return base64.StdEncoding.EncodeToString(finalCiphertext), nil
}
// Decrypts the symmetric key (extracts salt and decrypts using Curupira)
func decryptKey(encryptedKey string, password string) ([]byte, error) {
// Decode base64 string
data, err := base64.StdEncoding.DecodeString(encryptedKey)
if err != nil {
return nil, err
}
// Extract components
if len(data) < 40 {
return nil, errors.New("ciphertext too short")
}
salt := data[:16]
nonce := data[16:28]
tag := data[28:40]
ciphertext := data[40:]
// Derive key using extracted salt
encryptionKey, err := deriveKey(password, salt)
if err != nil {
return nil, err
}
if len(encryptionKey) != 12 && len(encryptionKey) != 18 && len(encryptionKey) != 24 {
return nil, errors.New("invalid key size for Curupira")
}
// Create Curupira cipher
cipher, err := curupira1.NewCipher(encryptionKey)
if err != nil {
return nil, err
}
// Create LetterSoup AEAD mode
aead := curupira1.NewLetterSoup(cipher)
aead.SetIV(nonce)
// Decrypt the data
decrypted := make([]byte, len(ciphertext))
aead.Decrypt(decrypted, ciphertext)
aead.Encrypt(ciphertext, decrypted)
tagEnc := aead.GetTag(nil, 96)
if !bytes.Equal(tag, tagEnc) {
return nil, errors.New("authentication verification failed")
}
return decrypted, nil
}
// PubPaths define um tipo para armazenar múltiplos caminhos de arquivos
type PubPaths []string
// Implementação do método String para a interface flag.Value
func (p *PubPaths) String() string {
return fmt.Sprintf("%v", *p)
}
// Implementação do método Set para a interface flag.Value
func (p *PubPaths) Set(value string) error {
*p = append(*p, value)
return nil
}
// MsgsPaths define um tipo para armazenar múltiplas mensagens
type MsgsPaths []string
// Implementação do método String para a interface flag.Value
func (m *MsgsPaths) String() string {
return fmt.Sprintf("%v", *m)
}
// Implementação do método Set para a interface flag.Value
func (m *MsgsPaths) Set(value string) error {
*m = append(*m, value)
return nil
}
// Estruturas ASN.1
type CiphertextPHP struct {
C1 *big.Int
C2 *big.Int
}
type Signature struct {
R *big.Int
S *big.Int
}
type PublicKeyASN1 struct {
P *big.Int
G *big.Int
Y *big.Int
}
type PrivateKeyASN1 struct {
P *big.Int
G *big.Int
X *big.Int
}
func encodePublicKeyASN1(pub *elgamalphp.PublicKey) ([]byte, error) {
return asn1.Marshal(PublicKeyASN1{P: pub.P, G: pub.G, Y: pub.Y})
}
func decodePublicKeyASN1(data []byte) (*elgamalphp.PublicKey, error) {
var pubASN1 PublicKeyASN1
_, err := asn1.Unmarshal(data, &pubASN1)
if err != nil {
return nil, err
}
return &elgamalphp.PublicKey{P: pubASN1.P, G: pubASN1.G, Y: pubASN1.Y}, nil
}
func encodePrivateKeyASN1(priv *elgamalphp.PrivateKey) ([]byte, error) {
return asn1.Marshal(PrivateKeyASN1{P: priv.P, G: priv.G, X: priv.X})
}
func decodePrivateKeyASN1(data []byte) (*elgamalphp.PrivateKey, error) {
var privASN1 PrivateKeyASN1
_, err := asn1.Unmarshal(data, &privASN1)
if err != nil {
return nil, err
}
return &elgamalphp.PrivateKey{P: privASN1.P, G: privASN1.G, X: privASN1.X}, nil
}
func savePEM(filename, blockType string, data []byte) error {
block := &pem.Block{
Type: blockType,
Bytes: data,
}
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
return pem.Encode(file, block)
}
func readPEM(filename string) ([]byte, error) {
file, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
block, _ := pem.Decode(file)
if block == nil {
return nil, fmt.Errorf("failed to parse PEM block")
}
return block.Bytes, nil
}
func hashMessage(message []byte) []byte {
h := whirlpool.New()
h.Write(message)
return h.Sum(nil)
}
func isHexDump(input string) bool {
if strings.Contains(input, "|") {
return false
} else {
return true
}
}
func decodeHexDump(input string) ([]byte, error) {
var decoded []byte
var buffer bytes.Buffer
lines := strings.Split(input, "\n")
for _, line := range lines {
if len(line) < 59 {
continue
}
hexCharsInLine := line[9:58]
hexCharsInLine = strings.ReplaceAll(hexCharsInLine, " ", "")
buffer.WriteString(hexCharsInLine)
}
decoded, err := hex.DecodeString(buffer.String())
if err != nil {
return nil, err
}
return decoded, nil
}
func zeroByteSlice() []byte {
return []byte{
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment