UNPKG

@dfinity/identity

Version:

JavaScript and TypeScript library to manage identity with the Internet Computer

216 lines 9.8 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _Ed25519PublicKey_rawKey, _Ed25519PublicKey_derKey, _Ed25519KeyIdentity_publicKey, _Ed25519KeyIdentity_privateKey; Object.defineProperty(exports, "__esModule", { value: true }); exports.Ed25519KeyIdentity = exports.Ed25519PublicKey = void 0; const agent_1 = require("@dfinity/agent"); const agent_2 = require("@dfinity/agent"); const ed25519_1 = require("@noble/curves/ed25519"); function isObject(value) { return value !== null && typeof value === 'object'; } class Ed25519PublicKey { // `fromRaw` and `fromDer` should be used for instantiation, not this constructor. constructor(key) { _Ed25519PublicKey_rawKey.set(this, void 0); _Ed25519PublicKey_derKey.set(this, void 0); if (key.byteLength !== Ed25519PublicKey.RAW_KEY_LENGTH) { throw new Error('An Ed25519 public key must be exactly 32bytes long'); } __classPrivateFieldSet(this, _Ed25519PublicKey_rawKey, (0, agent_2.bufFromBufLike)(key), "f"); __classPrivateFieldSet(this, _Ed25519PublicKey_derKey, Ed25519PublicKey.derEncode(key), "f"); } /** * Construct Ed25519PublicKey from an existing PublicKey * @param {unknown} maybeKey - existing PublicKey, ArrayBuffer, DerEncodedPublicKey, or hex string * @returns {Ed25519PublicKey} Instance of Ed25519PublicKey */ static from(maybeKey) { if (typeof maybeKey === 'string') { const key = (0, agent_2.fromHex)(maybeKey); return this.fromRaw(key); } else if (isObject(maybeKey)) { const key = maybeKey; if (isObject(key) && Object.hasOwnProperty.call(key, '__derEncodedPublicKey__')) { return this.fromDer(key); } else if (ArrayBuffer.isView(key)) { const view = key; return this.fromRaw((0, agent_2.bufFromBufLike)(view.buffer)); } else if (key instanceof ArrayBuffer) { return this.fromRaw(key); } else if ('rawKey' in key) { return this.fromRaw(key.rawKey); } else if ('derKey' in key) { return this.fromDer(key.derKey); } else if ('toDer' in key) { return this.fromDer(key.toDer()); } } throw new Error('Cannot construct Ed25519PublicKey from the provided key.'); } static fromRaw(rawKey) { return new Ed25519PublicKey(rawKey); } static fromDer(derKey) { return new Ed25519PublicKey(this.derDecode(derKey)); } static derEncode(publicKey) { const key = (0, agent_2.wrapDER)(publicKey, agent_2.ED25519_OID).buffer; key.__derEncodedPublicKey__ = undefined; return key; } static derDecode(key) { const unwrapped = (0, agent_2.unwrapDER)(key, agent_2.ED25519_OID); if (unwrapped.length !== this.RAW_KEY_LENGTH) { throw new Error('An Ed25519 public key must be exactly 32bytes long'); } return (0, agent_2.bufFromBufLike)(unwrapped); } get rawKey() { return __classPrivateFieldGet(this, _Ed25519PublicKey_rawKey, "f"); } get derKey() { return __classPrivateFieldGet(this, _Ed25519PublicKey_derKey, "f"); } toDer() { return this.derKey; } toRaw() { return this.rawKey; } } exports.Ed25519PublicKey = Ed25519PublicKey; _Ed25519PublicKey_rawKey = new WeakMap(), _Ed25519PublicKey_derKey = new WeakMap(); // The length of Ed25519 public keys is always 32 bytes. Ed25519PublicKey.RAW_KEY_LENGTH = 32; /** * Ed25519KeyIdentity is an implementation of SignIdentity that uses Ed25519 keys. This class is used to sign and verify messages for an agent. */ class Ed25519KeyIdentity extends agent_2.SignIdentity { // `fromRaw` and `fromDer` should be used for instantiation, not this constructor. constructor(publicKey, privateKey) { super(); _Ed25519KeyIdentity_publicKey.set(this, void 0); _Ed25519KeyIdentity_privateKey.set(this, void 0); __classPrivateFieldSet(this, _Ed25519KeyIdentity_publicKey, Ed25519PublicKey.from(publicKey), "f"); __classPrivateFieldSet(this, _Ed25519KeyIdentity_privateKey, new Uint8Array(privateKey), "f"); } /** * Generate a new Ed25519KeyIdentity. * @param seed a 32-byte seed for the private key. If not provided, a random seed will be generated. * @returns Ed25519KeyIdentity */ static generate(seed) { if (seed && seed.length !== 32) { throw new Error('Ed25519 Seed needs to be 32 bytes long.'); } if (!seed) seed = ed25519_1.ed25519.utils.randomPrivateKey(); // Check if the seed is all zeros if ((0, agent_1.bufEquals)(seed, new Uint8Array(new Array(32).fill(0)))) { console.warn('Seed is all zeros. This is not a secure seed. Please provide a seed with sufficient entropy if this is a production environment.'); } const sk = new Uint8Array(32); for (let i = 0; i < 32; i++) sk[i] = new Uint8Array(seed)[i]; const pk = ed25519_1.ed25519.getPublicKey(sk); return Ed25519KeyIdentity.fromKeyPair(pk, sk); } static fromParsedJson(obj) { const [publicKeyDer, privateKeyRaw] = obj; return new Ed25519KeyIdentity(Ed25519PublicKey.fromDer((0, agent_2.fromHex)(publicKeyDer)), (0, agent_2.fromHex)(privateKeyRaw)); } static fromJSON(json) { const parsed = JSON.parse(json); if (Array.isArray(parsed)) { if (typeof parsed[0] === 'string' && typeof parsed[1] === 'string') { return this.fromParsedJson([parsed[0], parsed[1]]); } else { throw new Error('Deserialization error: JSON must have at least 2 items.'); } } throw new Error(`Deserialization error: Invalid JSON type for string: ${JSON.stringify(json)}`); } static fromKeyPair(publicKey, privateKey) { return new Ed25519KeyIdentity(Ed25519PublicKey.fromRaw(publicKey), privateKey); } static fromSecretKey(secretKey) { const publicKey = ed25519_1.ed25519.getPublicKey(new Uint8Array(secretKey)); return Ed25519KeyIdentity.fromKeyPair(publicKey, secretKey); } /** * Serialize this key to JSON. */ toJSON() { return [(0, agent_2.toHex)(__classPrivateFieldGet(this, _Ed25519KeyIdentity_publicKey, "f").toDer()), (0, agent_2.toHex)(__classPrivateFieldGet(this, _Ed25519KeyIdentity_privateKey, "f"))]; } /** * Return a copy of the key pair. */ getKeyPair() { return { secretKey: __classPrivateFieldGet(this, _Ed25519KeyIdentity_privateKey, "f"), publicKey: __classPrivateFieldGet(this, _Ed25519KeyIdentity_publicKey, "f"), }; } /** * Return the public key. */ getPublicKey() { return __classPrivateFieldGet(this, _Ed25519KeyIdentity_publicKey, "f"); } /** * Signs a blob of data, with this identity's private key. * @param challenge - challenge to sign with this identity's secretKey, producing a signature */ async sign(challenge) { const blob = new Uint8Array(challenge); // Some implementations of Ed25519 private keys append a public key to the end of the private key. We only want the private key. const signature = (0, agent_2.uint8ToBuf)(ed25519_1.ed25519.sign(blob, __classPrivateFieldGet(this, _Ed25519KeyIdentity_privateKey, "f").slice(0, 32))); // add { __signature__: void; } to the signature to make it compatible with the agent Object.defineProperty(signature, '__signature__', { enumerable: false, value: undefined, }); return signature; } /** * Verify * @param sig - signature to verify * @param msg - message to verify * @param pk - public key * @returns - true if the signature is valid, false otherwise */ static verify(sig, msg, pk) { const [signature, message, publicKey] = [sig, msg, pk].map(x => { if (typeof x === 'string') { x = (0, agent_2.fromHex)(x); } if (x instanceof Uint8Array) { x = (0, agent_2.bufFromBufLike)(x.buffer); } return new Uint8Array(x); }); return ed25519_1.ed25519.verify(signature, message, publicKey); } } exports.Ed25519KeyIdentity = Ed25519KeyIdentity; _Ed25519KeyIdentity_publicKey = new WeakMap(), _Ed25519KeyIdentity_privateKey = new WeakMap(); //# sourceMappingURL=ed25519.js.map