Skip to content

Commit 62898ce

Browse files
authored
Merge pull request #154 from thaddeusdiamond/main
CIP-0008: Allow for signing with stake key directly
2 parents 3527aa4 + 8eed562 commit 62898ce

File tree

2 files changed

+77
-3
lines changed

2 files changed

+77
-3
lines changed

pycardano/cip/cip8.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from pycardano.key import (
1414
PaymentVerificationKey,
1515
SigningKey,
16+
StakeExtendedSigningKey,
17+
StakeSigningKey,
1618
StakeVerificationKey,
1719
VerificationKey,
1820
)
@@ -27,7 +29,9 @@ def sign(
2729
attach_cose_key: bool = False,
2830
network: Network = Network.MAINNET,
2931
) -> Union[str, dict]:
30-
"""Sign an arbitrary message with a payment key following CIP-0008.
32+
"""Sign an arbitrary message with a payment or stake key following CIP-0008.
33+
Note that a stake key passed in must be of type StakeSigningKey or
34+
StakeExtendedSigningKey to be detected.
3135
3236
Args:
3337
message (str): Message to be signed
@@ -43,11 +47,22 @@ def sign(
4347
# derive the verification key
4448
verification_key = VerificationKey.from_signing_key(signing_key)
4549

50+
if isinstance(signing_key, StakeSigningKey) or isinstance(
51+
signing_key, StakeExtendedSigningKey
52+
):
53+
address = Address(
54+
payment_part=None, staking_part=verification_key.hash(), network=network
55+
)
56+
else:
57+
address = Address(
58+
payment_part=verification_key.hash(), staking_part=None, network=network
59+
)
60+
4661
# create the message object, attach verification key to the header
4762
msg = Sign1Message(
4863
phdr={
4964
Algorithm: EdDSA,
50-
"address": Address(verification_key.hash(), network=network).to_primitive(),
65+
"address": address.to_primitive(),
5166
},
5267
payload=message.encode("utf-8"),
5368
)

test/pycardano/test_cip8.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
from pycardano.cip.cip8 import sign, verify
2-
from pycardano.key import PaymentSigningKey, PaymentVerificationKey
2+
from pycardano.key import (
3+
PaymentSigningKey,
4+
PaymentVerificationKey,
5+
StakeSigningKey,
6+
StakeVerificationKey,
7+
)
38
from pycardano.network import Network
49

510
SK = PaymentSigningKey.from_json(
@@ -18,6 +23,22 @@
1823
}"""
1924
)
2025

26+
STAKE_SK = StakeSigningKey.from_json(
27+
"""{
28+
"type": "StakeSigningKeyShelley_ed25519",
29+
"description": "Stake Signing Key",
30+
"cborHex": "5820ff3a330df8859e4e5f42a97fcaee73f6a00d0cf864f4bca902bd106d423f02c0"
31+
}"""
32+
)
33+
34+
STAKE_VK = StakeVerificationKey.from_json(
35+
"""{
36+
"type": "StakeVerificationKeyShelley_ed25519",
37+
"description": "Stake Verification Key",
38+
"cborHex": "58205edaa384c658c2bd8945ae389edac0a5bd452d0cfd5d1245e3ecd540030d1e3c"
39+
}"""
40+
)
41+
2142

2243
def test_verify_message():
2344

@@ -75,6 +96,18 @@ def test_sign_message():
7596
)
7697

7798

99+
def test_sign_message_with_stake():
100+
101+
message = "Pycardano is cool."
102+
signed_message = sign(
103+
message, signing_key=STAKE_SK, attach_cose_key=False, network=Network.TESTNET
104+
)
105+
assert (
106+
signed_message
107+
== "84584da301276761646472657373581de04828a2dadba97ca9fd0cdc99975899470c219bdc0d828cfa6ddf6d690458205edaa384c658c2bd8945ae389edac0a5bd452d0cfd5d1245e3ecd540030d1e3ca166686173686564f452507963617264616e6f20697320636f6f6c2e5840ba1dd643f0d2e844f0509b1a7161ae4a3650f1d553fcc6e517020c5703acb70dfeea1014f2a1513baefaa2279cb151e8ff2dada6b51269cf33127d3c05829502"
108+
)
109+
110+
78111
def test_sign_message_cosy_key_separate():
79112

80113
message = "Pycardano is cool."
@@ -109,3 +142,29 @@ def test_sign_and_verify():
109142
assert verification["verified"]
110143
assert verification["message"] == "Pycardano is cool."
111144
assert verification["signing_address"].payment_part == VK.hash()
145+
146+
147+
def test_sign_and_verify_stake():
148+
149+
# try first with no cose key attached
150+
message = "Pycardano is cool."
151+
signed_message = sign(
152+
message, signing_key=STAKE_SK, attach_cose_key=False, network=Network.TESTNET
153+
)
154+
155+
verification = verify(signed_message)
156+
assert verification["verified"]
157+
assert verification["message"] == "Pycardano is cool."
158+
assert verification["signing_address"].payment_part == None
159+
assert verification["signing_address"].staking_part == STAKE_VK.hash()
160+
161+
# try again but attach cose key
162+
signed_message = sign(
163+
message, signing_key=STAKE_SK, attach_cose_key=True, network=Network.TESTNET
164+
)
165+
166+
verification = verify(signed_message)
167+
assert verification["verified"]
168+
assert verification["message"] == "Pycardano is cool."
169+
assert verification["signing_address"].payment_part == None
170+
assert verification["signing_address"].staking_part == STAKE_VK.hash()

0 commit comments

Comments
 (0)