-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add aip-80 specs Co-authored-by: Greg Nazario <[email protected]>
- Loading branch information
1 parent
15e238a
commit 65a280e
Showing
2 changed files
with
134 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
Feature: Cryptographic Private Keys | ||
""" | ||
Cryptographic private keys are keys that use asymmetric cryptography to sign and verify messages. | ||
This specifications covers the following: | ||
* Specifications for Ed25519 and Secp256k1 private keys. | ||
* AIP-80 compliant formatting and parsing of bytes, hex strings, and AIP-80 compliant strings. Read about AIP-80 here: https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-80.md | ||
""" | ||
|
||
Scenario Outline: It must format a HexString to an AIP-80 compliant string | ||
Given key <key> hexstring <value> | ||
When I format to aip-80 | ||
Then the result should be aip80_string <formatted> | ||
|
||
Examples: | ||
| key | value | formatted | | ||
| ed25519 | 0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | ed25519-priv-0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | | ||
| secp256k1 | 0xd107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | secp256k1-priv-0xd107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | | ||
|
||
Scenario Outline: It must accept a HexString and derive the private key | ||
Given key <key> hexstring <value> | ||
When I derive the private key | ||
Then the result should be aip80_string <formatted> | ||
|
||
Examples: | ||
| key | value | formatted | | ||
| ed25519 | 0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | ed25519-priv-0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | | ||
| secp256k1 | 0xd107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | secp256k1-priv-0xd107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | | ||
|
||
Scenario Outline: It must accept bytes and derive the private key | ||
Given key <key> bytes <value> | ||
When I derive the private key | ||
Then the result should be aip80_string <formatted> | ||
|
||
Examples: | ||
| key | value | formatted | | ||
| ed25519 | c5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | ed25519-priv-0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | | ||
| secp256k1 | d107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | secp256k1-priv-0xd107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | | ||
|
||
Scenario Outline: It must accept AIP-80 compliant strings and derive the private key | ||
Given key <key> aip80_string <value> | ||
When I derive the private key | ||
Then the result should be aip80_string <formatted> | ||
|
||
Examples: | ||
| key | value | formatted | | ||
| ed25519 | ed25519-priv-0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | ed25519-priv-0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | | ||
| secp256k1 | secp256k1-priv-0xd107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | secp256k1-priv-0xd107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | | ||
|
||
Scenario Outline: It should throw when an invalid AIP-80 string is provided | ||
Given key <key> aip80_string <value> | ||
When I derive the private key | ||
Then it should throw | ||
|
||
Examples: | ||
| key | value | | ||
| ed25519 | ed25519-priv-0xINVALIDHEX | | ||
| ed25519 | INVALIDPREFIX-0xc5338cd251c22daa8c9c9cc94f498cc8a5c7e1d2e75287a5dda91096fe64efa5 | | ||
| secp256k1 | secp256k1-priv-0xINVALIDHEX | | ||
| secp256k1 | INVALIDPREFIX-0xd107155adf816a0a94c6db3c9489c13ad8a1eda7ada2e558ba3bfa47c020347e | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { Given, Then, When } from "@cucumber/cucumber"; | ||
import { Ed25519PrivateKey, Hex, PrivateKey, PrivateKeyVariants, Secp256k1PrivateKey } from "../../dist/esm/index.mjs"; | ||
import assert from "assert"; | ||
|
||
/* eslint-disable func-names */ | ||
|
||
Given( | ||
/^key (ed25519|secp256k1) (hexstring|bytes|aip80_string) (.*)$/, | ||
function (keyType: string, valueType: string, value: string) { | ||
switch (keyType) { | ||
case "ed25519": | ||
this.keyType = PrivateKeyVariants.Ed25519; | ||
break; | ||
case "secp256k1": | ||
this.keyType = PrivateKeyVariants.Secp256k1; | ||
break; | ||
default: | ||
throw new Error(`Unsupported key type: ${keyType}`); | ||
} | ||
|
||
switch (valueType) { | ||
case "hexstring": | ||
this.inputType = "hexstring"; | ||
this.input = value; | ||
break; | ||
case "bytes": | ||
this.inputType = "bytes"; | ||
this.input = Hex.fromHexString(value).toUint8Array(); | ||
break; | ||
case "aip80_string": | ||
this.inputType = "aip80_string"; | ||
this.input = value; | ||
break; | ||
default: | ||
throw new Error(`Unsupported value type: ${valueType}`); | ||
} | ||
}, | ||
); | ||
|
||
When(/^I derive the private key$/, function () { | ||
try { | ||
switch (this.keyType) { | ||
case PrivateKeyVariants.Ed25519: | ||
this.result = new Ed25519PrivateKey(this.input, false).toAIP80String(); | ||
break; | ||
case PrivateKeyVariants.Secp256k1: | ||
this.result = new Secp256k1PrivateKey(this.input, false).toAIP80String(); | ||
break; | ||
default: | ||
throw new Error(`Unsupported key type: ${this.keyType}`); | ||
} | ||
} catch (error) { | ||
this.error = error; | ||
} | ||
}); | ||
|
||
When(/^I format to aip-80$/, function () { | ||
this.result = PrivateKey.formatPrivateKey(this.input, this.keyType); | ||
}); | ||
|
||
Then(/^the result should be (aip80_string) (.*)$/, function (type: string, value: string) { | ||
if (this.error) throw this.error; | ||
switch (type) { | ||
case "aip80_string": | ||
assert.equal(this.result, value, `Expected ${value} to be ${this.result}`); | ||
break; | ||
default: | ||
throw new Error(`Unsupported result type: ${type}`); | ||
} | ||
}); | ||
|
||
Then(/^it should throw$/, function () { | ||
assert(this.error !== undefined, "Expected an error to be thrown"); | ||
}); |