@chainsafe/libp2p-noise
Version:
Noise libp2p handshake for js-libp2p
42 lines • 1.89 kB
JavaScript
import { publicKeyFromProtobuf, publicKeyToProtobuf } from '@libp2p/crypto/keys';
import { UnexpectedPeerError } from '@libp2p/interface';
import { concat as uint8ArrayConcat } from 'uint8arrays/concat';
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
import { NoiseHandshakePayload } from './proto/payload.js';
export async function createHandshakePayload(privateKey, staticPublicKey, extensions) {
const identitySig = await privateKey.sign(getSignaturePayload(staticPublicKey));
return NoiseHandshakePayload.encode({
identityKey: publicKeyToProtobuf(privateKey.publicKey),
identitySig,
extensions
});
}
export async function decodeHandshakePayload(payloadBytes, remoteStaticKey, remoteIdentityKey) {
try {
const payload = NoiseHandshakePayload.decode(payloadBytes);
const publicKey = publicKeyFromProtobuf(payload.identityKey);
if (remoteIdentityKey?.equals(publicKey) === false) {
throw new Error(`Payload identity key ${publicKey} does not match expected remote identity key ${remoteIdentityKey}`);
}
if (!remoteStaticKey) {
throw new Error('Remote static does not exist');
}
const signaturePayload = getSignaturePayload(remoteStaticKey);
if (!(await publicKey.verify(signaturePayload, payload.identitySig))) {
throw new Error('Invalid payload signature');
}
return payload;
}
catch (e) {
throw new UnexpectedPeerError(e.message);
}
}
export function getSignaturePayload(publicKey) {
const prefix = uint8ArrayFromString('noise-libp2p-static-key:');
if (publicKey instanceof Uint8Array) {
return uint8ArrayConcat([prefix, publicKey], prefix.length + publicKey.length);
}
publicKey.prepend(prefix);
return publicKey;
}
//# sourceMappingURL=utils.js.map