forked from ceramicnetwork/js-ceramic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsecp256r1.ts
79 lines (71 loc) · 2.5 KB
/
secp256r1.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Brent Shambaugh <brent.shambaugh@gmail.com>. 2021.
import * as u8a from 'uint8arrays'
import * as nist_weierstrauss from 'nist-weierstrauss'
import {base64urlPoint} from 'nist-weierstrauss'
/**
* Constructs the document based on the method key
*/
export function keyToDidDoc(pubKeyBytes: Uint8Array, fingerprint: string): any {
const did = `did:key:${fingerprint}`
const keyId = `${did}#${fingerprint}`
const key = pubKeyBytesToXY(pubKeyBytes)
return {
id: did,
verificationMethod: [
{
id: keyId,
type: 'JsonWebKey2020',
controller: did,
publicKeyJwk: {
kty: 'EC',
crv: 'P-256',
x: key.xm,
y: key.ym,
},
},
],
authentication: [keyId],
assertionMethod: [keyId],
capabilityDelegation: [keyId],
capabilityInvocation: [keyId],
}
}
/**
*
* @param pubKeyBytes - public key as uncompressed byte array with no prefix (raw key),
* uncompressed with 0x04 prefix, or compressed with 0x02 prefix if even and 0x03 prefix if odd.
* @returns point x,y with coordinates as multibase encoded base64urls
*
* See the the did:key specification: https://w3c-ccg.github.io/did-method-key/#p-256.
* At present only raw p-256 keys are covered in the specification.
* @throws TypeError: input cannot be null or undefined.
* @throws Error: Unexpected pubKeyBytes
* @internal
*/
export function pubKeyBytesToXY(pubKeyBytes: Uint8Array) : base64urlPoint {
if(!nist_weierstrauss.nist_weierstrauss_common.testUint8Array(pubKeyBytes)) {
throw new TypeError('input must be a Uint8Array');
}
const publicKeyHex = nist_weierstrauss.nist_weierstrauss_common.pubKeyBytesToHex(pubKeyBytes);
const bytesCount = publicKeyHex.length / 2;
// raw p-256 key
if(bytesCount == 64) {
return nist_weierstrauss.nist_weierstrauss_common.publicKeyToXY(publicKeyHex);
}
// uncompressed p-256 key, SEC format
if(bytesCount == 65) {
if(publicKeyHex.slice(0,2) == '04') {
const publicKey = publicKeyHex.slice(2);
return nist_weierstrauss.nist_weierstrauss_common.publicKeyToXY(publicKey);
}
}
// compressed p-256 key, SEC format
if(bytesCount == 33) {
if(publicKeyHex.slice(0,2) == '03' || publicKeyHex.slice(0,2) == '02') {
const publicKey = u8a.fromString(publicKeyHex,'base16')
const point = nist_weierstrauss.secp256r1.ECPointDecompress(publicKey);
return nist_weierstrauss.nist_weierstrauss_common.publicKeyIntToXY(point);
}
}
throw new Error('Unexpected pubKeyBytes')
}