Skip to content

Commit 4b4f98c

Browse files
committed
refactor(ocapn): include id and descriptor in public key object
1 parent bda842f commit 4b4f98c

File tree

7 files changed

+98
-101
lines changed

7 files changed

+98
-101
lines changed

packages/ocapn/src/client/index.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// @ts-check
22

33
/**
4-
* @import { OcapnLocation, OcapnPublicKeyData, OcapnSignature } from '../codecs/components.js'
5-
* @import { OcapnKeyPair, OcapnPublicKey } from '../cryptography.js'
4+
* @import { OcapnLocation, OcapnSignature } from '../codecs/components.js'
5+
* @import { OcapnPublicKey } from '../cryptography.js'
66
* @import { GrantTracker, Ocapn } from './ocapn.js'
77
* @import { Client, Connection, LocationId, Logger, NetLayer, PendingSession, SelfIdentity, Session, SessionManager } from './types.js'
88
*/
@@ -14,10 +14,8 @@ import {
1414
writeOcapnHandshakeMessage,
1515
} from '../codecs/operations.js';
1616
import {
17-
makePublicKeyId,
1817
makeOcapnKeyPair,
1918
makeOcapnPublicKey,
20-
publicKeyToPublicKeyData,
2119
makeSessionId,
2220
} from '../cryptography.js';
2321
import { OcapnMyLocationCodec } from '../codecs/components.js';
@@ -99,7 +97,7 @@ export const sendHello = (connection, mySessionData) => {
9997
const opStartSession = {
10098
type: 'op:start-session',
10199
captpVersion: '1.0',
102-
sessionPublicKey: publicKeyToPublicKeyData(keyPair.publicKey),
100+
sessionPublicKey: keyPair.publicKey.descriptor,
103101
location,
104102
locationSignature,
105103
};
@@ -119,8 +117,8 @@ const compareSessionKeysForCrossedHellos = (
119117
incommingPublicKey,
120118
) => {
121119
const outgoingPublicKey = outgoingConnection.selfIdentity.keyPair.publicKey;
122-
const outgoingId = makePublicKeyId(outgoingPublicKey);
123-
const incommingId = makePublicKeyId(incommingPublicKey);
120+
const outgoingId = outgoingPublicKey.id;
121+
const incommingId = incommingPublicKey.id;
124122
const result = compareByteArrays(
125123
outgoingId,
126124
incommingId,
@@ -243,9 +241,10 @@ const handleSessionHandshakeMessage = (
243241

244242
// Create session
245243
const { selfIdentity } = connection;
246-
const selfId = makePublicKeyId(selfIdentity.keyPair.publicKey);
247-
const peerId = makePublicKeyId(peerPublicKey);
248-
const sessionId = makeSessionId(selfId, peerId);
244+
const sessionId = makeSessionId(
245+
selfIdentity.keyPair.publicKey.id,
246+
peerPublicKey.id,
247+
);
249248
const ocapn = makeOcapn(
250249
logger,
251250
connection,

packages/ocapn/src/client/ocapn.js

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ import { getSelectorName, makeSelector } from '../pass-style-helpers.js';
3131
import { decodeSyrup } from '../syrup/js-representation.js';
3232
import { decodeSwissnum, locationToLocationId, toHex } from './util.js';
3333
import {
34-
makePublicKeyId,
35-
publicKeyDataToPublicKey,
36-
publicKeyToPublicKeyData,
34+
publicKeyDescriptorToPublicKey,
3735
randomGiftId,
3836
} from '../cryptography.js';
3937
import { compareByteArrays } from '../syrup/compare.js';
@@ -608,14 +606,12 @@ export const makeTableKit = (
608606
const {
609607
peer: { publicKey: receiverPublicKeyForGifter },
610608
} = gifterReceiverSession;
611-
const gifterSideId = makePublicKeyId(
612-
gifterExporterSession.self.keyPair.publicKey,
613-
);
609+
const gifterSideId = gifterExporterSession.self.keyPair.publicKey.id;
614610
const giftId = randomGiftId();
615611
/** @type {HandoffGive} */
616612
const handoffGive = {
617613
type: 'desc:handoff-give',
618-
receiverKey: publicKeyToPublicKeyData(receiverPublicKeyForGifter),
614+
receiverKey: receiverPublicKeyForGifter.descriptor,
619615
exporterLocation,
620616
exporterSessionId: gifterExporterSessionId,
621617
gifterSideId,
@@ -721,7 +717,7 @@ const makeBootstrapObject = (
721717
`${label}: Bootstrap withdraw-gift: No peer public key for session id: ${toHex(sessionId)}. This should never happen.`,
722718
);
723719
}
724-
const peerIdFromSession = makePublicKeyId(peerPublicKey);
720+
const peerIdFromSession = peerPublicKey.id;
725721
if (
726722
compareByteArrays(peerIdFromSession, peerIdFromHandoffReceive) !== 0
727723
) {
@@ -753,7 +749,7 @@ const makeBootstrapObject = (
753749

754750
// Verify HandoffReceive
755751
const handoffReceiveBytes = serializeHandoffReceive(handoffReceive);
756-
const receiverKeyForGifter = publicKeyDataToPublicKey(
752+
const receiverKeyForGifter = publicKeyDescriptorToPublicKey(
757753
receiverKeyDataForGifter,
758754
);
759755
const handoffReceiveIsValid = receiverKeyForGifter.verify(
@@ -1098,9 +1094,7 @@ export const makeOcapn = (
10981094
id: receiverExporterSessionId,
10991095
self: { keyPair: receiverKeyForExporter },
11001096
} = receiverExporterSession;
1101-
const receiverPeerIdForExporter = makePublicKeyId(
1102-
receiverKeyForExporter.publicKey,
1103-
);
1097+
const receiverPeerIdForExporter = receiverKeyForExporter.publicKey.id;
11041098
const {
11051099
self: { keyPair: receiverGifterKey },
11061100
} = receiverGifterSession;

packages/ocapn/src/codecs/components.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export const OcapnSignatureCodec = makeOcapnListComponentCodec(
9999
);
100100

101101
/**
102-
* @typedef {object} OcapnPublicKeyData
102+
* @typedef {object} OcapnPublicKeyDescriptor
103103
* @property {'public-key'} type
104104
* @property {'ecc'} scheme
105105
* @property {'Ed25519'} curve

packages/ocapn/src/codecs/descriptors.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* @import { SyrupCodec, SyrupRecordCodec, SyrupRecordUnionCodec } from '../syrup/codec.js'
66
* @import { SyrupReader } from '../syrup/decode.js'
77
* @import { SyrupWriter } from '../syrup/encode.js'
8-
* @import { OcapnLocation, OcapnPublicKeyData, OcapnSignature } from './components.js'
8+
* @import { OcapnLocation, OcapnPublicKeyDescriptor, OcapnSignature } from './components.js'
99
* @import { OcapnPublicKey, OcapnKeyPair } from '../cryptography.js'
1010
*/
1111

@@ -37,7 +37,7 @@ import { makeSyrupWriter } from '../syrup/encode.js';
3737
/**
3838
* @typedef {object} HandoffGive
3939
* @property {'desc:handoff-give'} type
40-
* @property {OcapnPublicKeyData} receiverKey
40+
* @property {OcapnPublicKeyDescriptor} receiverKey
4141
* @property {OcapnLocation} exporterLocation
4242
* @property {Uint8Array} exporterSessionId
4343
* @property {Uint8Array} gifterSideId

packages/ocapn/src/cryptography.js

Lines changed: 68 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ import { OcapnPublicKeyCodec } from './codecs/components.js';
99
import { compareByteArrays } from './syrup/compare.js';
1010

1111
/**
12-
* @import { OcapnPublicKeyData, OcapnSignature } from './codecs/components.js'
12+
* @import { OcapnPublicKeyDescriptor, OcapnSignature } from './codecs/components.js'
1313
*/
1414

1515
const textEncoder = new TextEncoder();
1616

1717
/**
1818
* @typedef {object} OcapnPublicKey
19+
* @property {Uint8Array} id
1920
* @property {Uint8Array} bytes
21+
* @property {OcapnPublicKeyDescriptor} descriptor
2022
* @property {(msg: Uint8Array, sig: OcapnSignature) => boolean} verify
2123
*/
2224

@@ -38,34 +40,71 @@ export const ocapNSignatureToBytes = sig => {
3840
};
3941

4042
/**
41-
* @param {Uint8Array} publicKey
42-
* @returns {OcapnPublicKey}
43+
* @param {Uint8Array} publicKeyBytes
44+
* @returns {OcapnPublicKeyDescriptor}
4345
*/
44-
export const makeOcapnPublicKey = publicKey => {
46+
const makePublicKeyDescriptor = publicKeyBytes => {
4547
return {
46-
bytes: publicKey,
48+
type: 'public-key',
49+
scheme: 'ecc',
50+
curve: 'Ed25519',
51+
flags: 'eddsa',
52+
q: publicKeyBytes,
53+
};
54+
};
55+
56+
/**
57+
* @param {OcapnPublicKeyDescriptor} publicKeyDescriptor
58+
* @returns {Uint8Array}
59+
*/
60+
const publicKeyDescriptorToEncodedBytes = publicKeyDescriptor => {
61+
const syrupWriter = makeSyrupWriter();
62+
OcapnPublicKeyCodec.write(publicKeyDescriptor, syrupWriter);
63+
return syrupWriter.getBytes();
64+
};
65+
66+
/**
67+
* @param {OcapnPublicKeyDescriptor} publicKeyDescriptor
68+
* @returns {Uint8Array}
69+
*/
70+
const makePublicKeyIdFromDescriptor = publicKeyDescriptor => {
71+
const publicKeyEncoded =
72+
publicKeyDescriptorToEncodedBytes(publicKeyDescriptor);
73+
return sha256(sha256(publicKeyEncoded));
74+
};
75+
76+
/**
77+
* @param {Uint8Array} publicKeyBytes
78+
* @returns {OcapnPublicKey}
79+
*/
80+
export const makeOcapnPublicKey = publicKeyBytes => {
81+
const publicKeyDescriptor = makePublicKeyDescriptor(publicKeyBytes);
82+
return harden({
83+
id: makePublicKeyIdFromDescriptor(publicKeyDescriptor),
84+
bytes: publicKeyBytes,
85+
descriptor: publicKeyDescriptor,
4786
/**
4887
* @param {Uint8Array} msgBytes
4988
* @param {OcapnSignature} ocapnSig
5089
* @returns {boolean}
5190
*/
5291
verify: (msgBytes, ocapnSig) => {
5392
const sigBytes = ocapNSignatureToBytes(ocapnSig);
54-
return ed25519.verify(sigBytes, msgBytes, publicKey);
93+
return ed25519.verify(sigBytes, msgBytes, publicKeyBytes);
5594
},
56-
};
95+
});
5796
};
5897

5998
/**
6099
* @returns {OcapnKeyPair}
61100
*/
62101
export const makeOcapnKeyPair = () => {
63-
const privateKey = ed25519.utils.randomPrivateKey();
64-
const publicKey = ed25519.getPublicKey(privateKey);
102+
const privateKeyBytes = ed25519.utils.randomPrivateKey();
103+
const publicKeyBytes = ed25519.getPublicKey(privateKeyBytes);
65104
return {
66-
publicKey: makeOcapnPublicKey(publicKey),
105+
publicKey: makeOcapnPublicKey(publicKeyBytes),
67106
sign: msg => {
68-
const sigBytes = ed25519.sign(msg, privateKey);
107+
const sigBytes = ed25519.sign(msg, privateKeyBytes);
69108
return {
70109
type: 'sig-val',
71110
scheme: 'eddsa',
@@ -77,46 +116,26 @@ export const makeOcapnKeyPair = () => {
77116
};
78117

79118
/**
80-
* @param {OcapnPublicKey} publicKey
81-
* @returns {OcapnPublicKeyData}
82-
*/
83-
export const publicKeyToPublicKeyData = publicKey => {
84-
return {
85-
type: 'public-key',
86-
scheme: 'ecc',
87-
curve: 'Ed25519',
88-
flags: 'eddsa',
89-
q: publicKey.bytes,
90-
};
91-
};
92-
93-
/**
94-
* @param {OcapnPublicKeyData} publicKeyData
119+
* @param {OcapnPublicKeyDescriptor} publicKeyDescriptor
95120
* @returns {OcapnPublicKey}
96121
*/
97-
export const publicKeyDataToPublicKey = publicKeyData => {
98-
return makeOcapnPublicKey(publicKeyData.q);
99-
};
100-
101-
/**
102-
* @param {OcapnPublicKeyData} publicKeyData
103-
* @returns {Uint8Array}
104-
*/
105-
const publicKeyDataToEncodedBytes = publicKeyData => {
106-
const syrupWriter = makeSyrupWriter();
107-
OcapnPublicKeyCodec.write(publicKeyData, syrupWriter);
108-
return syrupWriter.getBytes();
109-
};
110-
111-
/**
112-
* @param {OcapnPublicKey} publicKey
113-
* @returns {Uint8Array}
114-
*/
115-
export const makePublicKeyId = publicKey => {
116-
const publicKeyData = publicKeyToPublicKeyData(publicKey);
117-
const publicKeyEncoded = publicKeyDataToEncodedBytes(publicKeyData);
118-
// Double SHA256 hash of the public key
119-
return sha256(sha256(publicKeyEncoded));
122+
export const publicKeyDescriptorToPublicKey = publicKeyDescriptor => {
123+
if (publicKeyDescriptor.type !== 'public-key') {
124+
throw new Error('Invalid public key descriptor: Unexpected type');
125+
}
126+
if (publicKeyDescriptor.scheme !== 'ecc') {
127+
throw new Error('Invalid public key descriptor: Unexpected scheme');
128+
}
129+
if (publicKeyDescriptor.curve !== 'Ed25519') {
130+
throw new Error('Invalid public key descriptor: Unexpected curve');
131+
}
132+
if (publicKeyDescriptor.flags !== 'eddsa') {
133+
throw new Error('Invalid public key descriptor: Unexpected flags');
134+
}
135+
if (publicKeyDescriptor.q.length !== 32) {
136+
throw new Error('Invalid public key descriptor: Unexpected q length');
137+
}
138+
return makeOcapnPublicKey(publicKeyDescriptor.q);
120139
};
121140

122141
/**
@@ -125,7 +144,6 @@ export const makePublicKeyId = publicKey => {
125144
* @returns {Uint8Array}
126145
*/
127146
export const makeSessionId = (peerIdOne, peerIdTwo) => {
128-
// Calculate the ID of each side using the process described above.
129147
// Sort both IDs based on the resulting octets
130148
const result = compareByteArrays(
131149
peerIdOne,

packages/ocapn/test/codecs/components.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/**
44
* @import { CodecTestEntry } from './_codecs_util.js'
5-
* @import { OcapnLocation, OcapnPublicKeyData, OcapnSignature } from '../../src/codecs/components.js'
5+
* @import { OcapnLocation, OcapnPublicKeyDescriptor, OcapnSignature } from '../../src/codecs/components.js'
66
*/
77

88
import test from '@endo/ses-ava/test.js';
@@ -45,7 +45,7 @@ const table = [
4545
},
4646
{
4747
syrup: makePubKey(examplePubKeyQBytes),
48-
value: /** @type {OcapnPublicKeyData} */ ({
48+
value: /** @type {OcapnPublicKeyDescriptor} */ ({
4949
type: 'public-key',
5050
scheme: 'ecc',
5151
curve: 'Ed25519',

0 commit comments

Comments
 (0)