@astrox/identity 0.0.24 → 0.0.30
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/cjs/buffer.d.ts +10 -0
- package/lib/cjs/buffer.js +21 -0
- package/lib/cjs/buffer.js.map +1 -0
- package/lib/cjs/identity/delegation.d.ts +131 -0
- package/lib/cjs/identity/delegation.js +244 -0
- package/lib/cjs/identity/delegation.js.map +1 -0
- package/lib/cjs/identity/der.d.ts +35 -0
- package/lib/cjs/identity/der.js +178 -0
- package/lib/cjs/identity/der.js.map +1 -0
- package/lib/cjs/identity/ed25519.d.ts +45 -0
- package/lib/cjs/identity/ed25519.js +134 -0
- package/lib/cjs/identity/ed25519.js.map +1 -0
- package/lib/cjs/identity/secp256k1.d.ts +73 -0
- package/lib/cjs/identity/secp256k1.js +156 -0
- package/lib/cjs/identity/secp256k1.js.map +1 -0
- package/lib/cjs/identity/webauthn.d.ts +40 -0
- package/lib/cjs/identity/webauthn.js +205 -0
- package/lib/cjs/identity/webauthn.js.map +1 -0
- package/lib/cjs/index.d.ts +4 -0
- package/lib/cjs/index.js +18 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/esm/buffer.d.ts +10 -0
- package/lib/esm/buffer.js +16 -0
- package/lib/esm/buffer.js.map +1 -0
- package/lib/esm/identity/delegation.d.ts +131 -0
- package/lib/esm/identity/delegation.js +219 -0
- package/lib/esm/identity/delegation.js.map +1 -0
- package/lib/esm/identity/der.d.ts +35 -0
- package/lib/esm/identity/der.js +168 -0
- package/lib/esm/identity/der.js.map +1 -0
- package/lib/esm/identity/ed25519.d.ts +45 -0
- package/lib/esm/identity/ed25519.js +110 -0
- package/lib/esm/identity/ed25519.js.map +1 -0
- package/lib/esm/identity/secp256k1.d.ts +73 -0
- package/lib/esm/identity/secp256k1.js +148 -0
- package/lib/esm/identity/secp256k1.js.map +1 -0
- package/lib/esm/identity/webauthn.d.ts +40 -0
- package/lib/esm/identity/webauthn.js +178 -0
- package/lib/esm/identity/webauthn.js.map +1 -0
- package/lib/esm/index.d.ts +4 -0
- package/lib/esm/index.js +5 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/tsconfig-cjs.tsbuildinfo +2451 -0
- package/lib/tsconfig.tsbuildinfo +2441 -0
- package/package.json +20 -2
@@ -0,0 +1,45 @@
|
|
1
|
+
import { DerEncodedPublicKey, KeyPair, PublicKey, Signature, SignIdentity } from '@astrox/agent';
|
2
|
+
export declare class Ed25519PublicKey implements PublicKey {
|
3
|
+
static from(key: PublicKey): Ed25519PublicKey;
|
4
|
+
static fromRaw(rawKey: ArrayBuffer): Ed25519PublicKey;
|
5
|
+
static fromDer(derKey: DerEncodedPublicKey): Ed25519PublicKey;
|
6
|
+
private static RAW_KEY_LENGTH;
|
7
|
+
private static derEncode;
|
8
|
+
private static derDecode;
|
9
|
+
private readonly rawKey;
|
10
|
+
private readonly derKey;
|
11
|
+
private constructor();
|
12
|
+
toDer(): DerEncodedPublicKey;
|
13
|
+
toRaw(): ArrayBuffer;
|
14
|
+
}
|
15
|
+
export declare class Ed25519KeyIdentity extends SignIdentity {
|
16
|
+
protected _privateKey: ArrayBuffer;
|
17
|
+
static generate(seed?: Uint8Array): Ed25519KeyIdentity;
|
18
|
+
static fromParsedJson(obj: JsonnableEd25519KeyIdentity): Ed25519KeyIdentity;
|
19
|
+
static fromJSON(json: string): Ed25519KeyIdentity;
|
20
|
+
static fromKeyPair(publicKey: ArrayBuffer, privateKey: ArrayBuffer): Ed25519KeyIdentity;
|
21
|
+
static fromSecretKey(secretKey: ArrayBuffer): Ed25519KeyIdentity;
|
22
|
+
protected _publicKey: Ed25519PublicKey;
|
23
|
+
protected constructor(publicKey: PublicKey, _privateKey: ArrayBuffer);
|
24
|
+
/**
|
25
|
+
* Serialize this key to JSON.
|
26
|
+
*/
|
27
|
+
toJSON(): JsonnableEd25519KeyIdentity;
|
28
|
+
/**
|
29
|
+
* Return a copy of the key pair.
|
30
|
+
*/
|
31
|
+
getKeyPair(): KeyPair;
|
32
|
+
/**
|
33
|
+
* Return the public key.
|
34
|
+
*/
|
35
|
+
getPublicKey(): PublicKey;
|
36
|
+
/**
|
37
|
+
* Signs a blob of data, with this identity's private key.
|
38
|
+
* @param challenge - challenge to sign with this identity's secretKey, producing a signature
|
39
|
+
*/
|
40
|
+
sign(challenge: ArrayBuffer): Promise<Signature>;
|
41
|
+
}
|
42
|
+
declare type PublicKeyHex = string;
|
43
|
+
declare type SecretKeyHex = string;
|
44
|
+
export declare type JsonnableEd25519KeyIdentity = [PublicKeyHex, SecretKeyHex];
|
45
|
+
export {};
|
@@ -0,0 +1,134 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
+
}) : (function(o, m, k, k2) {
|
6
|
+
if (k2 === undefined) k2 = k;
|
7
|
+
o[k2] = m[k];
|
8
|
+
}));
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11
|
+
}) : function(o, v) {
|
12
|
+
o["default"] = v;
|
13
|
+
});
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
15
|
+
if (mod && mod.__esModule) return mod;
|
16
|
+
var result = {};
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18
|
+
__setModuleDefault(result, mod);
|
19
|
+
return result;
|
20
|
+
};
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
22
|
+
exports.Ed25519KeyIdentity = exports.Ed25519PublicKey = void 0;
|
23
|
+
const agent_1 = require("@astrox/agent");
|
24
|
+
const tweetnacl = __importStar(require("tweetnacl"));
|
25
|
+
const buffer_1 = require("../buffer");
|
26
|
+
const der_1 = require("./der");
|
27
|
+
class Ed25519PublicKey {
|
28
|
+
// `fromRaw` and `fromDer` should be used for instantiation, not this constructor.
|
29
|
+
constructor(key) {
|
30
|
+
this.rawKey = key;
|
31
|
+
this.derKey = Ed25519PublicKey.derEncode(key);
|
32
|
+
}
|
33
|
+
static from(key) {
|
34
|
+
return this.fromDer(key.toDer());
|
35
|
+
}
|
36
|
+
static fromRaw(rawKey) {
|
37
|
+
return new Ed25519PublicKey(rawKey);
|
38
|
+
}
|
39
|
+
static fromDer(derKey) {
|
40
|
+
return new Ed25519PublicKey(this.derDecode(derKey));
|
41
|
+
}
|
42
|
+
static derEncode(publicKey) {
|
43
|
+
return der_1.wrapDER(publicKey, der_1.ED25519_OID).buffer;
|
44
|
+
}
|
45
|
+
static derDecode(key) {
|
46
|
+
const unwrapped = der_1.unwrapDER(key, der_1.ED25519_OID);
|
47
|
+
if (unwrapped.length !== this.RAW_KEY_LENGTH) {
|
48
|
+
throw new Error('An Ed25519 public key must be exactly 32bytes long');
|
49
|
+
}
|
50
|
+
return unwrapped;
|
51
|
+
}
|
52
|
+
toDer() {
|
53
|
+
return this.derKey;
|
54
|
+
}
|
55
|
+
toRaw() {
|
56
|
+
return this.rawKey;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
exports.Ed25519PublicKey = Ed25519PublicKey;
|
60
|
+
// The length of Ed25519 public keys is always 32 bytes.
|
61
|
+
Ed25519PublicKey.RAW_KEY_LENGTH = 32;
|
62
|
+
class Ed25519KeyIdentity extends agent_1.SignIdentity {
|
63
|
+
// `fromRaw` and `fromDer` should be used for instantiation, not this constructor.
|
64
|
+
constructor(publicKey, _privateKey) {
|
65
|
+
super();
|
66
|
+
this._privateKey = _privateKey;
|
67
|
+
this._publicKey = Ed25519PublicKey.from(publicKey);
|
68
|
+
}
|
69
|
+
static generate(seed) {
|
70
|
+
if (seed && seed.length !== 32) {
|
71
|
+
throw new Error('Ed25519 Seed needs to be 32 bytes long.');
|
72
|
+
}
|
73
|
+
const { publicKey, secretKey } = seed === undefined ? tweetnacl.sign.keyPair() : tweetnacl.sign.keyPair.fromSeed(seed);
|
74
|
+
return new this(Ed25519PublicKey.fromRaw(publicKey), secretKey);
|
75
|
+
}
|
76
|
+
static fromParsedJson(obj) {
|
77
|
+
const [publicKeyDer, privateKeyRaw] = obj;
|
78
|
+
return new Ed25519KeyIdentity(Ed25519PublicKey.fromDer(buffer_1.fromHexString(publicKeyDer)), buffer_1.fromHexString(privateKeyRaw));
|
79
|
+
}
|
80
|
+
static fromJSON(json) {
|
81
|
+
const parsed = JSON.parse(json);
|
82
|
+
if (Array.isArray(parsed)) {
|
83
|
+
if (typeof parsed[0] === 'string' && typeof parsed[1] === 'string') {
|
84
|
+
return this.fromParsedJson([parsed[0], parsed[1]]);
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
throw new Error('Deserialization error: JSON must have at least 2 items.');
|
88
|
+
}
|
89
|
+
}
|
90
|
+
else if (typeof parsed === 'object' && parsed !== null) {
|
91
|
+
throw new Error('Deprecated JSON format for Ed25519 keys.');
|
92
|
+
}
|
93
|
+
throw new Error(`Deserialization error: Invalid JSON type for string: ${JSON.stringify(json)}`);
|
94
|
+
}
|
95
|
+
static fromKeyPair(publicKey, privateKey) {
|
96
|
+
return new Ed25519KeyIdentity(Ed25519PublicKey.fromRaw(publicKey), privateKey);
|
97
|
+
}
|
98
|
+
static fromSecretKey(secretKey) {
|
99
|
+
const keyPair = tweetnacl.sign.keyPair.fromSecretKey(new Uint8Array(secretKey));
|
100
|
+
return Ed25519KeyIdentity.fromKeyPair(keyPair.publicKey, keyPair.secretKey);
|
101
|
+
}
|
102
|
+
/**
|
103
|
+
* Serialize this key to JSON.
|
104
|
+
*/
|
105
|
+
toJSON() {
|
106
|
+
return [buffer_1.toHexString(this._publicKey.toDer()), buffer_1.toHexString(this._privateKey)];
|
107
|
+
}
|
108
|
+
/**
|
109
|
+
* Return a copy of the key pair.
|
110
|
+
*/
|
111
|
+
getKeyPair() {
|
112
|
+
return {
|
113
|
+
secretKey: this._privateKey,
|
114
|
+
publicKey: this._publicKey,
|
115
|
+
};
|
116
|
+
}
|
117
|
+
/**
|
118
|
+
* Return the public key.
|
119
|
+
*/
|
120
|
+
getPublicKey() {
|
121
|
+
return this._publicKey;
|
122
|
+
}
|
123
|
+
/**
|
124
|
+
* Signs a blob of data, with this identity's private key.
|
125
|
+
* @param challenge - challenge to sign with this identity's secretKey, producing a signature
|
126
|
+
*/
|
127
|
+
async sign(challenge) {
|
128
|
+
const blob = new Uint8Array(challenge);
|
129
|
+
const signature = tweetnacl.sign.detached(blob, new Uint8Array(this._privateKey)).buffer;
|
130
|
+
return signature;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
exports.Ed25519KeyIdentity = Ed25519KeyIdentity;
|
134
|
+
//# sourceMappingURL=ed25519.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ed25519.js","sourceRoot":"","sources":["../../../src/identity/ed25519.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,yCAAiG;AACjG,qDAAuC;AACvC,sCAAuD;AACvD,+BAAwD;AAExD,MAAa,gBAAgB;IA+B3B,kFAAkF;IAClF,YAAoB,GAAgB;QAClC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAChD,CAAC;IAlCM,MAAM,CAAC,IAAI,CAAC,GAAc;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACnC,CAAC;IAEM,MAAM,CAAC,OAAO,CAAC,MAAmB;QACvC,OAAO,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAEM,MAAM,CAAC,OAAO,CAAC,MAA2B;QAC/C,OAAO,IAAI,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,CAAC;IAKO,MAAM,CAAC,SAAS,CAAC,SAAsB;QAC7C,OAAO,aAAO,CAAC,SAAS,EAAE,iBAAW,CAAC,CAAC,MAA6B,CAAC;IACvE,CAAC;IAEO,MAAM,CAAC,SAAS,CAAC,GAAwB;QAC/C,MAAM,SAAS,GAAG,eAAS,CAAC,GAAG,EAAE,iBAAW,CAAC,CAAC;QAC9C,IAAI,SAAS,CAAC,MAAM,KAAK,IAAI,CAAC,cAAc,EAAE;YAC5C,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;SACvE;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAWM,KAAK;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;;AA3CH,4CA4CC;AA/BC,wDAAwD;AACzC,+BAAc,GAAG,EAAE,CAAC;AAgCrC,MAAa,kBAAmB,SAAQ,oBAAY;IA4ClD,kFAAkF;IAClF,YAAsB,SAAoB,EAAY,WAAwB;QAC5E,KAAK,EAAE,CAAC;QAD4C,gBAAW,GAAX,WAAW,CAAa;QAE5E,IAAI,CAAC,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;IA/CM,MAAM,CAAC,QAAQ,CAAC,IAAiB;QACtC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE;YAC9B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;SAC5D;QAED,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAC5B,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxF,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC;IAEM,MAAM,CAAC,cAAc,CAAC,GAAgC;QAC3D,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,GAAG,GAAG,CAAC;QAC1C,OAAO,IAAI,kBAAkB,CAC3B,gBAAgB,CAAC,OAAO,CAAC,sBAAa,CAAC,YAAY,CAAwB,CAAC,EAC5E,sBAAa,CAAC,aAAa,CAAC,CAC7B,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,QAAQ,CAAC,IAAY;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACzB,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE;gBAClE,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACpD;iBAAM;gBACL,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;aAC5E;SACF;aAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE;YACxD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;SAC7D;QACD,MAAM,IAAI,KAAK,CAAC,wDAAwD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClG,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,SAAsB,EAAE,UAAuB;QACvE,OAAO,IAAI,kBAAkB,CAAC,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAAC;IACjF,CAAC;IAEM,MAAM,CAAC,aAAa,CAAC,SAAsB;QAChD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QAChF,OAAO,kBAAkB,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC9E,CAAC;IAUD;;OAEG;IACI,MAAM;QACX,OAAO,CAAC,oBAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,EAAE,oBAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED;;OAEG;IACI,UAAU;QACf,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,WAAW;YAC3B,SAAS,EAAE,IAAI,CAAC,UAAU;SAC3B,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,YAAY;QACjB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,IAAI,CAAC,SAAsB;QACtC,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC;QACzF,OAAO,SAAsB,CAAC;IAChC,CAAC;CACF;AAnFD,gDAmFC"}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
import { DerEncodedPublicKey, KeyPair, Signature } from '@astrox/agent';
|
2
|
+
import { PublicKey, SignIdentity } from '@astrox/agent';
|
3
|
+
declare type PublicKeyHex = string;
|
4
|
+
declare type SecretKeyHex = string;
|
5
|
+
export declare type JsonableSecp256k1Identity = [PublicKeyHex, SecretKeyHex];
|
6
|
+
export declare class Secp256k1PublicKey implements PublicKey {
|
7
|
+
/**
|
8
|
+
* Construct Secp256k1PublicKey from an existing PublicKey
|
9
|
+
* @param {PublicKey} key
|
10
|
+
* @returns {Secp256k1PublicKey} Instance of Secp256k1PublicKey
|
11
|
+
*/
|
12
|
+
static from(key: PublicKey): Secp256k1PublicKey;
|
13
|
+
static fromRaw(rawKey: ArrayBuffer): Secp256k1PublicKey;
|
14
|
+
static fromDer(derKey: DerEncodedPublicKey): Secp256k1PublicKey;
|
15
|
+
private static derEncode;
|
16
|
+
private static derDecode;
|
17
|
+
private readonly rawKey;
|
18
|
+
private readonly derKey;
|
19
|
+
private constructor();
|
20
|
+
toDer(): DerEncodedPublicKey;
|
21
|
+
toRaw(): ArrayBuffer;
|
22
|
+
}
|
23
|
+
export declare class Secp256k1KeyIdentity extends SignIdentity {
|
24
|
+
protected _privateKey: ArrayBuffer;
|
25
|
+
/**
|
26
|
+
* Generates an identity. If a seed is provided, the keys are generated from the
|
27
|
+
* seed according to BIP 0032. Otherwise, the key pair is randomly generated.
|
28
|
+
* This method throws an error in case the seed is not 32 bytes long or invalid
|
29
|
+
* for use as a private key.
|
30
|
+
* @param {Uint8Array} seed the optional seed
|
31
|
+
* @returns {Secp256k1KeyIdentity}
|
32
|
+
*/
|
33
|
+
static generate(seed?: Uint8Array): Secp256k1KeyIdentity;
|
34
|
+
static fromParsedJson(obj: JsonableSecp256k1Identity): Secp256k1KeyIdentity;
|
35
|
+
static fromJSON(json: string): Secp256k1KeyIdentity;
|
36
|
+
/**
|
37
|
+
* generates an identity from a public and private key. Please ensure that you are generating these keys securely and protect the user's private key
|
38
|
+
* @param {ArrayBuffer} publicKey
|
39
|
+
* @param {ArrayBuffer} privateKey
|
40
|
+
* @returns {Secp256k1KeyIdentity}
|
41
|
+
*/
|
42
|
+
static fromKeyPair(publicKey: ArrayBuffer, privateKey: ArrayBuffer): Secp256k1KeyIdentity;
|
43
|
+
/**
|
44
|
+
* generates an identity from an existing secret key, and is the correct method to generate an identity from a seed phrase. Please ensure you protect the user's private key.
|
45
|
+
* @param {ArrayBuffer} secretKey
|
46
|
+
* @returns {Secp256k1KeyIdentity}
|
47
|
+
*/
|
48
|
+
static fromSecretKey(secretKey: ArrayBuffer): Secp256k1KeyIdentity;
|
49
|
+
protected _publicKey: Secp256k1PublicKey;
|
50
|
+
protected constructor(publicKey: Secp256k1PublicKey, _privateKey: ArrayBuffer);
|
51
|
+
/**
|
52
|
+
* Serialize this key to JSON-serializable object.
|
53
|
+
* @returns {JsonableSecp256k1Identity}
|
54
|
+
*/
|
55
|
+
toJSON(): JsonableSecp256k1Identity;
|
56
|
+
/**
|
57
|
+
* Return a copy of the key pair.
|
58
|
+
* @returns {KeyPair}
|
59
|
+
*/
|
60
|
+
getKeyPair(): KeyPair;
|
61
|
+
/**
|
62
|
+
* Return the public key.
|
63
|
+
* @returns {Secp256k1PublicKey}
|
64
|
+
*/
|
65
|
+
getPublicKey(): Secp256k1PublicKey;
|
66
|
+
/**
|
67
|
+
* Signs a blob of data, with this identity's private key.
|
68
|
+
* @param {ArrayBuffer} challenge - challenge to sign with this identity's secretKey, producing a signature
|
69
|
+
* @returns {Promise<Signature>} signature
|
70
|
+
*/
|
71
|
+
sign(challenge: ArrayBuffer): Promise<Signature>;
|
72
|
+
}
|
73
|
+
export default Secp256k1KeyIdentity;
|
@@ -0,0 +1,156 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.Secp256k1KeyIdentity = exports.Secp256k1PublicKey = void 0;
|
7
|
+
const agent_1 = require("@astrox/agent");
|
8
|
+
const js_sha256_1 = require("js-sha256");
|
9
|
+
const secp256k1_1 = __importDefault(require("secp256k1"));
|
10
|
+
const tweetnacl_1 = require("tweetnacl");
|
11
|
+
const buffer_1 = require("../buffer");
|
12
|
+
const der_1 = require("./der");
|
13
|
+
class Secp256k1PublicKey {
|
14
|
+
// `fromRaw` and `fromDer` should be used for instantiation, not this constructor.
|
15
|
+
constructor(key) {
|
16
|
+
key.byteLength;
|
17
|
+
this.rawKey = key;
|
18
|
+
this.derKey = Secp256k1PublicKey.derEncode(key);
|
19
|
+
}
|
20
|
+
/**
|
21
|
+
* Construct Secp256k1PublicKey from an existing PublicKey
|
22
|
+
* @param {PublicKey} key
|
23
|
+
* @returns {Secp256k1PublicKey} Instance of Secp256k1PublicKey
|
24
|
+
*/
|
25
|
+
static from(key) {
|
26
|
+
return this.fromDer(key.toDer());
|
27
|
+
}
|
28
|
+
static fromRaw(rawKey) {
|
29
|
+
return new Secp256k1PublicKey(rawKey);
|
30
|
+
}
|
31
|
+
static fromDer(derKey) {
|
32
|
+
return new Secp256k1PublicKey(this.derDecode(derKey));
|
33
|
+
}
|
34
|
+
static derEncode(publicKey) {
|
35
|
+
return der_1.wrapDER(publicKey, der_1.SECP256K1_OID).buffer;
|
36
|
+
}
|
37
|
+
static derDecode(key) {
|
38
|
+
return der_1.unwrapDER(key, der_1.SECP256K1_OID);
|
39
|
+
}
|
40
|
+
toDer() {
|
41
|
+
return this.derKey;
|
42
|
+
}
|
43
|
+
toRaw() {
|
44
|
+
return this.rawKey;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
exports.Secp256k1PublicKey = Secp256k1PublicKey;
|
48
|
+
class Secp256k1KeyIdentity extends agent_1.SignIdentity {
|
49
|
+
constructor(publicKey, _privateKey) {
|
50
|
+
super();
|
51
|
+
this._privateKey = _privateKey;
|
52
|
+
this._publicKey = publicKey;
|
53
|
+
}
|
54
|
+
/**
|
55
|
+
* Generates an identity. If a seed is provided, the keys are generated from the
|
56
|
+
* seed according to BIP 0032. Otherwise, the key pair is randomly generated.
|
57
|
+
* This method throws an error in case the seed is not 32 bytes long or invalid
|
58
|
+
* for use as a private key.
|
59
|
+
* @param {Uint8Array} seed the optional seed
|
60
|
+
* @returns {Secp256k1KeyIdentity}
|
61
|
+
*/
|
62
|
+
static generate(seed) {
|
63
|
+
if (seed && seed.byteLength !== 32) {
|
64
|
+
throw new Error('Secp256k1 Seed needs to be 32 bytes long.');
|
65
|
+
}
|
66
|
+
let privateKey;
|
67
|
+
if (seed) {
|
68
|
+
// private key from seed according to https://en.bitcoin.it/wiki/BIP_0032
|
69
|
+
// master key generation:
|
70
|
+
privateKey = seed;
|
71
|
+
if (!secp256k1_1.default.privateKeyVerify(privateKey)) {
|
72
|
+
throw new Error('The seed is invalid.');
|
73
|
+
}
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
privateKey = new Uint8Array(tweetnacl_1.randomBytes(32));
|
77
|
+
while (!secp256k1_1.default.privateKeyVerify(privateKey)) {
|
78
|
+
privateKey = new Uint8Array(tweetnacl_1.randomBytes(32));
|
79
|
+
}
|
80
|
+
}
|
81
|
+
const publicKeyRaw = secp256k1_1.default.publicKeyCreate(privateKey, false);
|
82
|
+
const publicKey = Secp256k1PublicKey.fromRaw(publicKeyRaw);
|
83
|
+
return new this(publicKey, privateKey);
|
84
|
+
}
|
85
|
+
static fromParsedJson(obj) {
|
86
|
+
const [publicKeyRaw, privateKeyRaw] = obj;
|
87
|
+
return new Secp256k1KeyIdentity(Secp256k1PublicKey.fromRaw(buffer_1.fromHexString(publicKeyRaw)), buffer_1.fromHexString(privateKeyRaw));
|
88
|
+
}
|
89
|
+
static fromJSON(json) {
|
90
|
+
const parsed = JSON.parse(json);
|
91
|
+
if (Array.isArray(parsed)) {
|
92
|
+
if (typeof parsed[0] === 'string' && typeof parsed[1] === 'string') {
|
93
|
+
return this.fromParsedJson([parsed[0], parsed[1]]);
|
94
|
+
}
|
95
|
+
throw new Error('Deserialization error: JSON must have at least 2 items.');
|
96
|
+
}
|
97
|
+
throw new Error(`Deserialization error: Invalid JSON type for string: ${JSON.stringify(json)}`);
|
98
|
+
}
|
99
|
+
/**
|
100
|
+
* generates an identity from a public and private key. Please ensure that you are generating these keys securely and protect the user's private key
|
101
|
+
* @param {ArrayBuffer} publicKey
|
102
|
+
* @param {ArrayBuffer} privateKey
|
103
|
+
* @returns {Secp256k1KeyIdentity}
|
104
|
+
*/
|
105
|
+
static fromKeyPair(publicKey, privateKey) {
|
106
|
+
return new Secp256k1KeyIdentity(Secp256k1PublicKey.fromRaw(publicKey), privateKey);
|
107
|
+
}
|
108
|
+
/**
|
109
|
+
* generates an identity from an existing secret key, and is the correct method to generate an identity from a seed phrase. Please ensure you protect the user's private key.
|
110
|
+
* @param {ArrayBuffer} secretKey
|
111
|
+
* @returns {Secp256k1KeyIdentity}
|
112
|
+
*/
|
113
|
+
static fromSecretKey(secretKey) {
|
114
|
+
const publicKey = secp256k1_1.default.publicKeyCreate(new Uint8Array(secretKey), false);
|
115
|
+
const identity = Secp256k1KeyIdentity.fromKeyPair(publicKey, new Uint8Array(secretKey));
|
116
|
+
return identity;
|
117
|
+
}
|
118
|
+
/**
|
119
|
+
* Serialize this key to JSON-serializable object.
|
120
|
+
* @returns {JsonableSecp256k1Identity}
|
121
|
+
*/
|
122
|
+
toJSON() {
|
123
|
+
return [buffer_1.toHexString(this._publicKey.toRaw()), buffer_1.toHexString(this._privateKey)];
|
124
|
+
}
|
125
|
+
/**
|
126
|
+
* Return a copy of the key pair.
|
127
|
+
* @returns {KeyPair}
|
128
|
+
*/
|
129
|
+
getKeyPair() {
|
130
|
+
return {
|
131
|
+
secretKey: this._privateKey,
|
132
|
+
publicKey: this._publicKey,
|
133
|
+
};
|
134
|
+
}
|
135
|
+
/**
|
136
|
+
* Return the public key.
|
137
|
+
* @returns {Secp256k1PublicKey}
|
138
|
+
*/
|
139
|
+
getPublicKey() {
|
140
|
+
return this._publicKey;
|
141
|
+
}
|
142
|
+
/**
|
143
|
+
* Signs a blob of data, with this identity's private key.
|
144
|
+
* @param {ArrayBuffer} challenge - challenge to sign with this identity's secretKey, producing a signature
|
145
|
+
* @returns {Promise<Signature>} signature
|
146
|
+
*/
|
147
|
+
async sign(challenge) {
|
148
|
+
const hash = js_sha256_1.sha256.create();
|
149
|
+
hash.update(challenge);
|
150
|
+
const signature = secp256k1_1.default.ecdsaSign(new Uint8Array(hash.digest()), new Uint8Array(this._privateKey)).signature.buffer;
|
151
|
+
return signature;
|
152
|
+
}
|
153
|
+
}
|
154
|
+
exports.Secp256k1KeyIdentity = Secp256k1KeyIdentity;
|
155
|
+
exports.default = Secp256k1KeyIdentity;
|
156
|
+
//# sourceMappingURL=secp256k1.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"secp256k1.js","sourceRoot":"","sources":["../../../src/identity/secp256k1.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { DerEncodedPublicKey, PublicKey, Signature, SignIdentity } from '@astrox/agent';
|
2
|
+
export declare class CosePublicKey implements PublicKey {
|
3
|
+
protected _cose: ArrayBuffer;
|
4
|
+
protected _encodedKey: DerEncodedPublicKey;
|
5
|
+
constructor(_cose: ArrayBuffer);
|
6
|
+
toDer(): DerEncodedPublicKey;
|
7
|
+
getCose(): ArrayBuffer;
|
8
|
+
}
|
9
|
+
/**
|
10
|
+
* A SignIdentity that uses `navigator.credentials`. See https://webauthn.guide/ for
|
11
|
+
* more information about WebAuthentication.
|
12
|
+
*/
|
13
|
+
export declare class WebAuthnIdentity extends SignIdentity {
|
14
|
+
readonly rawId: ArrayBuffer;
|
15
|
+
/**
|
16
|
+
* Create an identity from a JSON serialization.
|
17
|
+
* @param json - json to parse
|
18
|
+
*/
|
19
|
+
static fromJSON(json: string): WebAuthnIdentity;
|
20
|
+
/**
|
21
|
+
* Create an identity.
|
22
|
+
* @param credentialCreationOptions an optional CredentialCreationOptions Challenge
|
23
|
+
*/
|
24
|
+
static create(credentialCreationOptions?: CredentialCreationOptions): Promise<WebAuthnIdentity>;
|
25
|
+
protected _publicKey: CosePublicKey;
|
26
|
+
protected constructor(rawId: ArrayBuffer, cose: ArrayBuffer);
|
27
|
+
getPublicKey(): PublicKey;
|
28
|
+
sign(blob: ArrayBuffer): Promise<Signature>;
|
29
|
+
/**
|
30
|
+
* Allow for JSON serialization of all information needed to reuse this identity.
|
31
|
+
*/
|
32
|
+
toJSON(): JsonnableWebAuthnIdentitiy;
|
33
|
+
}
|
34
|
+
/**
|
35
|
+
* ReturnType<WebAuthnIdentity.toJSON>
|
36
|
+
*/
|
37
|
+
export interface JsonnableWebAuthnIdentitiy {
|
38
|
+
publicKey: string;
|
39
|
+
rawId: string;
|
40
|
+
}
|
@@ -0,0 +1,205 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
+
}) : (function(o, m, k, k2) {
|
6
|
+
if (k2 === undefined) k2 = k;
|
7
|
+
o[k2] = m[k];
|
8
|
+
}));
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11
|
+
}) : function(o, v) {
|
12
|
+
o["default"] = v;
|
13
|
+
});
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
15
|
+
if (mod && mod.__esModule) return mod;
|
16
|
+
var result = {};
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18
|
+
__setModuleDefault(result, mod);
|
19
|
+
return result;
|
20
|
+
};
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
23
|
+
};
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
25
|
+
exports.WebAuthnIdentity = exports.CosePublicKey = void 0;
|
26
|
+
const agent_1 = require("@astrox/agent");
|
27
|
+
const borc_1 = __importDefault(require("borc"));
|
28
|
+
const tweetnacl = __importStar(require("tweetnacl"));
|
29
|
+
const buffer_1 = require("../buffer");
|
30
|
+
const der_1 = require("./der");
|
31
|
+
function _coseToDerEncodedBlob(cose) {
|
32
|
+
return der_1.wrapDER(cose, der_1.DER_COSE_OID).buffer;
|
33
|
+
}
|
34
|
+
/**
|
35
|
+
* From the documentation;
|
36
|
+
* The authData is a byte array described in the spec. Parsing it will involve slicing bytes from
|
37
|
+
* the array and converting them into usable objects.
|
38
|
+
*
|
39
|
+
* See https://webauthn.guide/#registration (subsection "Example: Parsing the authenticator data").
|
40
|
+
*
|
41
|
+
* @param authData The authData field of the attestation response.
|
42
|
+
* @returns The COSE key of the authData.
|
43
|
+
*/
|
44
|
+
function _authDataToCose(authData) {
|
45
|
+
const dataView = new DataView(new ArrayBuffer(2));
|
46
|
+
const idLenBytes = authData.slice(53, 55);
|
47
|
+
[...new Uint8Array(idLenBytes)].forEach((v, i) => dataView.setUint8(i, v));
|
48
|
+
const credentialIdLength = dataView.getUint16(0);
|
49
|
+
// Get the public key object.
|
50
|
+
return authData.slice(55 + credentialIdLength);
|
51
|
+
}
|
52
|
+
class CosePublicKey {
|
53
|
+
constructor(_cose) {
|
54
|
+
this._cose = _cose;
|
55
|
+
this._encodedKey = _coseToDerEncodedBlob(_cose);
|
56
|
+
}
|
57
|
+
toDer() {
|
58
|
+
return this._encodedKey;
|
59
|
+
}
|
60
|
+
getCose() {
|
61
|
+
return this._cose;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
exports.CosePublicKey = CosePublicKey;
|
65
|
+
/**
|
66
|
+
* Create a challenge from a string or array. The default challenge is always the same
|
67
|
+
* because we don't need to verify the authenticity of the key on the server (we don't
|
68
|
+
* register our keys with the IC). Any challenge would do, even one per key, randomly
|
69
|
+
* generated.
|
70
|
+
*
|
71
|
+
* @param challenge The challenge to transform into a byte array. By default a hard
|
72
|
+
* coded string.
|
73
|
+
*/
|
74
|
+
function _createChallengeBuffer(challenge = '<ic0.app>') {
|
75
|
+
if (typeof challenge === 'string') {
|
76
|
+
return Uint8Array.from(challenge, c => c.charCodeAt(0));
|
77
|
+
}
|
78
|
+
else {
|
79
|
+
return challenge;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
/**
|
83
|
+
* Create a credentials to authenticate with a server. This is necessary in order in
|
84
|
+
* WebAuthn to get credentials IDs (which give us the public key and allow us to
|
85
|
+
* sign), but in the case of the Internet Computer, we don't actually need to register
|
86
|
+
* it, so we don't.
|
87
|
+
* @param credentialCreationOptions an optional CredentialCreationOptions object
|
88
|
+
*/
|
89
|
+
async function _createCredential(credentialCreationOptions) {
|
90
|
+
const creds = (await navigator.credentials.create(credentialCreationOptions !== null && credentialCreationOptions !== void 0 ? credentialCreationOptions : {
|
91
|
+
publicKey: {
|
92
|
+
authenticatorSelection: {
|
93
|
+
userVerification: 'preferred',
|
94
|
+
},
|
95
|
+
attestation: 'direct',
|
96
|
+
challenge: _createChallengeBuffer(),
|
97
|
+
pubKeyCredParams: [{ type: 'public-key', alg: PubKeyCoseAlgo.ECDSA_WITH_SHA256 }],
|
98
|
+
rp: {
|
99
|
+
name: 'Internet Identity Service',
|
100
|
+
},
|
101
|
+
user: {
|
102
|
+
id: tweetnacl.randomBytes(16),
|
103
|
+
name: 'Internet Identity',
|
104
|
+
displayName: 'Internet Identity',
|
105
|
+
},
|
106
|
+
},
|
107
|
+
}));
|
108
|
+
// Validate that it's the correct type at runtime, since WebAuthn does not HAVE to
|
109
|
+
// reply with a PublicKeyCredential.
|
110
|
+
if (creds.response === undefined || !(creds.rawId instanceof ArrayBuffer)) {
|
111
|
+
return null;
|
112
|
+
}
|
113
|
+
else {
|
114
|
+
return creds;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
// See https://www.iana.org/assignments/cose/cose.xhtml#algorithms for a complete
|
118
|
+
// list of these algorithms. We only list the ones we support here.
|
119
|
+
var PubKeyCoseAlgo;
|
120
|
+
(function (PubKeyCoseAlgo) {
|
121
|
+
PubKeyCoseAlgo[PubKeyCoseAlgo["ECDSA_WITH_SHA256"] = -7] = "ECDSA_WITH_SHA256";
|
122
|
+
})(PubKeyCoseAlgo || (PubKeyCoseAlgo = {}));
|
123
|
+
/**
|
124
|
+
* A SignIdentity that uses `navigator.credentials`. See https://webauthn.guide/ for
|
125
|
+
* more information about WebAuthentication.
|
126
|
+
*/
|
127
|
+
class WebAuthnIdentity extends agent_1.SignIdentity {
|
128
|
+
constructor(rawId, cose) {
|
129
|
+
super();
|
130
|
+
this.rawId = rawId;
|
131
|
+
this._publicKey = new CosePublicKey(cose);
|
132
|
+
}
|
133
|
+
/**
|
134
|
+
* Create an identity from a JSON serialization.
|
135
|
+
* @param json - json to parse
|
136
|
+
*/
|
137
|
+
static fromJSON(json) {
|
138
|
+
const { publicKey, rawId } = JSON.parse(json);
|
139
|
+
if (typeof publicKey !== 'string' || typeof rawId !== 'string') {
|
140
|
+
throw new Error('Invalid JSON string.');
|
141
|
+
}
|
142
|
+
return new this(buffer_1.fromHexString(rawId), buffer_1.fromHexString(publicKey));
|
143
|
+
}
|
144
|
+
/**
|
145
|
+
* Create an identity.
|
146
|
+
* @param credentialCreationOptions an optional CredentialCreationOptions Challenge
|
147
|
+
*/
|
148
|
+
static async create(credentialCreationOptions) {
|
149
|
+
const creds = await _createCredential(credentialCreationOptions);
|
150
|
+
if (!creds || creds.type !== 'public-key') {
|
151
|
+
throw new Error('Could not create credentials.');
|
152
|
+
}
|
153
|
+
const response = creds.response;
|
154
|
+
if (!(response.attestationObject instanceof ArrayBuffer)) {
|
155
|
+
throw new Error('Was expecting an attestation response.');
|
156
|
+
}
|
157
|
+
// Parse the attestationObject as CBOR.
|
158
|
+
const attObject = borc_1.default.decodeFirst(new Uint8Array(response.attestationObject));
|
159
|
+
return new this(creds.rawId, _authDataToCose(attObject.authData));
|
160
|
+
}
|
161
|
+
getPublicKey() {
|
162
|
+
return this._publicKey;
|
163
|
+
}
|
164
|
+
async sign(blob) {
|
165
|
+
const result = (await navigator.credentials.get({
|
166
|
+
publicKey: {
|
167
|
+
allowCredentials: [
|
168
|
+
{
|
169
|
+
type: 'public-key',
|
170
|
+
id: this.rawId,
|
171
|
+
},
|
172
|
+
],
|
173
|
+
challenge: blob,
|
174
|
+
userVerification: 'preferred',
|
175
|
+
},
|
176
|
+
}));
|
177
|
+
const response = result.response;
|
178
|
+
if (response.signature instanceof ArrayBuffer &&
|
179
|
+
response.authenticatorData instanceof ArrayBuffer) {
|
180
|
+
const cbor = borc_1.default.encode(new borc_1.default.Tagged(55799, {
|
181
|
+
authenticator_data: new Uint8Array(response.authenticatorData),
|
182
|
+
client_data_json: new TextDecoder().decode(response.clientDataJSON),
|
183
|
+
signature: new Uint8Array(response.signature),
|
184
|
+
}));
|
185
|
+
if (!cbor) {
|
186
|
+
throw new Error('failed to encode cbor');
|
187
|
+
}
|
188
|
+
return cbor.buffer;
|
189
|
+
}
|
190
|
+
else {
|
191
|
+
throw new Error('Invalid response from WebAuthn.');
|
192
|
+
}
|
193
|
+
}
|
194
|
+
/**
|
195
|
+
* Allow for JSON serialization of all information needed to reuse this identity.
|
196
|
+
*/
|
197
|
+
toJSON() {
|
198
|
+
return {
|
199
|
+
publicKey: buffer_1.toHexString(this._publicKey.getCose()),
|
200
|
+
rawId: buffer_1.toHexString(this.rawId),
|
201
|
+
};
|
202
|
+
}
|
203
|
+
}
|
204
|
+
exports.WebAuthnIdentity = WebAuthnIdentity;
|
205
|
+
//# sourceMappingURL=webauthn.js.map
|