This package ties several other commonly used cryptography packages together. The goal is to make common cryptographic operations simple. The following elliptic curves are supported:
This package was originally the part of https://github.com/regnull/ubikom, but then became its own little package, because why not.
(see examples_test.go and encryption_test.go files).
Elliptic curves are defined as constants:
const (
SECP256K1 EllipticCurve = 1
P256 EllipticCurve = 2
P384 EllipticCurve = 3
P521 EllipticCurve = 4
)
Use them when creating keys.
Sign hash and verify signature (Using ECDSA)
privateKey := CreatePrivateKey(P256, big.NewInt(12345))
data := "super secret message"
hash := Hash256([]byte(data))
signature, err := privateKey.Sign(hash)
if err != nil {
log.Fatal(err)
}
publicKey := privateKey.PublicKey()
success := signature.Verify(publicKey, hash)
fmt.Printf("Signature verified: %v\n", success)
// Output: Signature verified: true
Encrypt with shared secret (Using ECDH):
aliceKey, err := GeneratePrivateKey(P256)
if err != nil {
log.Fatal(err)
}
bobKey, err := GeneratePrivateKey(P256)
if err != nil {
log.Fatal(err)
}
data := "super secret message"
encrypted, err := aliceKey.EncryptECDH([]byte(data), bobKey.PublicKey())
if err != nil {
log.Fatal(err)
}
decrypted, err := bobKey.DecryptECDH(encrypted, aliceKey.PublicKey())
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", string(decrypted))
// Output: super secret message
privateKey := CreatePrivateKey(P256, big.NewInt(12345))
encryptedKey, err := privateKey.EncryptKeyWithPassphrase("my passphrase")
if err != nil {
log.Fatal(err)
}
decryptedKey, err := CreatePrivateKeyFromEncrypted(P256, encryptedKey, "my passphrase")
fmt.Printf("%d\n", decryptedKey.Secret())
// Output: 12345
privateKey := CreatePrivateKey(P256, big.NewInt(12345))
publicKey := privateKey.PublicKey()
serializedCompressed := publicKey.SerializeCompressed()
fmt.Printf("%x\n", serializedCompressed)
publicKeyCopy, err := DeserializeCompressed(P256, serializedCompressed)
if err != nil {
log.Fatal(err)
}
sameKey := publicKey.Equal(publicKeyCopy)
fmt.Printf("the correct key was created: %v\n", sameKey)
// Output: 0226efcebd0ee9e34a669187e18b3a9122b2f733945b649cc9f9f921e9f9dad812
// the correct key was created: true
// BitcoinAddress and EthereumAddress only work for secp256k1 curve.
privateKey := CreatePrivateKey(SECP256K1, big.NewInt(12345))
publicKey := privateKey.PublicKey()
bitcoinAddress, err := publicKey.BitcoinAddress()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Bitcoin address: %s\n", bitcoinAddress)
ethereumAddress, err := publicKey.EthereumAddress()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Ethereum address: %s\n", ethereumAddress)
// Output: Bitcoin address: 12vieiAHxBe4qCUrwvfb2kRkDuc8kQ2VZ2
// Ethereum address: 0xEB4665750b1382DF4AeBF49E04B429AAAc4d9929
EasyECC offers some limited JWK support (see https://www.rfc-editor.org/rfc/rfc7517). Private keys can be exported and imported as JWK JSON:
privateKey := CreatePrivateKey(P256, big.NewInt(12345))
jwkBytes, err := privateKey.MarshalToJWK()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", jwkBytes)
privateKeyCopy, err := CreatePrivateKeyFromJWK(jwkBytes)
if err != nil {
log.Fatal(err)
}
if privateKey.Equal(privateKeyCopy) {
fmt.Printf("keys match!")
}
// Output: {
// "kty": "EC",
// "crv": "P-256",
// "x": "Ju/OvQ7p40pmkYfhizqRIrL3M5RbZJzJ+fkh6fna2BI",
// "y": "kCOL3pzHuzMNFQxncE3SWucFUgV0S28xv0BwdFhy0OY",
// "d": "MDk"
// }
// keys match!