iso-signatures 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,31 +13,29 @@ export class ECDSASigner implements ISigner {
13
13
  /**
14
14
  * Import a signer from a JWK
15
15
  *
16
- * @param {import('../types.js').PrivateKeyJwk} jwk
16
+ * @param {import('iso-did/types').ECJWKPrivate} jwk
17
+ * @param {import('iso-did/types').VerifiableDID} [did]
17
18
  */
18
- static importJwk(jwk: import('../types.js').PrivateKeyJwk): Promise<ECDSASigner>;
19
+ static importJwk(jwk: import('iso-did/types').ECJWKPrivate, did?: import("iso-did/types").VerifiableDID | undefined): Promise<ECDSASigner>;
19
20
  /**
20
21
  * Import a signer from a CryptoKeyPair
21
22
  *
22
23
  * @param {CryptoKeyPair} key
24
+ * @param {import('iso-did/types').VerifiableDID} [did]
23
25
  */
24
- static import(key: CryptoKeyPair): Promise<ECDSASigner>;
26
+ static import(key: CryptoKeyPair, did?: import("iso-did/types").VerifiableDID | undefined): Promise<ECDSASigner>;
25
27
  /**
26
- * @param {ECDSAAlg} alg
27
- * @param {Uint8Array} publicKey
28
+ * @param {import('iso-did/types').VerifiableDID} did
28
29
  * @param {CryptoKeyPair} keypair
29
30
  */
30
- constructor(alg: ECDSAAlg, publicKey: Uint8Array, keypair: CryptoKeyPair);
31
- params: {
32
- name: "ECDSA";
33
- namedCurve: "P-256" | "P-384" | "P-521";
34
- hash: "SHA-256" | "SHA-384" | "SHA-512";
35
- };
36
- keypair: CryptoKeyPair;
31
+ constructor(did: import('iso-did/types').VerifiableDID, keypair: CryptoKeyPair);
32
+ did: `did:${string}:${string}`;
33
+ url: import("iso-did/types").DIDURLObject;
34
+ type: "P-256" | "P-384" | "P-521" | "Ed25519" | "secp256k1" | "RSA";
37
35
  publicKey: Uint8Array;
38
36
  alg: "ES256" | "ES384" | "ES512";
39
- type: "P-256" | "P-384" | "P-521";
40
- did: DIDKey;
37
+ document: import("iso-did/types").DIDDocument;
38
+ didKey: `did:${string}:${string}`;
41
39
  /**
42
40
  * Sign a message
43
41
  *
@@ -50,8 +48,9 @@ export class ECDSASigner implements ISigner {
50
48
  * @returns {CryptoKeyPair}
51
49
  */
52
50
  export(): CryptoKeyPair;
51
+ toString(): string;
52
+ #private;
53
53
  }
54
54
  export type ISigner = import('../types.js').ISigner<CryptoKeyPair>;
55
55
  export type ECDSAAlg = Extract<import('iso-did/types').SignatureAlgorithm, 'ES256' | 'ES384' | 'ES512'>;
56
- import { DIDKey } from 'iso-did/key';
57
56
  //# sourceMappingURL=ecdsa.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ecdsa.d.ts","sourceRoot":"","sources":["../../../src/signers/ecdsa.js"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH;IAeE;;;;OAIG;IACH,qBAFW,QAAQ,wBAelB;IAED;;;;OAIG;IACH,sBAFW,OAAO,aAAa,EAAE,aAAa,wBA0B7C;IAED;;;;OAIG;IACH,mBAFW,aAAa,wBA0BvB;IA9FD;;;;OAIG;IACH,iBAJW,QAAQ,aACR,UAAU,WACV,aAAa,EASvB;IANC;;;;MAAoC;IACpC,uBAAsB;IACtB,sBAA0B;IAC1B,iCAAc;IACd,kCAAkC;IAClC,YAA0D;IAqF5D;;;;OAIG;IACH,cAFW,UAAU,uBAUpB;IAED;;;;OAIG;IACH,UAFa,aAAa,CAIzB;CACF;sBA3IY,OAAO,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC;uBAC5C,QAAQ,OAAO,eAAe,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;uBALxD,aAAa"}
1
+ {"version":3,"file":"ecdsa.d.ts","sourceRoot":"","sources":["../../../src/signers/ecdsa.js"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH;IAsBE;;;;OAIG;IACH,qBAFW,QAAQ,wBAkBlB;IAED;;;;;OAKG;IACH,sBAHW,OAAO,eAAe,EAAE,YAAY,iFA4B9C;IAED;;;;;OAKG;IACH,mBAHW,aAAa,iFA+BvB;IA1GD;;;OAGG;IACH,iBAHW,OAAO,eAAe,EAAE,aAAa,WACrC,aAAa,EAYvB;IATC,+BAAkB;IAClB,0CAAkB;IAClB,oEAAoB;IACpB,sBAA8B;IAC9B,iCAA8B;IAC9B,8CAA4B;IAG5B,kCAAqE;IA+FvE;;;;OAIG;IACH,cAFW,UAAU,uBAUpB;IAED;;;;OAIG;IACH,UAFa,aAAa,CAIzB;IAED,mBAEC;;CACF;sBAhKY,OAAO,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC;uBAC5C,QAAQ,OAAO,eAAe,EAAE,kBAAkB,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC"}
@@ -1,6 +1,3 @@
1
- /**
2
- * @typedef {import('../types.js').ISigner<string>} ISigner
3
- */
4
1
  /**
5
2
  * EdDSA signer
6
3
  *
@@ -22,19 +19,21 @@ export class EdDSASigner implements ISigner {
22
19
  * Import a signer from a encoded string
23
20
  *
24
21
  * @param {string} encoded
22
+ * @param {import('iso-did/types').VerifiableDID} [did]
25
23
  */
26
- static import(encoded: string): Promise<EdDSASigner>;
24
+ static import(encoded: string, did?: import("iso-did/types").VerifiableDID | undefined): Promise<EdDSASigner>;
27
25
  /**
28
- * @param {Uint8Array} publicKey
26
+ * @param {import('iso-did/types').VerifiableDID} did
29
27
  * @param {Uint8Array} privateKey
30
28
  */
31
- constructor(publicKey: Uint8Array, privateKey: Uint8Array);
32
- privateKey: Uint8Array;
29
+ constructor(did: import('iso-did/types').VerifiableDID, privateKey: Uint8Array);
30
+ did: `did:${string}:${string}`;
31
+ url: import("iso-did/types").DIDURLObject;
32
+ type: "P-256" | "P-384" | "P-521" | "Ed25519" | "secp256k1" | "RSA";
33
33
  publicKey: Uint8Array;
34
- alg: "EdDSA";
35
- type: "Ed25519";
36
- code: number;
37
- did: DIDKey;
34
+ alg: "EdDSA" | "ES256" | "ES384" | "ES512" | "ES256K" | "RS256";
35
+ document: import("iso-did/types").DIDDocument;
36
+ didKey: `did:${string}:${string}`;
38
37
  /**
39
38
  * Sign a message
40
39
  *
@@ -45,7 +44,8 @@ export class EdDSASigner implements ISigner {
45
44
  * Export the signer as a encoded string
46
45
  */
47
46
  export(): string;
47
+ toString(): string;
48
+ #private;
48
49
  }
49
50
  export type ISigner = import('../types.js').ISigner<string>;
50
- import { DIDKey } from 'iso-did/key';
51
51
  //# sourceMappingURL=eddsa.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eddsa.d.ts","sourceRoot":"","sources":["../../../src/signers/eddsa.js"],"names":[],"mappings":"AAUA;;GAEG;AAEH;;;;GAIG;AACH;IACE,2EAA2E;IAC3E,YADW,QAAQ,OAAO,eAAe,EAAE,kBAAkB,EAAE,OAAO,CAAC,CACnD;IAEpB,kEAAkE;IAClE,aADW,QAAQ,OAAO,eAAe,EAAE,OAAO,EAAE,SAAS,CAAC,CACvC;IAEvB,oBAAoB;IAepB;;;;OAIG;IACH,sEAIC;IAED;;;;OAIG;IACH,uBAFW,MAAM,wBAOhB;IAlCD;;;OAGG;IACH,uBAHW,UAAU,cACV,UAAU,EASpB;IANC,uBAA4B;IAC5B,sBAA0B;IAC1B,aAA0B;IAC1B,gBAA4B;IAC5B,aAA4B;IAC5B,YAAiE;IA0BnE;;;;OAIG;IACH,cAFW,UAAU,uBAIpB;IAED;;OAEG;IACH,iBAEC;CACF;sBApEY,OAAO,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC;uBAN3B,aAAa"}
1
+ {"version":3,"file":"eddsa.d.ts","sourceRoot":"","sources":["../../../src/signers/eddsa.js"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH;IACE,2EAA2E;IAC3E,YADW,QAAQ,OAAO,eAAe,EAAE,kBAAkB,EAAE,OAAO,CAAC,CACnD;IAEpB,kEAAkE;IAClE,aADW,QAAQ,OAAO,eAAe,EAAE,OAAO,EAAE,SAAS,CAAC,CACvC;IAEvB,oBAAoB;IAqBpB;;;;OAIG;IACH,sEAOC;IAED;;;;;OAKG;IACH,uBAHW,MAAM,iFAWhB;IA5CD;;;OAGG;IACH,iBAHW,OAAO,eAAe,EAAE,aAAa,cACrC,UAAU,EAYpB;IARC,+BAAkB;IAClB,0CAAkB;IAClB,oEAAoB;IACpB,sBAA8B;IAC9B,gEAAkB;IAClB,8CAA4B;IAE5B,kCAAqE;IAiCvE;;;;OAIG;IACH,cAFW,UAAU,uBAIpB;IAED;;OAEG;IACH,iBAEC;IAED,mBAEC;;CACF;sBAlGY,OAAO,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC"}
@@ -1,6 +1,3 @@
1
- /**
2
- * @typedef {import('../types.js').ISigner<CryptoKeyPair>} ISigner
3
- */
4
1
  /**
5
2
  * RSA signer
6
3
  *
@@ -19,26 +16,29 @@ export class RSASigner implements ISigner {
19
16
  /**
20
17
  * Import a signer from a JWK
21
18
  *
22
- * @param {import('../types.js').PrivateKeyRSAJwk} jwk
19
+ * @param {import('iso-did/types').RSAJWKPrivate} jwk
20
+ * @param {import('iso-did/types').VerifiableDID} [did]
23
21
  */
24
- static importJwk(jwk: import('../types.js').PrivateKeyRSAJwk): Promise<RSASigner>;
22
+ static importJwk(jwk: import('iso-did/types').RSAJWKPrivate, did?: import("iso-did/types").VerifiableDID | undefined): Promise<RSASigner>;
25
23
  /**
26
24
  * Import a signer from a keypair
27
25
  *
28
26
  * @param {CryptoKeyPair} keypair
27
+ * @param {import('iso-did/types').VerifiableDID} [did]
29
28
  */
30
- static import(keypair: CryptoKeyPair): Promise<RSASigner>;
29
+ static import(keypair: CryptoKeyPair, did?: import("iso-did/types").VerifiableDID | undefined): Promise<RSASigner>;
31
30
  /**
32
- * @param {Uint8Array} publicKey
31
+ * @param {import('iso-did/types').VerifiableDID} did
33
32
  * @param {CryptoKeyPair} keypair
34
33
  */
35
- constructor(publicKey: Uint8Array, keypair: CryptoKeyPair);
36
- keypair: CryptoKeyPair;
34
+ constructor(did: import('iso-did/types').VerifiableDID, keypair: CryptoKeyPair);
35
+ did: `did:${string}:${string}`;
36
+ url: import("iso-did/types").DIDURLObject;
37
+ type: "P-256" | "P-384" | "P-521" | "Ed25519" | "secp256k1" | "RSA";
37
38
  publicKey: Uint8Array;
38
- alg: "RS256";
39
- type: "RSA";
40
- code: number;
41
- did: DIDKey;
39
+ alg: "EdDSA" | "ES256" | "ES384" | "ES512" | "ES256K" | "RS256";
40
+ document: import("iso-did/types").DIDDocument;
41
+ didKey: `did:${string}:${string}`;
42
42
  /**
43
43
  * Sign a message
44
44
  *
@@ -49,7 +49,8 @@ export class RSASigner implements ISigner {
49
49
  * Export the signer as a crypto key pair
50
50
  */
51
51
  export(): CryptoKeyPair;
52
+ toString(): string;
53
+ #private;
52
54
  }
53
55
  export type ISigner = import('../types.js').ISigner<CryptoKeyPair>;
54
- import { DIDKey } from 'iso-did/key';
55
56
  //# sourceMappingURL=rsa.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rsa.d.ts","sourceRoot":"","sources":["../../../src/signers/rsa.js"],"names":[],"mappings":"AAMA;;GAEG;AAEH;;;;GAIG;AACH;IACE,2EAA2E;IAC3E,YADW,QAAQ,OAAO,eAAe,EAAE,kBAAkB,EAAE,OAAO,CAAC,CACnD;IAEpB,8DAA8D;IAC9D,aADW,QAAQ,OAAO,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC,CACvC;IAGnB,oBAAoB;IAepB;;OAEG;IACH,sCAmBC;IAED;;;;OAIG;IACH,sBAFW,OAAO,aAAa,EAAE,gBAAgB,sBA8BhD;IAED;;;;OAIG;IACH,uBAFW,aAAa,sBASvB;IApFD;;;OAGG;IACH,uBAHW,UAAU,WACV,aAAa,EASvB;IANC,uBAAsB;IACtB,sBAA0B;IAC1B,aAAwB;IACxB,YAA0B;IAC1B,aAA0B;IAC1B,YAA+D;IA4EjE;;;;OAIG;IACH,cAFW,UAAU,uBAUpB;IAED;;OAEG;IACH,wBAEC;CACF;sBA7HY,OAAO,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC;uBAJlC,aAAa"}
1
+ {"version":3,"file":"rsa.d.ts","sourceRoot":"","sources":["../../../src/signers/rsa.js"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH;IACE,2EAA2E;IAC3E,YADW,QAAQ,OAAO,eAAe,EAAE,kBAAkB,EAAE,OAAO,CAAC,CACnD;IAEpB,8DAA8D;IAC9D,aADW,QAAQ,OAAO,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC,CACvC;IAGnB,oBAAoB;IAqBpB;;OAEG;IACH,sCAqBC;IAED;;;;;OAKG;IACH,sBAHW,OAAO,eAAe,EAAE,aAAa,+EAgC/C;IAED;;;;;OAKG;IACH,uBAHW,aAAa,+EAevB;IAjGD;;;OAGG;IACH,iBAHW,OAAO,eAAe,EAAE,aAAa,WACrC,aAAa,EAYvB;IARC,+BAAkB;IAClB,0CAAkB;IAClB,oEAAoB;IACpB,sBAA8B;IAC9B,gEAAkB;IAClB,8CAA4B;IAE5B,kCAAqE;IAsFvE;;;;OAIG;IACH,cAFW,UAAU,uBAUpB;IAED;;OAEG;IACH,wBAEC;IAED,mBAEC;;CACF;sBA9JY,OAAO,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC"}
@@ -1,23 +1,9 @@
1
- import type { DIDKey } from 'iso-did/key';
2
- import type { KeyType, SignatureAlgorithm } from 'iso-did/types';
3
- export interface ISigner<Export extends CryptoKeyPair | string> {
4
- /**
5
- * JWT signing algorithm
6
- */
7
- alg: SignatureAlgorithm;
8
- /**
9
- * Keypair type
10
- */
11
- type: KeyType;
12
- /**
13
- * Multicodec identifier for the private key
14
- */
15
- code?: number;
16
- did: DIDKey;
17
- /**
18
- * Sign a message
19
- */
1
+ import type { SignatureAlgorithm, VerifiableDID } from 'iso-did/types';
2
+ export interface Sign {
20
3
  sign: (message: Uint8Array) => Promise<Uint8Array>;
4
+ }
5
+ export interface ISigner<Export extends CryptoKeyPair | string> extends VerifiableDID, Sign {
6
+ code?: number;
21
7
  export: () => Export;
22
8
  }
23
9
  export interface VerifyInput {
@@ -38,26 +24,4 @@ export interface IResolver {
38
24
  export interface ResolverOptions {
39
25
  cache?: Cache | boolean | undefined;
40
26
  }
41
- export interface PublicKeyJwk {
42
- kty: string;
43
- crv: string;
44
- x: string;
45
- y: string;
46
- }
47
- export interface PublicKeyRSAJwk {
48
- kty: string;
49
- n: string;
50
- e: string;
51
- }
52
- export interface PrivateKeyRSAJwk extends PublicKeyRSAJwk {
53
- d: string;
54
- p: string;
55
- q: string;
56
- dp: string;
57
- dq: string;
58
- qi: string;
59
- }
60
- export type PrivateKeyJwk = PublicKeyJwk & {
61
- d: string;
62
- };
63
27
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAEhE,MAAM,WAAW,OAAO,CAAC,MAAM,SAAS,aAAa,GAAG,MAAM;IAC5D;;OAEG;IACH,GAAG,EAAE,kBAAkB,CAAA;IACvB;;OAEG;IACH,IAAI,EAAE,OAAO,CAAA;IACb;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb,GAAG,EAAE,MAAM,CAAA;IACX;;OAEG;IACH,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;IAElD,MAAM,EAAE,MAAM,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,UAAU,CAAA;IACrB,OAAO,EAAE,UAAU,CAAA;IACnB,SAAS,EAAE,UAAU,CAAA;CACtB;AACD,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE7D,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,kBAAkB,IAAI,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AAEtE,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,kBAAkB,IAAI,OAAO,CAClE,QAAQ,CAAC,CAAC,CAAC,CACZ,CAAA;AAED,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,GAAG,EAAE,kBAAkB,CAAA;CACxB;AACD,MAAM,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE7E,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACzD;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,SAAS,CAAA;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG;IAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAEtE,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAA;CACnD;AAED,MAAM,WAAW,OAAO,CAAC,MAAM,SAAS,aAAa,GAAG,MAAM,CAC5D,SAAQ,aAAa,EACnB,IAAI;IACN,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,UAAU,CAAA;IACrB,OAAO,EAAE,UAAU,CAAA;IACnB,SAAS,EAAE,UAAU,CAAA;CACtB;AACD,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE7D,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,kBAAkB,IAAI,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;AAEtE,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,kBAAkB,IAAI,OAAO,CAClE,QAAQ,CAAC,CAAC,CAAC,CACZ,CAAA;AAED,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,GAAG,EAAE,kBAAkB,CAAA;CACxB;AACD,MAAM,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE7E,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACzD;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,SAAS,CAAA;CACpC"}
@@ -9,4 +9,11 @@ export function createEcdsaParams(alg: import("iso-did/types").SignatureAlgorith
9
9
  namedCurve: 'P-256' | 'P-384' | 'P-521';
10
10
  hash: 'SHA-256' | 'SHA-384' | 'SHA-512';
11
11
  };
12
+ /**
13
+ *
14
+ * @param {import('iso-did/types').KeyType} type
15
+ * @param {BufferSource} publicKey
16
+ * @param {import('iso-did/types').VerifiableDID} [did]
17
+ */
18
+ export function didKeyOrVerifiableDID(type: import('iso-did/types').KeyType, publicKey: BufferSource, did?: import("iso-did/types").VerifiableDID | undefined): import("iso-did/types").VerifiableDID;
12
19
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,uCAHW,OAAO,eAAe,EAAE,kBAAkB,GACxC;IAAC,MAAM,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;CAAC,CA8B7G"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,uCAHW,OAAO,eAAe,EAAE,kBAAkB,GACxC;IAAC,MAAM,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;CAAC,CA8B7G;AAED;;;;;GAKG;AACH,4CAJW,OAAO,eAAe,EAAE,OAAO,aAC/B,YAAY,kGAsBtB"}
@@ -1 +1 @@
1
- {"version":3,"file":"eddsa.d.ts","sourceRoot":"","sources":["../../../src/verifiers/eddsa.js"],"names":[],"mappings":"AAWuT,gFAAyC;AAJhW,mDAAmD;AACnD,uBADW,OAAO,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,CAG9C"}
1
+ {"version":3,"file":"eddsa.d.ts","sourceRoot":"","sources":["../../../src/verifiers/eddsa.js"],"names":[],"mappings":"AAWsH,gFAAyC;AAJ/J,mDAAmD;AACnD,uBADW,OAAO,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,CAG9C"}
@@ -12,7 +12,6 @@ export class Resolver implements IResolver {
12
12
  constructor(registry?: import('../types').VerifierRegistry<import('iso-did/types').SignatureAlgorithm>, options?: import('../types').ResolverOptions);
13
13
  registry: Partial<import("../types").Verifier<"EdDSA" | "ES256" | "ES384" | "ES512" | "ES256K" | "RS256">>;
14
14
  cache: import("../types").Cache;
15
- /** @type {IResolver['verify']} */
16
15
  verify(input: import("../types").ResolverVerifyInput): Promise<boolean>;
17
16
  }
18
17
  export type IResolver = import('../types').IResolver;
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/verifiers/resolver.js"],"names":[],"mappings":"AAoCA;;;;GAIG;AACH;IACE;;;;OAIG;IACH,uBAHW,OAAO,UAAU,EAAE,gBAAgB,CAAC,OAAO,eAAe,EAAE,kBAAkB,CAAC,YAC/E,OAAO,UAAU,EAAE,eAAe,EAM5C;IAHC,2GAAwB;IACxB,gCACmE;IAGrE,kCAAkC;IAClC,wEAAS;CAQV;wBA7DY,OAAO,UAAU,EAAE,SAAS"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/verifiers/resolver.js"],"names":[],"mappings":"AAoCA;;;;GAIG;AACH;IACE;;;;OAIG;IACH,uBAHW,OAAO,UAAU,EAAE,gBAAgB,CAAC,OAAO,eAAe,EAAE,kBAAkB,CAAC,YAC/E,OAAO,UAAU,EAAE,eAAe,EAM5C;IAHC,2GAAwB;IACxB,gCACmE;IALlC,wEAEd;CAetB;wBA7DY,OAAO,UAAU,EAAE,SAAS"}
@@ -1 +1 @@
1
- {"version":3,"file":"rsa.d.ts","sourceRoot":"","sources":["../../../src/verifiers/rsa.js"],"names":[],"mappings":"AAyBM,mFAAyC;AAJ/C,sDAAsD;AACtD,uBADW,OAAO,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,CAGjD"}
1
+ {"version":3,"file":"rsa.d.ts","sourceRoot":"","sources":["../../../src/verifiers/rsa.js"],"names":[],"mappings":"AAcQ,mFAAyC;AAOjD,sDAAsD;AACtD,uBADW,OAAO,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,CAGjD"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "iso-signatures",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.3.1",
5
5
  "description": "Signatures tooling.",
6
6
  "author": "Hugo Dias <hugomrdias@gmail.com> (hugodias.me)",
7
7
  "license": "MIT",
@@ -83,16 +83,16 @@
83
83
  "dependencies": {
84
84
  "@noble/ed25519": "^2.0.0",
85
85
  "iso-base": "^2.0.1",
86
- "iso-did": "^1.4.0"
86
+ "iso-did": "^1.6.0"
87
87
  },
88
88
  "devDependencies": {
89
89
  "@types/assert": "^1.5.10",
90
90
  "@types/mocha": "^10.0.6",
91
- "@types/node": "^20.10.4",
91
+ "@types/node": "^20.11.15",
92
92
  "assert": "^2.1.0",
93
93
  "mocha": "^10.2.0",
94
- "playwright-test": "^14.0.0",
95
- "type-fest": "^4.8.3",
94
+ "playwright-test": "^14.1.0",
95
+ "type-fest": "^4.10.2",
96
96
  "typescript": "5.3.3"
97
97
  },
98
98
  "publishConfig": {
@@ -1,7 +1,7 @@
1
1
  import { webcrypto } from 'iso-base/crypto'
2
2
  import { u8 } from 'iso-base/utils'
3
- import { DIDKey, keyTypeToAlg } from 'iso-did/key'
4
- import { createEcdsaParams } from '../utils.js'
3
+ import { DIDKey, algToKeyType, keyTypeToAlg } from 'iso-did/key'
4
+ import { createEcdsaParams, didKeyOrVerifiableDID } from '../utils.js'
5
5
 
6
6
  /**
7
7
  * @typedef {import('../types.js').ISigner<CryptoKeyPair>} ISigner
@@ -12,7 +12,7 @@ import { createEcdsaParams } from '../utils.js'
12
12
  * @param {string} alg
13
13
  */
14
14
  function asECDSAAlg(alg) {
15
- if (alg.startsWith('ES')) {
15
+ if (['ES256', 'ES384', 'ES512'].includes(alg)) {
16
16
  return /** @type {ECDSAAlg} */ (alg)
17
17
  }
18
18
  throw new TypeError(`Unsupported algorithm ${alg}`)
@@ -24,18 +24,25 @@ function asECDSAAlg(alg) {
24
24
  * @implements {ISigner}
25
25
  */
26
26
  export class ECDSASigner {
27
+ /** @type {ReturnType<createEcdsaParams>} */
28
+ #params
29
+
30
+ /** @type {CryptoKeyPair} */
31
+ #keypair
27
32
  /**
28
- * @param {ECDSAAlg} alg
29
- * @param {Uint8Array} publicKey
33
+ * @param {import('iso-did/types').VerifiableDID} did
30
34
  * @param {CryptoKeyPair} keypair
31
35
  */
32
- constructor(alg, publicKey, keypair) {
33
- this.params = createEcdsaParams(alg)
34
- this.keypair = keypair
35
- this.publicKey = publicKey
36
- this.alg = alg
37
- this.type = this.params.namedCurve
38
- this.did = DIDKey.fromPublicKey(this.type, this.publicKey)
36
+ constructor(did, keypair) {
37
+ this.did = did.did
38
+ this.url = did.url
39
+ this.type = did.type
40
+ this.publicKey = did.publicKey
41
+ this.alg = asECDSAAlg(did.alg)
42
+ this.document = did.document
43
+ this.#params = createEcdsaParams(this.alg)
44
+ this.#keypair = keypair
45
+ this.didKey = DIDKey.fromPublicKey(this.type, this.publicKey).url.did
39
46
  }
40
47
 
41
48
  /**
@@ -55,17 +62,22 @@ export class ECDSASigner {
55
62
  cryptoKeyPair.publicKey
56
63
  )
57
64
 
58
- return new ECDSASigner(alg, u8(publicKey), cryptoKeyPair)
65
+ return new ECDSASigner(
66
+ DIDKey.fromPublicKey(algToKeyType(alg), u8(publicKey)),
67
+ cryptoKeyPair
68
+ )
59
69
  }
60
70
 
61
71
  /**
62
72
  * Import a signer from a JWK
63
73
  *
64
- * @param {import('../types.js').PrivateKeyJwk} jwk
74
+ * @param {import('iso-did/types').ECJWKPrivate} jwk
75
+ * @param {import('iso-did/types').VerifiableDID} [did]
65
76
  */
66
- static async importJwk(jwk) {
77
+ static async importJwk(jwk, did) {
67
78
  const alg = asECDSAAlg(keyTypeToAlg(jwk.crv))
68
79
  const params = createEcdsaParams(alg)
80
+ const type = jwk.crv
69
81
  const privateKey = await webcrypto.subtle.importKey(
70
82
  'jwk',
71
83
  jwk,
@@ -83,7 +95,7 @@ export class ECDSASigner {
83
95
 
84
96
  const publicKey = await webcrypto.subtle.exportKey('raw', publicKeyJWK)
85
97
 
86
- return new ECDSASigner(alg, u8(publicKey), {
98
+ return new ECDSASigner(didKeyOrVerifiableDID(type, publicKey, did), {
87
99
  privateKey,
88
100
  publicKey: publicKeyJWK,
89
101
  })
@@ -93,8 +105,9 @@ export class ECDSASigner {
93
105
  * Import a signer from a CryptoKeyPair
94
106
  *
95
107
  * @param {CryptoKeyPair} key
108
+ * @param {import('iso-did/types').VerifiableDID} [did]
96
109
  */
97
- static async import(key) {
110
+ static async import(key, did) {
98
111
  const publicKey = await webcrypto.subtle.exportKey('raw', key.publicKey)
99
112
 
100
113
  /** @type { ECDSAAlg } */
@@ -117,7 +130,11 @@ export class ECDSASigner {
117
130
  throw new Error('Unsupported key type')
118
131
  }
119
132
  }
120
- return new ECDSASigner(alg, u8(publicKey), key)
133
+
134
+ return new ECDSASigner(
135
+ didKeyOrVerifiableDID(algToKeyType(alg), publicKey, did),
136
+ key
137
+ )
121
138
  }
122
139
 
123
140
  /**
@@ -127,8 +144,8 @@ export class ECDSASigner {
127
144
  */
128
145
  async sign(message) {
129
146
  const buf = await webcrypto.subtle.sign(
130
- this.params,
131
- this.keypair.privateKey,
147
+ this.#params,
148
+ this.#keypair.privateKey,
132
149
  message
133
150
  )
134
151
 
@@ -141,6 +158,10 @@ export class ECDSASigner {
141
158
  * @returns {CryptoKeyPair}
142
159
  */
143
160
  export() {
144
- return this.keypair
161
+ return this.#keypair
162
+ }
163
+
164
+ toString() {
165
+ return this.url.didUrl
145
166
  }
146
167
  }
@@ -4,6 +4,7 @@ import { webcrypto } from 'iso-base/crypto'
4
4
  import { base64pad } from 'iso-base/rfc4648'
5
5
  import { tag, untag } from 'iso-base/varint'
6
6
  import { DIDKey } from 'iso-did/key'
7
+ import { didKeyOrVerifiableDID } from '../utils.js'
7
8
 
8
9
  // @ts-ignore
9
10
  if (!globalThis.crypto) globalThis.crypto = webcrypto
@@ -12,6 +13,19 @@ if (!globalThis.crypto) globalThis.crypto = webcrypto
12
13
  * @typedef {import('../types.js').ISigner<string>} ISigner
13
14
  */
14
15
 
16
+ /**
17
+ *
18
+ * @param {import('iso-did/types').VerifiableDID} did
19
+ */
20
+ function checkDid(did) {
21
+ if (did.type !== 'Ed25519') {
22
+ throw new TypeError(`Unsupported key type ${did.type}`)
23
+ }
24
+ if (did.alg !== 'EdDSA') {
25
+ throw new TypeError(`Unsupported algorithm ${did.alg}`)
26
+ }
27
+ }
28
+
15
29
  /**
16
30
  * EdDSA signer
17
31
  *
@@ -26,17 +40,23 @@ export class EdDSASigner {
26
40
 
27
41
  static code = 0x1300
28
42
 
43
+ /** @type {Uint8Array} */
44
+ #privateKey
45
+
29
46
  /**
30
- * @param {Uint8Array} publicKey
47
+ * @param {import('iso-did/types').VerifiableDID} did
31
48
  * @param {Uint8Array} privateKey
32
49
  */
33
- constructor(publicKey, privateKey) {
34
- this.privateKey = privateKey
35
- this.publicKey = publicKey
36
- this.alg = EdDSASigner.alg
37
- this.type = EdDSASigner.type
38
- this.code = EdDSASigner.code
39
- this.did = DIDKey.fromPublicKey(EdDSASigner.type, this.publicKey)
50
+ constructor(did, privateKey) {
51
+ checkDid(did)
52
+ this.did = did.did
53
+ this.url = did.url
54
+ this.type = did.type
55
+ this.publicKey = did.publicKey
56
+ this.alg = did.alg
57
+ this.document = did.document
58
+ this.#privateKey = privateKey
59
+ this.didKey = DIDKey.fromPublicKey(this.type, this.publicKey).url.did
40
60
  }
41
61
 
42
62
  /**
@@ -47,19 +67,26 @@ export class EdDSASigner {
47
67
  static async generate(bytes) {
48
68
  const privateKey = bytes || utils.randomPrivateKey()
49
69
  const publicKey = await getPublicKeyAsync(privateKey)
50
- return new EdDSASigner(publicKey, privateKey)
70
+ return new EdDSASigner(
71
+ DIDKey.fromPublicKey('Ed25519', publicKey),
72
+ privateKey
73
+ )
51
74
  }
52
75
 
53
76
  /**
54
77
  * Import a signer from a encoded string
55
78
  *
56
79
  * @param {string} encoded
80
+ * @param {import('iso-did/types').VerifiableDID} [did]
57
81
  */
58
- static async import(encoded) {
82
+ static async import(encoded, did) {
59
83
  const privateKey = untag(EdDSASigner.code, base64pad.decode(encoded))
60
84
  const publicKey = await getPublicKeyAsync(privateKey)
61
85
 
62
- return new EdDSASigner(publicKey, privateKey)
86
+ return new EdDSASigner(
87
+ didKeyOrVerifiableDID('Ed25519', publicKey, did),
88
+ privateKey
89
+ )
63
90
  }
64
91
 
65
92
  /**
@@ -68,13 +95,17 @@ export class EdDSASigner {
68
95
  * @param {Uint8Array} message
69
96
  */
70
97
  async sign(message) {
71
- return signAsync(message, this.privateKey)
98
+ return signAsync(message, this.#privateKey)
72
99
  }
73
100
 
74
101
  /**
75
102
  * Export the signer as a encoded string
76
103
  */
77
104
  export() {
78
- return base64pad.encode(tag(EdDSASigner.code, this.privateKey))
105
+ return base64pad.encode(tag(EdDSASigner.code, this.#privateKey))
106
+ }
107
+
108
+ toString() {
109
+ return this.url.didUrl
79
110
  }
80
111
  }
@@ -3,11 +3,25 @@ import { webcrypto } from 'iso-base/crypto'
3
3
  import { u8 } from 'iso-base/utils'
4
4
  import { DIDKey } from 'iso-did/key'
5
5
  import { spki } from '../spki.js'
6
+ import { didKeyOrVerifiableDID } from '../utils.js'
6
7
 
7
8
  /**
8
9
  * @typedef {import('../types.js').ISigner<CryptoKeyPair>} ISigner
9
10
  */
10
11
 
12
+ /**
13
+ *
14
+ * @param {import('iso-did/types').VerifiableDID} did
15
+ */
16
+ function checkDid(did) {
17
+ if (did.type !== RSASigner.type) {
18
+ throw new TypeError(`Unsupported key type ${did.type}`)
19
+ }
20
+ if (did.alg !== RSASigner.alg) {
21
+ throw new TypeError(`Unsupported algorithm ${did.alg}`)
22
+ }
23
+ }
24
+
11
25
  /**
12
26
  * RSA signer
13
27
  *
@@ -23,17 +37,23 @@ export class RSASigner {
23
37
  // multicodec code for RSA private key
24
38
  static code = 0x1305
25
39
 
40
+ /** @type {CryptoKeyPair} */
41
+ #keypair
42
+
26
43
  /**
27
- * @param {Uint8Array} publicKey
44
+ * @param {import('iso-did/types').VerifiableDID} did
28
45
  * @param {CryptoKeyPair} keypair
29
46
  */
30
- constructor(publicKey, keypair) {
31
- this.keypair = keypair
32
- this.publicKey = publicKey
33
- this.alg = RSASigner.alg
34
- this.type = RSASigner.type
35
- this.code = RSASigner.code
36
- this.did = DIDKey.fromPublicKey(RSASigner.type, this.publicKey)
47
+ constructor(did, keypair) {
48
+ checkDid(did)
49
+ this.did = did.did
50
+ this.url = did.url
51
+ this.type = did.type
52
+ this.publicKey = did.publicKey
53
+ this.alg = did.alg
54
+ this.document = did.document
55
+ this.#keypair = keypair
56
+ this.didKey = DIDKey.fromPublicKey(this.type, this.publicKey).url.did
37
57
  }
38
58
 
39
59
  /**
@@ -56,16 +76,19 @@ export class RSASigner {
56
76
  'spki',
57
77
  cryptoKeyPair.publicKey
58
78
  )
59
-
60
- return new RSASigner(spki.decode(u8(publicKey)), cryptoKeyPair)
79
+ return new RSASigner(
80
+ DIDKey.fromPublicKey('RSA', spki.decode(u8(publicKey))),
81
+ cryptoKeyPair
82
+ )
61
83
  }
62
84
 
63
85
  /**
64
86
  * Import a signer from a JWK
65
87
  *
66
- * @param {import('../types.js').PrivateKeyRSAJwk} jwk
88
+ * @param {import('iso-did/types').RSAJWKPrivate} jwk
89
+ * @param {import('iso-did/types').VerifiableDID} [did]
67
90
  */
68
- static async importJwk(jwk) {
91
+ static async importJwk(jwk, did) {
69
92
  const privateKey = await webcrypto.subtle.importKey(
70
93
  'jwk',
71
94
  jwk,
@@ -88,8 +111,9 @@ export class RSASigner {
88
111
  )
89
112
 
90
113
  const publicKey = await webcrypto.subtle.exportKey('spki', publicKeyJWK)
114
+ const decodedPublicKey = spki.decode(u8(publicKey))
91
115
 
92
- return new RSASigner(spki.decode(u8(publicKey)), {
116
+ return new RSASigner(didKeyOrVerifiableDID('RSA', decodedPublicKey, did), {
93
117
  privateKey,
94
118
  publicKey: publicKeyJWK,
95
119
  })
@@ -99,14 +123,20 @@ export class RSASigner {
99
123
  * Import a signer from a keypair
100
124
  *
101
125
  * @param {CryptoKeyPair} keypair
126
+ * @param {import('iso-did/types').VerifiableDID} [did]
102
127
  */
103
- static async import(keypair) {
128
+ static async import(keypair, did) {
104
129
  const publicKey = await webcrypto.subtle.exportKey(
105
130
  'spki',
106
131
  keypair.publicKey
107
132
  )
108
133
 
109
- return new RSASigner(spki.decode(u8(publicKey)), keypair)
134
+ const decodedPublicKey = spki.decode(u8(publicKey))
135
+
136
+ return new RSASigner(
137
+ didKeyOrVerifiableDID('RSA', decodedPublicKey, did),
138
+ keypair
139
+ )
110
140
  }
111
141
 
112
142
  /**
@@ -117,7 +147,7 @@ export class RSASigner {
117
147
  async sign(message) {
118
148
  const buf = await webcrypto.subtle.sign(
119
149
  { name: 'RSASSA-PKCS1-v1_5', saltLength: 128 },
120
- this.keypair.privateKey,
150
+ this.#keypair.privateKey,
121
151
  message
122
152
  )
123
153
 
@@ -128,6 +158,10 @@ export class RSASigner {
128
158
  * Export the signer as a crypto key pair
129
159
  */
130
160
  export() {
131
- return this.keypair
161
+ return this.#keypair
162
+ }
163
+
164
+ toString() {
165
+ return this.url.didUrl
132
166
  }
133
167
  }
package/src/types.ts CHANGED
@@ -1,26 +1,13 @@
1
- import type { DIDKey } from 'iso-did/key'
2
- import type { KeyType, SignatureAlgorithm } from 'iso-did/types'
1
+ import type { SignatureAlgorithm, VerifiableDID } from 'iso-did/types'
3
2
 
4
- export interface ISigner<Export extends CryptoKeyPair | string> {
5
- /**
6
- * JWT signing algorithm
7
- */
8
- alg: SignatureAlgorithm
9
- /**
10
- * Keypair type
11
- */
12
- type: KeyType
13
- /**
14
- * Multicodec identifier for the private key
15
- */
16
- code?: number
17
-
18
- did: DIDKey
19
- /**
20
- * Sign a message
21
- */
3
+ export interface Sign {
22
4
  sign: (message: Uint8Array) => Promise<Uint8Array>
5
+ }
23
6
 
7
+ export interface ISigner<Export extends CryptoKeyPair | string>
8
+ extends VerifiableDID,
9
+ Sign {
10
+ code?: number
24
11
  export: () => Export
25
12
  }
26
13
 
@@ -49,27 +36,3 @@ export interface IResolver {
49
36
  export interface ResolverOptions {
50
37
  cache?: Cache | boolean | undefined
51
38
  }
52
-
53
- export interface PublicKeyJwk {
54
- kty: string
55
- crv: string
56
- x: string
57
- y: string
58
- }
59
-
60
- export interface PublicKeyRSAJwk {
61
- kty: string
62
- n: string
63
- e: string
64
- }
65
-
66
- export interface PrivateKeyRSAJwk extends PublicKeyRSAJwk {
67
- d: string
68
- p: string
69
- q: string
70
- dp: string
71
- dq: string
72
- qi: string
73
- }
74
-
75
- export type PrivateKeyJwk = PublicKeyJwk & { d: string }
package/src/utils.js CHANGED
@@ -1,3 +1,6 @@
1
+ import { DIDKey } from 'iso-did/key'
2
+ import { equals, u8 } from 'iso-base/utils'
3
+
1
4
  /**
2
5
  * Create web crypto params for ECDSA.
3
6
  *
@@ -33,3 +36,30 @@ export function createEcdsaParams(alg) {
33
36
  }
34
37
  }
35
38
  }
39
+
40
+ /**
41
+ *
42
+ * @param {import('iso-did/types').KeyType} type
43
+ * @param {BufferSource} publicKey
44
+ * @param {import('iso-did/types').VerifiableDID} [did]
45
+ */
46
+ export function didKeyOrVerifiableDID(type, publicKey, did) {
47
+ /** @type {import('iso-did/types').VerifiableDID} */
48
+ let _did = DIDKey.fromPublicKey(type, u8(publicKey))
49
+ if (did) {
50
+ if (!equals(did.publicKey, _did.publicKey)) {
51
+ throw new Error('Public key mismatch')
52
+ }
53
+
54
+ if (did.alg !== _did.alg) {
55
+ throw new Error('Algorithm mismatch')
56
+ }
57
+
58
+ if (did.type !== _did.type) {
59
+ throw new Error('Key type mismatch')
60
+ }
61
+ _did = did
62
+ }
63
+
64
+ return _did
65
+ }