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

The Ed25519 key pair creation from the seed is broken #295

Closed
DieMyst opened this issue Feb 1, 2023 · 2 comments · Fixed by #300
Closed

The Ed25519 key pair creation from the seed is broken #295

DieMyst opened this issue Feb 1, 2023 · 2 comments · Fixed by #300
Labels

Comments

@DieMyst
Copy link

DieMyst commented Feb 1, 2023

If we create key pair from seed, sign and verify some random data, it will fail. I checked it by adding a test case in this repo (here https://github.com/libp2p/js-libp2p-crypto/blob/master/test/keys/ed25519.spec.ts).

    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)
    // `valid` is false
    expect(valid).to.eql(true)

example in fork: https://github.com/DieMyst/js-libp2p-crypto/blob/master/test/keys/ed25519.spec.ts#L151

@DieMyst DieMyst changed the title The key pair creation from the seed is broken The Ed25519 key pair creation from the seed is broken Feb 1, 2023
@folex
Copy link

folex commented Feb 1, 2023

It seeems to me that derivePublicKey became quite unusual for ed25519

function derivePublicKey (privateKey: Uint8Array) {
  const hash = crypto.createHash('sha512')
  hash.update(privateKey)
  return hash.digest().subarray(32)
}

before, it was

function getKeyFromHash(hashed: Uint8Array) {
  // First 32 bytes of 64b uniformingly random input are taken,
  // clears 3 bits of it to produce a random field element.
  const head = adjustBytes25519(hashed.slice(0, 32));
  // Second 32 bytes is called key prefix (5.1.6)
  const prefix = hashed.slice(32, 64);
  // The actual private scalar
  const scalar = modlLE(head);
  // Point on Edwards curve aka public key
  const point = Point.BASE.multiply(scalar);
  const pointBytes = point.toRawBytes();
  return { head, prefix, scalar, point, pointBytes };
}

which made much for sense.

AFAIU, publicKey = sha512(privateKey) is not valid for ed25519 🤔

achingbrain added a commit that referenced this issue Feb 8, 2023
Create a private key object from the raw `Ed25519` private key and
export it as a JWK to obtain the public key.

Fixes #295
mpetrunic pushed a commit that referenced this issue Feb 8, 2023
Create a private key object from the raw `Ed25519` private key and
export it as a JWK to obtain the public key.

Fixes #295
github-actions bot pushed a commit that referenced this issue Feb 8, 2023
## [1.0.12](v1.0.11...v1.0.12) (2023-02-08)

### Bug Fixes

* derive ed25519 public key from private key using node crypto ([#300](#300)) ([874f820](874f820)), closes [#295](#295)

### Trivial Changes

* replace err-code with CodeError ([#293](#293)) ([4398cf6](4398cf6)), closes [js-libp2p#1269](libp2p/js-libp2p#1269)
@github-actions
Copy link

github-actions bot commented Feb 8, 2023

🎉 This issue has been resolved in version 1.0.12 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants