package main import ( "crypto" "crypto/aes" "crypto/cipher" "crypto/ed25519" "encoding/hex" "fmt" "github.com/dchest/bcrypt_pbkdf" ) /* Same key as private.ed25519 example. */ func main() { const ( passphrase string = "test" rounds int = 100 keySize int = 32 lenPlain int = 160 ) var salt []byte var bcryptKey []byte var sk []byte var pk []byte var pubkey crypto.PublicKey var key ed25519.PrivateKey var decrypted []byte var aesCtx cipher.Block var encData []byte decrypted = make([]byte, lenPlain) encData = make([]byte, lenPlain) // Import salt if s, err := hex.DecodeString("50132f72900d68e0a31f9d75b6f0a5bc"); err != nil { fmt.Println(err) return } else { salt = s } // Import encrypted data if b, err := hex.DecodeString( "c49777cd0d1a7d37db77a1814991278f8ce99d572e2c666b93b99867425c60da" + "4652fddb8555098532b51beeee2959f9db5cf5a0905052720c5de25f2c4dd87e" + "bcc7bb5ea3d7bcbeacc6b732e4c39295d9991a97ef3f0838f8a9bfd43edb3403" + "189649088f6cfb78946fb914e358ac6abc64691072f5f2788534d9d42d7f406b" + "c5090b30df23cb7dd8c5cb938e41facd6e38e8845b8160bff840598118d447c2", ); err != nil { fmt.Println(err) return } else { encData = b } // ED25519 keys // This is used to validate decrypted keys. if edk, err := hex.DecodeString( "ce6e2b8d638c9d5219dff455af1a90d0a5b72694cfcedfb93bc1e1b1816dee98" + "bfa2031aa5463113e40e16896af503c5299ead76b09cb63846f41cc4de1740f6", ); err != nil { fmt.Println(err) return } else { key = edk // .Public() returns a crypto.PublicKey, which... is an interface that seemingly cannot be type asserted to anything. pubkey = key.Public() } sep := len(key) - ed25519.PublicKeySize pk = key[sep:] sk = key[0:sep] // Bcrypt_pbkdf2 derivation (used for deriving decryption key for AES encrypted private key) // if k, err := bcrypt_pbkdf.Key([]byte(passphrase), salt, rounds, keySize); err != nil { if k, err := bcrypt_pbkdf.Key([]byte(passphrase), salt, rounds, keySize+len(salt)); err != nil { fmt.Println(err) return } else { bcryptKey = k } realBcryptKey := bcryptKey[0:sep] realIV := bcryptKey[sep:] // Decrypter if a, err := aes.NewCipher(realBcryptKey); err != nil { fmt.Println(err) return } else { aesCtx = a } // Actual cipher setup. AES256-CBC // d := cipher.NewCBCDecrypter(aesCtx, realIV) // d.CryptBlocks(decrypted, encData) // Actual cipher setup. AES256-CTR d := cipher.NewCTR(aesCtx, realIV) d.XORKeyStream(decrypted, encData) /* if p, s, err := ed25519.GenerateKey(nil); err != nil { fmt.Println(err) return } else { pubkey = p key = s pk = key[(len(key) - ed25519.PublicKeySize):] sk = key[0:(len(key) - ed25519.PublicKeySize)] } */ fmt.Printf("ED25519 key: %v\n", hex.EncodeToString(key)) fmt.Printf("Pubkey: %v\n", pubkey) fmt.Printf("SK: %v\n", hex.EncodeToString(sk)) fmt.Printf("PK: %v\n", hex.EncodeToString(pk)) fmt.Printf("Salt: %v\n", hex.EncodeToString(salt)) fmt.Printf("Bcrypt Key: %v\n", hex.EncodeToString(bcryptKey)) fmt.Printf("realBcryptKey: %v\n", hex.EncodeToString(realBcryptKey)) fmt.Printf("realIV: %v\n", hex.EncodeToString(realIV)) // fmt.Printf("Encrypted data: %v\n", hex.EncodeToString(encData)) fmt.Printf("Decrypted data?: %v\n", hex.EncodeToString(decrypted)) }