---
title: "GenerateAsymmetricKeyPair"
language: "en"
type: "Symbol"
summary: "GenerateAsymmetricKeyPair[] randomly generates a PrivateKey and corresponding PublicKey object for use with public-key cryptographic functions. GenerateAsymmetricKeyPair[type] randomly generates private and public keys of the specified type. GenerateAsymmetricKeyPair[opts] randomly generates keys using the specified options."
keywords: 
- public key
- private key
- cryptography
- digital signature
- cryptocurrency
- cryptocurrencies
- blockchain
- bitcoin
- btc
- ethereum
- eth
- elliptic curve
- elliptic curves
- secp256k1
- RSA
canonical_url: "https://reference.wolfram.com/language/ref/GenerateAsymmetricKeyPair.html"
source: "Wolfram Language Documentation"
related_guides: 
  - 
    title: "Cryptographic Number Theory"
    link: "https://reference.wolfram.com/language/guide/CryptographicNumberTheory.en.md"
  - 
    title: "Working with Tezos Blockchains"
    link: "https://reference.wolfram.com/language/guide/Blockchain-Tezos.en.md"
  - 
    title: "Working with Ethereum Blockchains"
    link: "https://reference.wolfram.com/language/guide/Blockchain-Ethereum.en.md"
  - 
    title: "Working with Cardano Blockchains"
    link: "https://reference.wolfram.com/language/guide/Blockchain-Cardano.en.md"
  - 
    title: "Working with bloxberg Blockchain"
    link: "https://reference.wolfram.com/language/guide/Blockchain-bloxberg.en.md"
  - 
    title: "Working with Bitcoin Blockchains"
    link: "https://reference.wolfram.com/language/guide/Blockchain-Bitcoin.en.md"
  - 
    title: "Working with ARK Blockchains"
    link: "https://reference.wolfram.com/language/guide/Blockchain-ARK.en.md"
  - 
    title: "Working with Blockchains"
    link: "https://reference.wolfram.com/language/guide/Blockchain.en.md"
  - 
    title: "Cryptography"
    link: "https://reference.wolfram.com/language/guide/Cryptography.en.md"
related_workflows: 
  - 
    title: "Create a Pay-to-Public-Key-Hash Bitcoin Address"
    link: "https://reference.wolfram.com/language/workflow/CreateAPayToPublicKeyHashBitcoinAddress.en.md"
  - 
    title: "Create and Verify a Cryptographic Digital Signature"
    link: "https://reference.wolfram.com/language/workflow/CreateAndVerifyACryptographicDigitalSignature.en.md"
related_functions: 
  - 
    title: "PrivateKey"
    link: "https://reference.wolfram.com/language/ref/PrivateKey.en.md"
  - 
    title: "PublicKey"
    link: "https://reference.wolfram.com/language/ref/PublicKey.en.md"
  - 
    title: "$CryptographicEllipticCurveNames"
    link: "https://reference.wolfram.com/language/ref/$CryptographicEllipticCurveNames.en.md"
  - 
    title: "Encrypt"
    link: "https://reference.wolfram.com/language/ref/Encrypt.en.md"
  - 
    title: "Decrypt"
    link: "https://reference.wolfram.com/language/ref/Decrypt.en.md"
  - 
    title: "GenerateDigitalSignature"
    link: "https://reference.wolfram.com/language/ref/GenerateDigitalSignature.en.md"
  - 
    title: "VerifyDigitalSignature"
    link: "https://reference.wolfram.com/language/ref/VerifyDigitalSignature.en.md"
  - 
    title: "DigitalSignature"
    link: "https://reference.wolfram.com/language/ref/DigitalSignature.en.md"
  - 
    title: "RandomPrime"
    link: "https://reference.wolfram.com/language/ref/RandomPrime.en.md"
  - 
    title: "PowerMod"
    link: "https://reference.wolfram.com/language/ref/PowerMod.en.md"
---
# GenerateAsymmetricKeyPair

GenerateAsymmetricKeyPair[] randomly generates a PrivateKey and corresponding PublicKey object for use with public-key cryptographic functions.

GenerateAsymmetricKeyPair[type] randomly generates private and public keys of the specified type.

GenerateAsymmetricKeyPair[opts] randomly generates keys using the specified options.

## Details and Options

* ``GenerateAsymmetricKeyPair`` returns an association of the form ``<|"PrivateKey" -> …, "PublicKey" -> …|>``.

* ``GenerateAsymmetricKeyPair[]`` by default uses the ``"RSA"`` type, with a system-specific, high-entropy randomness source.

* In ``GenerateAsymmetricKeyPair[type]``, the following types can be specified:

|                       |                               |
| --------------------- | ----------------------------- |
| "RSA"                 | RSA with default parameters   |
| "EllipticCurve"       | elliptic curve secp256k1      |
| "EdwardsCurve"        | twisted Edwards curve ed25519 |
| "Bitcoin", "Ethereum" | keys suitable for blockchains |
| Method -> "curve"      | named elliptic curve          |

* ``GenerateAsymmetricKeyPair`` has the following option:

Method	[`Automatic`](https://reference.wolfram.com/language/ref/Automatic.en.md)	details of key generation method

* With the setting ``Method -> assoc``, the association ``assoc`` gives details of the key generation method to use.

* The following element should be included in the association:

"Type"	"RSA"	type of keys to produce

* Possible settings for ``"Type"`` are ``"RSA"`` , ``"EllipticCurve"`` and ``"EdwardsCurve"``.

* For ``"RSA"``, the following elements can be given in the association:

|                  |       |                            |
| ---------------- | ----- | -------------------------- |
| "KeySize"        | 2048  | target size of key in bits |
| "PublicExponent" | 65537 | public exponent            |

* For ``"EllipticCurve"``, the following elements can be given in the association:

|              |             |                                              |
| ------------ | ----------- | -------------------------------------------- |
| "CurveName"  | "secp256k1" | elliptic curve to use                        |
| "Compressed" | False       | whether the public key is in compressed form |

* For ``"EdwardsCurve"``, the following elements can be given in the association:

"CurveName"	"ed25519"	twisted Edwards curve to use

* Possible settings for ``"CurveName"`` and ``Method -> curve`` are listed in ``\$CryptographicEllipticCurveNames``.

* ``"Bitcoin"`` uses ``"CurveName" -> "secp256k1"`` and ``"Compressed" -> True``.

* ``"Ethereum"`` uses ``"CurveName" -> "secp256k1"`` and ``"Compressed" -> False``.

---

## Examples (19)

### Basic Examples (3)

Generate corresponding public and private keys:

```wl
In[1]:= keys = GenerateAsymmetricKeyPair[]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "RSA", "Cipher" -> "RSA", "Padding" -> "PKCS1", 
  "PublicExponent" -> 65537, "PublicModulus" -> 273339263686207521797215877188286888361180222571923\
80086553422658280766996774604400674914942370696 ... 2, 15, 89, 255, 148, 174, 6, 196, 216, 219, 154, 20, 
     115, 74, 194, 101, 84, 67, 19, 223, 29, 38, 178, 100, 192, 238, 143, 18, 136, 107, 215, 139, 
     97, 180, 241, 120, 255, 124, 13, 175, 215, 141, 34, 62, 186, 194, 26, 102, 230, 227}]]]|>
```

Encrypt using the public key:

```wl
In[2]:= Encrypt[keys["PublicKey"], "Now is the time..."]

Out[2]=
EncryptedObject[Association["Data" -> ByteArray[{55, 220, 27, 41, 33, 56, 118, 175, 42, 98, 153, 
     172, 243, 238, 196, 43, 207, 123, 51, 144, 170, 71, 60, 50, 188, 10, 14, 46, 142, 235, 240, 
     20, 51, 221, 101, 125, 218, 210, 27, 84, 89, 24 ...  231, 238, 189, 4, 165, 213, 10, 195, 220, 205, 115, 96, 74, 188, 0, 164, 178, 144, 
     128, 205, 1, 186, 165, 197, 48, 112, 192, 43, 222, 58, 216, 154, 128, 205, 201, 223, 64, 89, 
     62, 11}], "OriginalForm" -> String, "Padding" -> "PKCS1"]]
```

Decrypt with the private key:

```wl
In[3]:= Decrypt[keys["PrivateKey"], %]

Out[3]= "Now is the time..."
```

Alternatively, encrypt with the private key:

```wl
In[4]:= Encrypt[keys["PrivateKey"], "Now is the time..."]

Out[4]=
EncryptedObject[Association["Data" -> ByteArray[{170, 118, 175, 11, 172, 111, 70, 17, 80, 37, 54, 
     153, 188, 192, 95, 160, 145, 128, 105, 45, 22, 57, 153, 128, 70, 253, 80, 196, 128, 104, 109, 
     250, 172, 173, 77, 6, 29, 195, 83, 176, 173, ...  193, 50, 156, 174, 155, 218, 247, 189, 10, 104, 198, 118, 165, 190, 250, 96, 44, 134, 
     239, 97, 7, 76, 216, 122, 230, 161, 30, 104, 101, 46, 172, 23, 159, 217, 56, 129, 96, 5, 153, 
     62}], "OriginalForm" -> String, "Padding" -> "PKCS1"]]
```

Decrypt with the public key:

```wl
In[5]:= Decrypt[keys["PublicKey"], %]

Out[5]= "Now is the time..."
```

---

Generate an elliptic curve key pair using the default curve secp256k1:

```wl
In[1]:= GenerateAsymmetricKeyPair["EllipticCurve"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "PublicCurvePoint" -> 
   {39350288644175514720820276072106024069193657798995890560018398946143116372136, 
    39908725346416568754686314633841620316 ... 
     247, 23, 145, 119, 5, 40, 131, 157, 109, 202}], "PublicCurvePoint" -> 
   {39350288644175514720820276072106024069193657798995890560018398946143116372136, 
    39908725346416568754686314633841620316484023595349327415278551935196940037578}]]|>
```

---

Generate a twisted Edwards elliptic curve key pair using the default curve ed25519:

```wl
In[1]:= GenerateAsymmetricKeyPair["EdwardsCurve"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EdwardsCurve", "CurveName" -> "ed25519", 
  "PrivateByteArray" -> ByteArray[{245, 1, 192, 206, 213, 92, 173, 223, 43, 66, 174, 211, 28, 129, 
     238, 61, 124, 201, 55, 101, 239, 20, 146, 53, 4,  ... 254, 109, 70, 186, 65, 233, 47, 91, 8, 202, 127}], 
  "PublicCurvePoint" -> 
   {17216240540148481388084949456829444332111543318000613116429421151964914298858, 
    57800692549531619962333393052049857051802463408860100879803372700499313331922}]]|>
```

### Scope (6)

#### Default Method (1)

Generate a key pair without arguments, using RSA as the default method:

```wl
In[1]:= GenerateAsymmetricKeyPair[]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "RSA", "Cipher" -> "RSA", "Padding" -> "PKCS1", 
  "PublicExponent" -> 65537, "PublicModulus" -> 247911987501885044697982433069414290416512318562006\
50514063379072441104431699579665475738583815360 ... 4, 103, 247, 247, 230, 182, 254, 99, 183, 0, 16, 29, 211, 82, 
     207, 42, 251, 99, 69, 125, 77, 59, 196, 235, 165, 173, 37, 29, 41, 41, 188, 13, 188, 81, 233, 
     87, 215, 204, 54, 118, 57, 251, 82, 161, 222, 106, 48, 114, 107, 105, 159}]]]|>
```

#### Named Methods (4)

Generate an RSA key pair:

```wl
In[1]:= GenerateAsymmetricKeyPair["RSA"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "RSA", "Cipher" -> "RSA", "Padding" -> "PKCS1", 
  "PublicExponent" -> 65537, "PublicModulus" -> 299947337124241049078187962861234320770754467769544\
13668007374339511545159925927595885422338001831 ... 81, 100, 200, 80, 242, 232, 141, 230, 
     177, 117, 151, 229, 218, 37, 73, 125, 100, 242, 43, 214, 107, 165, 225, 1, 102, 45, 161, 24, 
     182, 250, 215, 61, 227, 228, 132, 171, 151, 88, 229, 97, 210, 111, 121, 38, 149, 46, 80, 
     107}]]]|>
```

---

Generate an elliptic curve key pair using the default curve secp256k1:

```wl
In[1]:= GenerateAsymmetricKeyPair["EllipticCurve"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "PublicCurvePoint" -> 
   {44099192373323475949873530683473124541874672301506817329957388702503910270118, 
    11549412258952730136888574068745690489 ... 
     172, 244, 66, 157, 63, 222, 53, 41, 12, 142}], "PublicCurvePoint" -> 
   {44099192373323475949873530683473124541874672301506817329957388702503910270118, 
    115494122589527301368885740687456904893576070714709757329397571464616135429262}]]|>
```

---

Generate a twisted Edwards elliptic curve key pair using the default curve ed25519:

```wl
In[1]:= GenerateAsymmetricKeyPair["EdwardsCurve"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EdwardsCurve", "CurveName" -> "ed25519", 
  "PrivateByteArray" -> ByteArray[{225, 123, 153, 101, 173, 168, 177, 79, 171, 88, 10, 129, 37, 95, 
     104, 116, 33, 232, 197, 148, 102, 85, 167, 135,  ... , 173, 234, 150, 18, 53, 17, 248, 102, 253, 180}], 
  "PublicCurvePoint" -> 
   {15761060119519429132499210482380886528315908023630280563660113428504706537933, 
    23967991099725071287616740406535346556397681394793745578605888605002022493363}]]|>
```

---

Generate key pairs compatible with cryptocurrency networks:

```wl
In[1]:= GenerateAsymmetricKeyPair["Bitcoin"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "PublicCurvePoint" -> 
   {5943989807633066675583977433731030581821397650725907518857720028262432134489, 
    796227414656234756700495612856685537765 ...  157, 202, 161, 132, 67, 208, 46, 147, 6, 85, 89}], 
  "PublicCurvePoint" -> 
   {5943989807633066675583977433731030581821397650725907518857720028262432134489, 
    79622741465623475670049561285668553776599225683492938406717460234854469698023}]]|>

In[2]:= GenerateAsymmetricKeyPair["Ethereum"]

Out[2]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "PublicCurvePoint" -> 
   {80080591955162376456465395999483337298527212189239156800892241413482208010080, 
    49738334790728861123351011523020867443 ...  18, 136, 87, 132, 196, 210, 199, 208, 181, 163}], 
  "PublicCurvePoint" -> 
   {80080591955162376456465395999483337298527212189239156800892241413482208010080, 
    49738334790728861123351011523020867443259577777103568195102065510623757776291}]]|>
```

#### Particular Settings (1)

Provide an association with particular settings in the ``Method`` option:

```wl
In[1]:= GenerateAsymmetricKeyPair[Method -> <|"Type" -> "EllipticCurve", "CurveName" -> "secp521r1", "Compressed" -> False|>]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp521r1", 
  "PublicCurvePoint" -> {33803151295503818482786960182169229018735465983797410490616367900277572645\
65144193806534988102673970145285995833206964255604 ... 4193806534988102673970145285995833206964255604645808973809699411841736316170641, 67023964104975\
217673607386473642723519180402730614346391971321466523796136829478934948202800093862797636586812656\
89235981116639186933623614169477075887186362}]]|>

In[2]:= GenerateAsymmetricKeyPair[Method -> <|"Type" -> "EdwardsCurve", "CurveName" -> "ed448"|>]

Out[2]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EdwardsCurve", "CurveName" -> "ed448", 
  "PrivateByteArray" -> ByteArray[{217, 145, 43, 156, 218, 212, 68, 237, 1, 195, 144, 94, 74, 203, 
     20, 49, 188, 44, 59, 139, 22, 181, 150, 39, 135, 14 ... 04797508141943035076872473597194742925\
2348875112195286705593333798934292325079590077078888747257294, 380898785915386211098170455081338151\
918739706409911070436895547542904033657215574471365471965818872972904805065491208213137217476403214}\
]]|>
```

### Options (6)

#### Method (6)

Generate a key pair with a 4096-bit key:

```wl
In[1]:= GenerateAsymmetricKeyPair[Method -> <|"Type" -> "RSA", "KeySize" -> 4096|>]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "RSA", "Cipher" -> "RSA", "Padding" -> "PKCS1", 
  "PublicExponent" -> 65537, "PublicModulus" -> 887948302907507661625950748343920137461870231920723\
21032560973577743967692126847345947428980083626 ... 3999978076715451265925499575025163251044045058296616321221965124419015335291667551914259\
562781246497419024437247491134398059549542186951078861220416130477001046075368516925094567093, 
  "PublicByteArray" -> ByteArray[CompressedData["«769»"]]]]|>
```

---

Generate a key pair with a public exponent of 17:

```wl
In[1]:= GenerateAsymmetricKeyPair[Method -> <|"Type" -> "RSA", "PublicExponent" -> 17|>]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "RSA", "Cipher" -> "RSA", "Padding" -> "PKCS1", 
  "PublicExponent" -> 17, "PublicModulus" -> 231662525480029797118858642997581426552147574127755302\
05047073383882974150330162574064373800152350206 ... , 54, 20, 161, 119, 203, 253, 10, 78, 198, 73, 229, 78, 98, 217, 50, 
     193, 228, 149, 208, 94, 128, 200, 36, 90, 57, 44, 25, 198, 29, 78, 51, 4, 187, 90, 104, 94, 
     109, 60, 21, 34, 218, 119, 211, 53, 214, 200, 134, 221, 75, 181, 133}]]]|>
```

---

Generate a Bitcoin key pair with a compressed public key:

```wl
In[1]:= GenerateAsymmetricKeyPair[Method -> <|"Type" -> "EllipticCurve", "CurveName" -> "Bitcoin", "Compressed" -> True|>]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "PublicCurvePoint" -> 
   {102847475793894749073301463625865744574278780503639572574267899190954292019551, 
    1104526335509284565711873235987755915 ... , 11, 144, 30, 140, 131, 135, 251, 222, 1, 95}], 
  "PublicCurvePoint" -> 
   {102847475793894749073301463625865744574278780503639572574267899190954292019551, 
    110452633550928456571187323598775591574843200995478632823917034303405349092025}]]|>
```

---

Generate an Ethereum key pair with an uncompressed public key:

```wl
In[1]:= GenerateAsymmetricKeyPair[Method -> <|"Type" -> "EllipticCurve", "CurveName" -> "Ethereum", "Compressed" -> False|>]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "PublicCurvePoint" -> 
   {14203167609253728986945286505061296282669875121019549580435707918308574417198, 
    65382138412116710013876005393560191424 ... 2, 108, 193, 145, 126, 8, 205, 50, 189, 251, 68}], 
  "PublicCurvePoint" -> 
   {14203167609253728986945286505061296282669875121019549580435707918308574417198, 
    65382138412116710013876005393560191424201743224894830954290462344887601593156}]]|>
```

---

Generate a twisted Edwards curve–based key specifying a particular curve name:

```wl
In[1]:= GenerateAsymmetricKeyPair[Method -> <|"Type" -> "EdwardsCurve", "CurveName" -> "ed448"|>]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EdwardsCurve", "CurveName" -> "ed448", 
  "PrivateByteArray" -> ByteArray[{217, 145, 43, 156, 218, 212, 68, 237, 1, 195, 144, 94, 74, 203, 
     20, 49, 188, 44, 59, 139, 22, 181, 150, 39, 135, 14 ... 04797508141943035076872473597194742925\
2348875112195286705593333798934292325079590077078888747257294, 380898785915386211098170455081338151\
918739706409911070436895547542904033657215574471365471965818872972904805065491208213137217476403214}\
]]|>
```

---

Generate an elliptic curve–based key pair using a curve name as method:

```wl
In[1]:= GenerateAsymmetricKeyPair[Method -> "prime192v1"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "prime192v1", 
  "PublicCurvePoint" -> {431279845909111419396757173399107793331002972525471130997, 
    673825471087636165434715299863460964729857422683627714534}, 
 ... 156, 65, 161, 168, 224, 112, 75, 230, 248, 4, 143, 55, 34, 110, 183, 139, 114, 65, 247, 230}], 
  "PublicCurvePoint" -> {431279845909111419396757173399107793331002972525471130997, 
    673825471087636165434715299863460964729857422683627714534}]]|>

In[2]:= GenerateAsymmetricKeyPair[Method -> "ed448"]

Out[2]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EdwardsCurve", "CurveName" -> "ed448", 
  "PrivateByteArray" -> ByteArray[{222, 247, 222, 118, 107, 189, 120, 72, 214, 119, 159, 19, 30, 
     240, 123, 247, 253, 230, 237, 179, 29, 100, 54, 32, 2 ... 1775220278917098003495044017\
73919593094656540446832588458276632870032328089148071922342419068779849, 60674662964078090565575315\
146321405708603169449962387793216133720474893312335006569095906447006357353084622364779253500950115\
0224534813}]]|>
```

### Applications (2)

Generate a personal pair of elliptic curve–based keys to sign and verify a message using the Elliptic Curve Digital Signature Algorithm:

```wl
In[1]:= keys = GenerateAsymmetricKeyPair["EllipticCurve"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "PublicCurvePoint" -> 
   {20637682249279934256376015649159292936419928263528656271958163324816321344696, 
    83702419953714529660229432264605685890 ... , 197, 
     74, 135, 69, 217, 24, 26, 14, 15, 151}], "PublicCurvePoint" -> 
   {20637682249279934256376015649159292936419928263528656271958163324816321344696, 
    83702419953714529660229432264605685890388321605984863266773451893187004993431}]]|>
```

Generate a digital signature using your private key:

```wl
In[2]:= message = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";

In[3]:= signature = GenerateDigitalSignature[message, keys["PrivateKey"]]

Out[3]=
DigitalSignature[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "SignatureType" -> "NonDeterministic", "HashingMethod" -> "SHA256", 
  "R" -> ByteArray[{15, 189, 37, 206, 115, 232, 83, 235, 96, 135, 234, 170, 34, 168, 27, 98, ... 174, 118, 96, 204, 212, 76, 34, 63, 75, 95, 164, 73, 70, 53, 174}], 
  "S" -> ByteArray[{91, 158, 131, 90, 133, 228, 92, 9, 146, 250, 129, 208, 97, 75, 238, 152, 169, 
     176, 53, 138, 113, 201, 131, 244, 102, 198, 120, 12, 167, 165, 175, 40}]]]
```

Verify a digital signature using your public key:

```wl
In[4]:= VerifyDigitalSignature[{message, signature}, keys["PublicKey"]]

Out[4]= True
```

---

Write simple RSA-based signing and verification functions:

```wl
In[1]:= sign[key_PrivateKey, expr_] := Encrypt[key, Hash[expr, "SHA256"]]

In[2]:= verify[key_PublicKey, expr_, signature_EncryptedObject] := Decrypt[key, signature] === Hash[expr, "SHA256"]
```

Generate a pair of public and private RSA keys:

```wl
In[3]:= keys = GenerateAsymmetricKeyPair[]

Out[3]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "RSA", "Cipher" -> "RSA", "Padding" -> "PKCS1", 
  "PublicExponent" -> 65537, "PublicModulus" -> 259968294542309956304212130852512259185604520610428\
23885285616230336521880508592698064323675777262 ... 8, 15, 147, 161, 127, 33, 88, 190, 72, 107, 181, 
     84, 233, 109, 135, 160, 59, 178, 16, 229, 227, 16, 24, 231, 208, 192, 122, 176, 217, 214, 205, 
     34, 249, 14, 137, 209, 228, 202, 129, 185, 213, 212, 173, 161, 167, 173, 50, 160, 245}]]]|>
```

Define an expression to sign:

```wl
In[4]:= expr = Graphics[Disk[]]

Out[4]= [image]
```

Generate a signature:

```wl
In[5]:= sig = sign[keys["PrivateKey"], expr]

Out[5]=
EncryptedObject[Association["Data" -> ByteArray[{111, 187, 47, 127, 170, 152, 242, 96, 92, 162, 
     137, 230, 106, 192, 104, 54, 130, 80, 208, 72, 202, 162, 70, 94, 220, 186, 55, 158, 63, 26, 
     191, 215, 186, 214, 210, 153, 5, 104, 109, 187,  ...  101, 98, 39, 146, 241, 157, 159, 185, 157, 48, 88, 220, 253, 122, 238, 183, 130, 
     169, 32, 199, 40, 177, 2, 100, 155, 220, 122, 50, 19, 68, 31, 95, 136, 107, 182, 67, 170, 23, 
     120}], "OriginalForm" -> Expression, "Padding" -> "PKCS1"]]
```

Verify that the signature is authentic:

```wl
In[6]:= verify[keys["PublicKey"], expr, sig]

Out[6]= True
```

Verifying with another expression will fail:

```wl
In[7]:= verify[keys["PublicKey"], "another expression", sig]

Out[7]= False
```

### Possible Issues (2)

#### Incompatible Private Keys (1)

Encryption with elliptic curve–based keys is not currently supported:

```wl
In[1]:= keys = GenerateAsymmetricKeyPair["EllipticCurve"]

Out[1]=
<|"PrivateKey" -> PrivateKey[Association["Type" -> "EllipticCurve", "CurveName" -> "secp256k1", 
  "PublicCurvePoint" -> 
   {101508668566949638846256739177192172116242732943419876271705976684468206503744, 
    8385295269522917944626986308165964351 ... 4, 
     70, 141, 232, 221, 103, 143, 138, 7, 146}], "PublicCurvePoint" -> 
   {101508668566949638846256739177192172116242732943419876271705976684468206503744, 
    83852952695229179446269863081659643512597604916983897363344059087578703988626}]]|>

In[2]:= Encrypt[keys["PrivateKey"], "Now is the time..."]
```

Encrypt::ecckeyspec: Encryption is not available with elliptic curves.

```wl
Out[2]= $Failed
```

#### Timing (1)

Generating larger keys takes longer:

```wl
In[1]:= AbsoluteTiming[GenerateAsymmetricKeyPair[Method -> <|"Type" -> "RSA", "KeySize" -> 512|>]]

Out[1]=
{0.0051896, <|"PrivateKey" -> PrivateKey[Association["Type" -> "RSA", "Cipher" -> "RSA", "Padding" -> "PKCS1", 
  "PublicExponent" -> 65537, "PublicModulus" -> 925275754314611800525915037611912163660240891858212\
99100917020737006081167997312536445 ... 76, 143, 100, 101, 43, 100, 241, 28, 52, 141, 151, 244, 141, 98, 101, 128, 78, 142, 80, 
     16, 103, 17, 45, 52, 98, 75, 125, 252, 178, 81, 22, 121, 119, 103, 234, 111, 46, 81, 5, 185, 
     241, 251, 30, 95, 97, 187, 85, 28, 177, 175, 27}]]]|>}

In[2]:= AbsoluteTiming[GenerateAsymmetricKeyPair[Method -> <|"Type" -> "RSA", "KeySize" -> 8192|>]]

Out[2]=
{4.2619, <|"PrivateKey" -> PrivateKey[Association["Type" -> "RSA", "Cipher" -> "RSA", "Padding" -> "PKCS1", 
  "PublicExponent" -> 65537, "PublicModulus" -> 790196677284606482795923790735500075108021113385793\
61373677462334003627564132385581684151 ... 12867915835683979591664760507085297421\
470571057060649972827005053635572737521552457431869894545361634647132696003332406511015350184127835\
726345232073766557719205856052987310711, "PublicByteArray" -> 
   ByteArray[CompressedData["«1493»"]]]]|>}
```

## See Also

* [`PrivateKey`](https://reference.wolfram.com/language/ref/PrivateKey.en.md)
* [`PublicKey`](https://reference.wolfram.com/language/ref/PublicKey.en.md)
* [`\$CryptographicEllipticCurveNames`](https://reference.wolfram.com/language/ref/$CryptographicEllipticCurveNames.en.md)
* [`Encrypt`](https://reference.wolfram.com/language/ref/Encrypt.en.md)
* [`Decrypt`](https://reference.wolfram.com/language/ref/Decrypt.en.md)
* [`GenerateDigitalSignature`](https://reference.wolfram.com/language/ref/GenerateDigitalSignature.en.md)
* [`VerifyDigitalSignature`](https://reference.wolfram.com/language/ref/VerifyDigitalSignature.en.md)
* [`DigitalSignature`](https://reference.wolfram.com/language/ref/DigitalSignature.en.md)
* [`RandomPrime`](https://reference.wolfram.com/language/ref/RandomPrime.en.md)
* [`PowerMod`](https://reference.wolfram.com/language/ref/PowerMod.en.md)

## Related Guides

* [Cryptographic Number Theory](https://reference.wolfram.com/language/guide/CryptographicNumberTheory.en.md)
* [Working with Tezos Blockchains](https://reference.wolfram.com/language/guide/Blockchain-Tezos.en.md)
* [Working with Ethereum Blockchains](https://reference.wolfram.com/language/guide/Blockchain-Ethereum.en.md)
* [Working with Cardano Blockchains](https://reference.wolfram.com/language/guide/Blockchain-Cardano.en.md)
* [Working with bloxberg Blockchain](https://reference.wolfram.com/language/guide/Blockchain-bloxberg.en.md)
* [Working with Bitcoin Blockchains](https://reference.wolfram.com/language/guide/Blockchain-Bitcoin.en.md)
* [Working with ARK Blockchains](https://reference.wolfram.com/language/guide/Blockchain-ARK.en.md)
* [Working with Blockchains](https://reference.wolfram.com/language/guide/Blockchain.en.md)
* [`Cryptography`](https://reference.wolfram.com/language/guide/Cryptography.en.md)

## Related Workflows

* [Create a Pay-to-Public-Key-Hash Bitcoin Address](https://reference.wolfram.com/language/workflow/CreateAPayToPublicKeyHashBitcoinAddress.en.md)
* [Create and Verify a Cryptographic Digital Signature](https://reference.wolfram.com/language/workflow/CreateAndVerifyACryptographicDigitalSignature.en.md)

## History

* [Introduced in 2015 (10.1)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn101.en.md) \| [Updated in 2019 (12.0)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn120.en.md) ▪ [2020 (12.1)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn121.en.md) ▪ [2020 (12.2)](https://reference.wolfram.com/language/guide/SummaryOfNewFeaturesIn122.en.md)