Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

did-jwt

Package Overview
Dependencies
Maintainers
8
Versions
142
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

did-jwt - npm Package Compare versions

Comparing version 5.10.0 to 5.11.0

lib/blockchains/bip122.d.ts

249

lib/index.modern.js

@@ -8,2 +8,3 @@ import * as u8a from 'uint8arrays';

import canonicalizeData from 'canonicalize';
import { bech32 } from 'bech32';
import { sharedKey, generateKeyPair } from '@stablelib/x25519';

@@ -23,2 +24,5 @@ import { XChaCha20Poly1305 } from '@stablelib/xchacha20poly1305';

}
function bytesToBase58(b) {
return u8a.toString(b, 'base58btc');
}
function hexToBytes(s) {

@@ -340,2 +344,237 @@ const input = s.startsWith('0x') ? s.substring(2) : s;

// https://github.com/crypto-browserify/ripemd160/blob/master/index.js
const zl = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13];
const zr = [5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11];
const sl = [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6];
const sr = [8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11];
const hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e];
const hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000];
function rotl(x, n) {
return x << n | x >>> 32 - n;
}
function fn1(a, b, c, d, e, m, k, s) {
return rotl(a + (b ^ c ^ d) + m + k | 0, s) + e | 0;
}
function fn2(a, b, c, d, e, m, k, s) {
return rotl(a + (b & c | ~b & d) + m + k | 0, s) + e | 0;
}
function fn3(a, b, c, d, e, m, k, s) {
return rotl(a + ((b | ~c) ^ d) + m + k | 0, s) + e | 0;
}
function fn4(a, b, c, d, e, m, k, s) {
return rotl(a + (b & d | c & ~d) + m + k | 0, s) + e | 0;
}
function fn5(a, b, c, d, e, m, k, s) {
return rotl(a + (b ^ (c | ~d)) + m + k | 0, s) + e | 0;
}
class Ripemd160 {
// state
constructor(blockSize = 64) {
this._a = 0x67452301;
this._b = 0xefcdab89;
this._c = 0x98badcfe;
this._d = 0x10325476;
this._e = 0xc3d2e1f0;
this._blockOffset = 0;
this._block = void 0;
this._blockSize = void 0;
this._length = [0, 0, 0, 0];
this._finalized = void 0;
this.update = data => {
if (this._finalized) throw new Error('Digest already called'); // consume data
const block = this._block;
let offset = 0;
while (this._blockOffset + data.length - offset >= this._blockSize) {
for (let i = this._blockOffset; i < this._blockSize;) block[i++] = data[offset++];
this._update();
this._blockOffset = 0;
}
while (offset < data.length) block[this._blockOffset++] = data[offset++]; // update length
for (let j = 0, carry = data.length * 8; carry > 0; ++j) {
this._length[j] += carry;
carry = this._length[j] / 0x0100000000 | 0;
if (carry > 0) this._length[j] -= 0x0100000000 * carry;
}
return this;
};
this.digest = () => {
if (this._finalized) throw new Error('Digest already called');
this._finalized = true;
const digest = this._digest(); // reset state
this._block.fill(0);
this._blockOffset = 0;
for (let i = 0; i < 4; ++i) this._length[i] = 0;
return digest;
};
this._update = () => {
const words = new Array(16);
const temp = new DataView(this._block.buffer);
for (let j = 0; j < 16; ++j) words[j] = words[j] = temp.getInt32(j * 4, true);
let al = this._a | 0;
let bl = this._b | 0;
let cl = this._c | 0;
let dl = this._d | 0;
let el = this._e | 0;
let ar = this._a | 0;
let br = this._b | 0;
let cr = this._c | 0;
let dr = this._d | 0;
let er = this._e | 0; // computation
for (let i = 0; i < 80; i += 1) {
let tl;
let tr;
if (i < 16) {
tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i]);
tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i]);
} else if (i < 32) {
tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i]);
tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i]);
} else if (i < 48) {
tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i]);
tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i]);
} else if (i < 64) {
tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i]);
tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i]);
} else {
// if (i<80) {
tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i]);
tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i]);
}
al = el;
el = dl;
dl = rotl(cl, 10);
cl = bl;
bl = tl;
ar = er;
er = dr;
dr = rotl(cr, 10);
cr = br;
br = tr;
} // update state
const t = this._b + cl + dr | 0;
this._b = this._c + dl + er | 0;
this._c = this._d + el + ar | 0;
this._d = this._e + al + br | 0;
this._e = this._a + bl + cr | 0;
this._a = t;
};
this._digest = () => {
// create padding and handle blocks
this._block[this._blockOffset++] = 0x80;
if (this._blockOffset > 56) {
this._block.fill(0, this._blockOffset, 64);
this._update();
this._blockOffset = 0;
}
this._block.fill(0, this._blockOffset, 56);
const temp = new DataView(this._block.buffer);
temp.setUint32(56, this._length[0], true);
temp.setUint32(60, this._length[1], true);
this._block = new Uint8Array(temp.buffer);
this._update(); // produce result
const buffer = new DataView(new Uint8Array(20).buffer);
buffer.setInt32(0, this._a, true);
buffer.setInt32(4, this._b, true);
buffer.setInt32(8, this._c, true);
buffer.setInt32(12, this._d, true);
buffer.setInt32(16, this._e, true);
return new Uint8Array(buffer.buffer);
};
this._block = new Uint8Array(blockSize);
this._blockSize = blockSize;
this._blockOffset = 0;
this._length = [0, 0, 0, 0];
this._finalized = false;
}
}
const publicKeyToAddress$1 = publicKey => {
const publicKeyBuffer = u8a.fromString(publicKey, 'hex');
const publicKeyHash = new Ripemd160().update(sha256(publicKeyBuffer)).digest();
const step1 = '00' + u8a.toString(publicKeyHash, 'hex');
const step2 = sha256(u8a.fromString(step1, 'hex'));
const step3 = sha256(step2);
const checksum = u8a.toString(step3, 'hex').substring(0, 8);
const step4 = step1 + checksum;
return bytesToBase58(u8a.fromString(step4, 'hex'));
};
const publicKeyToAddress = (publicKey, prefix) => {
const ec$1 = new ec('secp256k1');
const compressedPublicKey = ec$1.keyFromPublic(publicKey, 'hex').getPublic().encode('hex', true);
const publicKeyBuffer = u8a.fromString(compressedPublicKey, 'hex');
const hash = new Ripemd160().update(sha256(publicKeyBuffer)).digest();
const words = bech32.toWords(hash);
return bech32.encode(prefix, words).replace(prefix, '');
};
const verifyBlockchainAccountId = (publicKey, blockchainAccountId) => {
if (blockchainAccountId) {
const chain = blockchainAccountId.split(':');
switch (chain[0]) {
case 'bip122':
chain[chain.length - 1] = publicKeyToAddress$1(publicKey);
break;
case 'cosmos':
chain[chain.length - 1] = publicKeyToAddress(publicKey, chain[1]);
break;
case 'eip155':
chain[chain.length - 1] = toEthereumAddress(publicKey);
break;
default:
return false;
}
return chain.join(':') === blockchainAccountId;
}
return false;
};
const secp256k1 = new ec('secp256k1'); // converts a JOSE signature to it's components

@@ -399,3 +638,3 @@

});
const ethAddressKeys = authenticators.filter(({
const blockchainAddressKeys = authenticators.filter(({
ethereumAddress,

@@ -415,4 +654,4 @@ blockchainAccountId

if (!signer && ethAddressKeys.length > 0) {
signer = verifyRecoverableES256K(data, signature, ethAddressKeys);
if (!signer && blockchainAddressKeys.length > 0) {
signer = verifyRecoverableES256K(data, signature, blockchainAddressKeys);
}

@@ -448,3 +687,5 @@

const keyHex = bytesToHex(extractPublicKeyBytes(pk));
return keyHex === recoveredPublicKeyHex || keyHex === recoveredCompressedPublicKeyHex || ((_pk$ethereumAddress = pk.ethereumAddress) == null ? void 0 : _pk$ethereumAddress.toLowerCase()) === recoveredAddress || ((_pk$blockchainAccount = pk.blockchainAccountId) == null ? void 0 : (_pk$blockchainAccount2 = _pk$blockchainAccount.split('@eip155')) == null ? void 0 : _pk$blockchainAccount2[0].toLowerCase()) === recoveredAddress;
return keyHex === recoveredPublicKeyHex || keyHex === recoveredCompressedPublicKeyHex || ((_pk$ethereumAddress = pk.ethereumAddress) == null ? void 0 : _pk$ethereumAddress.toLowerCase()) === recoveredAddress || ((_pk$blockchainAccount = pk.blockchainAccountId) == null ? void 0 : (_pk$blockchainAccount2 = _pk$blockchainAccount.split('@eip155')) == null ? void 0 : _pk$blockchainAccount2[0].toLowerCase()) === recoveredAddress || // CAIP-2
verifyBlockchainAccountId(recoveredPublicKeyHex, pk.blockchainAccountId) // CAIP-10
;
});

@@ -451,0 +692,0 @@ return signer;

3

package.json
{
"name": "did-jwt",
"version": "5.10.0",
"version": "5.11.0",
"description": "Library for Signing and Verifying JWTs that use DIDs as issuers and JWEs that use DIDs as recipients",

@@ -86,2 +86,3 @@ "source": "src/index.ts",

"@stablelib/xchacha20poly1305": "^1.0.1",
"bech32": "^2.0.0",
"canonicalize": "^1.0.5",

@@ -88,0 +89,0 @@ "did-resolver": "^3.1.1",

import VerifierAlgorithm from '../VerifierAlgorithm'
import { createJWT } from '../JWT'
import { toEthereumAddress } from '../Digest'
import nacl from 'tweetnacl'

@@ -10,2 +9,5 @@ import { ec as EC } from 'elliptic'

import { ES256KSigner } from '../signers/ES256KSigner'
import { toEthereumAddress } from '../Digest'
import { publicKeyToAddress as toBip122Address } from '../blockchains/bip122'
import { publicKeyToAddress as toCosmosAddressWithoutPrefix } from '../blockchains/cosmos'

@@ -47,3 +49,6 @@ const secp256k1 = new EC('secp256k1')

const publicKeyMultibase = bytesToMultibase(hexToBytes(publicKey), 'base58btc')
const address = toEthereumAddress(publicKey)
const eip155 = toEthereumAddress(publicKey)
const bip122 = toBip122Address(publicKey)
const cosmosPrefix = 'example'
const cosmos = toCosmosAddressWithoutPrefix(publicKey, cosmosPrefix)
const signer = ES256KSigner(privateKey)

@@ -77,3 +82,3 @@ const recoverySigner = ES256KSigner(privateKey, true)

controller: did,
ethereumAddress: address,
ethereumAddress: eip155,
}

@@ -85,5 +90,26 @@

controller: did,
blockchainAccountId: `${address}@eip155:1`,
blockchainAccountId: `${eip155}@eip155:1`,
}
const blockchainAddressCaip10 = {
id: `${did}#keys-blockchain`,
type: 'EcdsaSecp256k1RecoveryMethod2020',
controller: did,
blockchainAccountId: `eip155:1:${eip155}`,
}
const blockchainAddressBip122 = {
id: `${did}#keys-blockchain`,
type: 'EcdsaSecp256k1RecoveryMethod2020',
controller: did,
blockchainAccountId: `bip122:000000000019d6689c085ae165831e93:${bip122}`,
}
const blockchainAddressCosmos = {
id: `${did}#keys-blockchain`,
type: 'EcdsaSecp256k1RecoveryMethod2020',
controller: did,
blockchainAccountId: `cosmos:${cosmosPrefix}:${cosmos}`,
}
const compressedKey = {

@@ -100,3 +126,3 @@ id: `${did}#keys-4`,

controller: did,
ethereumAddress: address,
ethereumAddress: eip155,
}

@@ -232,2 +258,23 @@

it('validates signature produced by blockchainAccountId - CAIP 10 (EIP 155)', async () => {
expect.assertions(1)
const jwt = await createJWT({ bla: 'bla' }, { issuer: did, signer })
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/)
return expect(verifier(parts[1], parts[2], [blockchainAddressCaip10])).toEqual(blockchainAddressCaip10)
})
it('validates signature produced by blockchainAccountId - CAIP 10 (BIP 122)', async () => {
expect.assertions(1)
const jwt = await createJWT({ bla: 'bla' }, { issuer: did, signer })
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/)
return expect(verifier(parts[1], parts[2], [blockchainAddressBip122])).toEqual(blockchainAddressBip122)
})
it('validates signature produced by blockchainAccountId - CAIP 10 (Cosmos)', async () => {
expect.assertions(1)
const jwt = await createJWT({ bla: 'bla' }, { issuer: did, signer })
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/)
return expect(verifier(parts[1], parts[2], [blockchainAddressCosmos])).toEqual(blockchainAddressCosmos)
})
it('validates signature produced by EcdsaSecp256k1RecoveryMethod2020 - github #152', async () => {

@@ -272,2 +319,23 @@ expect.assertions(1)

it('validates signature with blockchainAccountId - CAIP 10 (EIP 155)', async () => {
expect.assertions(1)
const jwt = await createJWT({ bla: 'bla' }, { issuer: did, signer: recoverySigner, alg: 'ES256K-R' })
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/)
return expect(verifier(parts[1], parts[2], [ecKey1, blockchainAddressCaip10])).toEqual(blockchainAddressCaip10)
})
it('validates signature with blockchainAccountId - CAIP 10 (BIP 122)', async () => {
expect.assertions(1)
const jwt = await createJWT({ bla: 'bla' }, { issuer: did, signer: recoverySigner, alg: 'ES256K-R' })
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/)
return expect(verifier(parts[1], parts[2], [ecKey1, blockchainAddressBip122])).toEqual(blockchainAddressBip122)
})
it('validates signature with blockchainAccountId - CAIP 10 (COSMOS)', async () => {
expect.assertions(1)
const jwt = await createJWT({ bla: 'bla' }, { issuer: did, signer: recoverySigner, alg: 'ES256K-R' })
const parts = jwt.match(/^([a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/)
return expect(verifier(parts[1], parts[2], [ecKey1, blockchainAddressCosmos])).toEqual(blockchainAddressCosmos)
})
it('validates signature with EcdsaSecp256k1RecoveryMethod2020 - github #152', async () => {

@@ -274,0 +342,0 @@ expect.assertions(1)

@@ -7,2 +7,3 @@ import { ec as EC, SignatureInput } from 'elliptic'

import { hexToBytes, base58ToBytes, base64ToBytes, bytesToHex, EcdsaSignature, stringToBytes } from './util'
import { verifyBlockchainAccountId } from './blockchains'

@@ -64,3 +65,3 @@ const secp256k1 = new EC('secp256k1')

})
const ethAddressKeys = authenticators.filter(({ ethereumAddress, blockchainAccountId }) => {
const blockchainAddressKeys = authenticators.filter(({ ethereumAddress, blockchainAccountId }) => {
return typeof ethereumAddress !== 'undefined' || typeof blockchainAccountId !== undefined

@@ -78,4 +79,4 @@ })

if (!signer && ethAddressKeys.length > 0) {
signer = verifyRecoverableES256K(data, signature, ethAddressKeys)
if (!signer && blockchainAddressKeys.length > 0) {
signer = verifyRecoverableES256K(data, signature, blockchainAddressKeys)
}

@@ -117,3 +118,4 @@

pk.ethereumAddress?.toLowerCase() === recoveredAddress ||
pk.blockchainAccountId?.split('@eip155')?.[0].toLowerCase() === recoveredAddress
pk.blockchainAccountId?.split('@eip155')?.[0].toLowerCase() === recoveredAddress || // CAIP-2
verifyBlockchainAccountId(recoveredPublicKeyHex, pk.blockchainAccountId) // CAIP-10
)

@@ -120,0 +122,0 @@ })

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc