diff --git a/src/keys/ed25519.ts b/src/keys/ed25519.ts index 5232b75a..f643e3d7 100644 --- a/src/keys/ed25519.ts +++ b/src/keys/ed25519.ts @@ -13,10 +13,25 @@ const SIGNATURE_BYTE_LENGTH = 64 export { PUBLIC_KEY_BYTE_LENGTH as publicKeyLength } export { PRIVATE_KEY_BYTE_LENGTH as privateKeyLength } -function derivePublicKey (privateKey: Uint8Array) { - const hash = crypto.createHash('sha512') - hash.update(privateKey) - return hash.digest().subarray(32) +function derivePublicKey (privateKey: Uint8Array): Uint8Array { + const keyObject = crypto.createPrivateKey({ + format: 'jwk', + key: { + crv: 'Ed25519', + x: '', + d: uint8arrayToString(privateKey, 'base64url'), + kty: 'OKP' + } + }) + const jwk = keyObject.export({ + format: 'jwk' + }) + + if (jwk.x == null || jwk.x === '') { + throw new Error('Could not export JWK public key') + } + + return uint8arrayFromString(jwk.x, 'base64url') } export async function generateKey () { diff --git a/test/keys/ed25519.spec.ts b/test/keys/ed25519.spec.ts index 7b9579a7..8e8499e1 100644 --- a/test/keys/ed25519.spec.ts +++ b/test/keys/ed25519.spec.ts @@ -148,6 +148,15 @@ describe('ed25519', function () { expect(valid).to.eql(true) }) + it('sign and verify from seed', async () => { + const seed = new Uint8Array(32).fill(1) + const seededkey = await crypto.keys.generateKeyPairFromSeed('Ed25519', seed) + const data = uint8ArrayFromString('hello world') + const sig = await seededkey.sign(data) + const valid = await seededkey.public.verify(data, sig) + expect(valid).to.eql(true) + }) + it('fails to verify for different data', async () => { const data = uint8ArrayFromString('hello world') const sig = await key.sign(data)