Skip to content
This repository has been archived by the owner on Jul 21, 2023. It is now read-only.

Commit

Permalink
fix: derive ed25519 public key from private key using node crypto (#300)
Browse files Browse the repository at this point in the history
Create a private key object from the raw `Ed25519` private key and
export it as a JWK to obtain the public key.

Fixes #295
  • Loading branch information
achingbrain authored Feb 8, 2023
1 parent dfe6825 commit 874f820
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
23 changes: 19 additions & 4 deletions src/keys/ed25519.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down
9 changes: 9 additions & 0 deletions test/keys/ed25519.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 874f820

Please sign in to comment.