@@ -588,6 +588,45 @@ The recipinet has to call `counterverify` to verify the countersignature explici
588588``` py
589589from cwt import COSE , COSEKey, COSEMessage
590590
591+ enc_key = COSEKey.generate_symmetric_key(alg = " ChaCha20/Poly1305" , kid = " 01" )
592+
593+ # The sender side:
594+ nonce = enc_key.generate_nonce()
595+ sender = COSE .new(alg_auto_inclusion = True , kid_auto_inclusion = True )
596+ encoded = sender.encode(b " Hello world!" , enc_key, unprotected = {5 : nonce})
597+
598+ # The notary side:
599+ notary = Signer.from_jwk(
600+ {
601+ " kid" : " 01" ,
602+ " kty" : " OKP" ,
603+ " crv" : " Ed25519" ,
604+ " alg" : " EdDSA" ,
605+ " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
606+ " d" : " L8JS08VsFZoZxGa9JvzYmCWOwg7zaKcei3KZmYsj7dc" ,
607+ },
608+ )
609+ countersigned = COSEMessage.loads(encoded).countersign(notary).dumps()
610+
611+ # The recipient side:
612+ pub_key = COSEKey.from_jwk(
613+ {
614+ " kid" : " 01" ,
615+ " kty" : " OKP" ,
616+ " crv" : " Ed25519" ,
617+ " alg" : " EdDSA" ,
618+ " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
619+ },
620+ )
621+ recipient = COSE .new()
622+ assert b " Hello world!" == recipient.decode(countersigned, enc_key)
623+ try :
624+ sig = COSEMessage.loads(countersigned).counterverify(pub_key)
625+ except Exception as err:
626+ pytest.fail(f " failed to verify: { err} " )
627+ countersignature = COSEMessage.from_cose_signature(sig)
628+ assert countersignature.protected[1 ] == - 8 # alg: "EdDSA"
629+ assert countersignature.unprotected[4 ] == b " 01" # kid: b"01"
591630```
592631
593632#### COSE-HPKE (Encrypt0)
@@ -846,8 +885,56 @@ The notary below adds a countersignature to an encrypted COSE message.
846885The recipinet has to call ` counterverify ` to verify the countersignature explicitly.
847886
848887``` py
849- from cwt import COSE , COSEKey, COSEMessage
888+ from cwt import COSE , COSEKey, COSEMessage, Recipient
889+
890+ enc_key = COSEKey.generate_symmetric_key(alg = " ChaCha20/Poly1305" , kid = " 01" )
891+
892+ # The sender side:
893+ nonce = enc_key.generate_nonce()
894+ r = Recipient.new(unprotected = {" alg" : " direct" })
850895
896+ sender = COSE .new()
897+ encoded = sender.encode(
898+ b " Hello world!" ,
899+ enc_key,
900+ protected = {" alg" : " ChaCha20/Poly1305" },
901+ unprotected = {" kid" : enc_key.kid, " iv" : nonce},
902+ recipients = [r],
903+ )
904+
905+ # The notary side:
906+ notary = Signer.from_jwk(
907+ {
908+ " kid" : " 01" ,
909+ " kty" : " OKP" ,
910+ " crv" : " Ed25519" ,
911+ " alg" : " EdDSA" ,
912+ " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
913+ " d" : " L8JS08VsFZoZxGa9JvzYmCWOwg7zaKcei3KZmYsj7dc" ,
914+ },
915+ )
916+ countersigned = COSEMessage.loads(encoded).countersign(notary).dumps()
917+
918+ # The recipient side:
919+ pub_key = COSEKey.from_jwk(
920+ {
921+ " kid" : " 01" ,
922+ " kty" : " OKP" ,
923+ " crv" : " Ed25519" ,
924+ " alg" : " EdDSA" ,
925+ " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
926+ },
927+ )
928+ recipient = COSE .new()
929+ assert b " Hello world!" == recipient.decode(countersigned, enc_key)
930+
931+ try :
932+ sig = COSEMessage.loads(countersigned).counterverify(pub_key)
933+ except Exception as err:
934+ pytest.fail(f " failed to verify: { err} " )
935+ countersignature = COSEMessage.from_cose_signature(sig)
936+ assert countersignature.protected[1 ] == - 8 # alg: "EdDSA"
937+ assert countersignature.unprotected[4 ] == b " 01" # kid: b"01"
851938```
852939
853940#### COSE-HPKE (Encrypt)
@@ -953,6 +1040,61 @@ The recipinet has to call `counterverify` to verify the countersignature explici
9531040``` py
9541041from cwt import COSE , COSEKey, COSEMessage
9551042
1043+ # The sender side:
1044+ priv_key = COSEKey.from_jwk(
1045+ {
1046+ " kty" : " EC" ,
1047+ " kid" : " 01" ,
1048+ " crv" : " P-256" ,
1049+ " x" : " usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8" ,
1050+ " y" : " IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4" ,
1051+ " d" : " V8kgd2ZBRuh2dgyVINBUqpPDr7BOMGcF22CQMIUHtNM" ,
1052+ }
1053+ )
1054+ sender = COSE .new(alg_auto_inclusion = True , kid_auto_inclusion = True )
1055+ encoded = sender.encode(b " Hello world!" , priv_key)
1056+
1057+ # The notary side:
1058+ notary = Signer.from_jwk(
1059+ {
1060+ " kid" : " 01" ,
1061+ " kty" : " OKP" ,
1062+ " crv" : " Ed25519" ,
1063+ " alg" : " EdDSA" ,
1064+ " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
1065+ " d" : " L8JS08VsFZoZxGa9JvzYmCWOwg7zaKcei3KZmYsj7dc" ,
1066+ },
1067+ )
1068+ countersigned = COSEMessage.loads(encoded).countersign(notary).dumps()
1069+
1070+ # The recipient side:
1071+ pub_key = COSEKey.from_jwk(
1072+ {
1073+ " kty" : " EC" ,
1074+ " kid" : " 01" ,
1075+ " crv" : " P-256" ,
1076+ " x" : " usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8" ,
1077+ " y" : " IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4" ,
1078+ }
1079+ )
1080+ notary_pub_key = COSEKey.from_jwk(
1081+ {
1082+ " kid" : " 01" ,
1083+ " kty" : " OKP" ,
1084+ " crv" : " Ed25519" ,
1085+ " alg" : " EdDSA" ,
1086+ " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
1087+ },
1088+ )
1089+ recipient = COSE .new()
1090+ assert b " Hello world!" == recipient.decode(countersigned, pub_key)
1091+ try :
1092+ sig = COSEMessage.loads(countersigned).counterverify(notary_pub_key)
1093+ except Exception as err:
1094+ pytest.fail(f " failed to verify: { err} " )
1095+ countersignature = COSEMessage.from_cose_signature(sig)
1096+ assert countersignature.protected[1 ] == - 8 # alg: "EdDSA"
1097+ assert countersignature.unprotected[4 ] == b " 01" # kid: b"01"
9561098```
9571099
9581100### COSE Signature
@@ -997,8 +1139,64 @@ The notary below adds a countersignature to a signed COSE message.
9971139The recipinet has to call ` counterverify ` to verify the countersignature explicitly.
9981140
9991141``` py
1000- from cwt import COSE , COSEKey, COSEMessage
1142+ from cwt import COSE , COSEKey, COSEMessage, Signer
10011143
1144+ # The sender side:
1145+ signer = Signer.from_jwk(
1146+ {
1147+ " kty" : " EC" ,
1148+ " kid" : " 01" ,
1149+ " crv" : " P-256" ,
1150+ " x" : " usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8" ,
1151+ " y" : " IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4" ,
1152+ " d" : " V8kgd2ZBRuh2dgyVINBUqpPDr7BOMGcF22CQMIUHtNM" ,
1153+ },
1154+ )
1155+ sender = COSE .new()
1156+ encoded = sender.encode(b " Hello world!" , signers = [signer])
1157+
1158+ # The notary side:
1159+ notary = Signer.from_jwk(
1160+ {
1161+ " kid" : " 01" ,
1162+ " kty" : " OKP" ,
1163+ " crv" : " Ed25519" ,
1164+ " alg" : " EdDSA" ,
1165+ " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
1166+ " d" : " L8JS08VsFZoZxGa9JvzYmCWOwg7zaKcei3KZmYsj7dc" ,
1167+ },
1168+ )
1169+ countersigned = COSEMessage.loads(encoded).countersign(notary).dumps()
1170+
1171+ # The recipient side:
1172+ pub_key = COSEKey.from_jwk(
1173+ {
1174+ " kty" : " EC" ,
1175+ " kid" : " 01" ,
1176+ " crv" : " P-256" ,
1177+ " x" : " usWxHK2PmfnHKwXPS54m0kTcGJ90UiglWiGahtagnv8" ,
1178+ " y" : " IBOL-C3BttVivg-lSreASjpkttcsz-1rb7btKLv8EX4" ,
1179+ }
1180+ )
1181+ notary_pub_key = COSEKey.from_jwk(
1182+ {
1183+ " kid" : " 01" ,
1184+ " kty" : " OKP" ,
1185+ " crv" : " Ed25519" ,
1186+ " alg" : " EdDSA" ,
1187+ " x" : " 2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0" ,
1188+ },
1189+ )
1190+ recipient = COSE .new()
1191+ assert b " Hello world!" == recipient.decode(encoded, pub_key)
1192+
1193+ try :
1194+ sig = COSEMessage.loads(countersigned).counterverify(notary_pub_key)
1195+ except Exception as err:
1196+ pytest.fail(f " failed to verify: { err} " )
1197+ countersignature = COSEMessage.from_cose_signature(sig)
1198+ assert countersignature.protected[1 ] == - 8 # alg: "EdDSA"
1199+ assert countersignature.unprotected[4 ] == b " 01" # kid: b"01"
10021200```
10031201
10041202## CWT Usage Examples
0 commit comments