Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ed25519KeyIdentity.verify incorrect implementation #943

Open
adpopescu338 opened this issue Oct 16, 2024 · 0 comments
Open

Ed25519KeyIdentity.verify incorrect implementation #943

adpopescu338 opened this issue Oct 16, 2024 · 0 comments

Comments

@adpopescu338
Copy link

Ed25519KeyIdentity.verify is calling ed25519.verify with the wrong args

To Reproduce

import { Ed25519KeyIdentity } from '@dfinity/identity';

// Arguments
const args = [
  'vfKdMCDuw5sx85POiPwPNJ+OMp9711ORElAET0G1KpqoausXE4QUVjqalfQ7z+ZKlW/MWtHwlqHLRJVwPrR6Cg==',
  '{"termsAndConditionsId":"default","termsAndConditionsConsent":true,"emailAddress":"[email protected]","temporaryIdentityPublicKeyDerBase64":"MCowBQYDK2VwAyEAQgA3YzGamtPWxowSoUrwtew+lha45zKXay+IycoZOwA="}',
  'MCowBQYDK2VwAyEAQgA3YzGamtPWxowSoUrwtew+lha45zKXay+IycoZOwA=',
];

// Decode the signature from base64
const signature = Uint8Array.from(Buffer.from(args[0], 'base64')); // Convert to Uint8Array
console.log('Decoded signature length:', signature.length); // Check the length of the signature

// Decode the body (JSON string)
const message = Uint8Array.from(Buffer.from(args[1], 'utf8')); // Convert to Uint8Array
console.log('Decoded message length:', message.length); // Check the length of the message

// Decode the public key from base64
const temporaryIdentityPublicKeyDerBase64 = Uint8Array.from(
  Buffer.from(args[2], 'base64')
); // Convert to Uint8Array

console.log(
  'Decoded public key length:',
  temporaryIdentityPublicKeyDerBase64.length
); // Check the length of the public key

const result = Ed25519KeyIdentity.verify(
  signature,
  message,
  temporaryIdentityPublicKeyDerBase64
);

console.log('Verification result:', result);

Output:

Decoded signature length: 64
Decoded message length: 209
Decoded public key length: 44
/test/node_modules/@noble/curves/abstract/utils.js:152
        throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);
              ^

Error: signature expected 64 bytes, got 209
    at ensureBytes (/test/node_modules/@noble/curves/abstract/utils.js:152:15)
    at Object.verify (/test/node_modules/@noble/curves/abstract/edwards.js:386:42)
    at Ed25519KeyIdentity.verify (/test/node_modules/@dfinity/identity/lib/cjs/identity/ed25519.js:211:34)
    at file:///test/src/test.mjs:28:35
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v20.11.0

If we swap message and signature as follows, it doesn't error out anymore, but the output will be false

const result = Ed25519KeyIdentity.verify(
    message,
  signature,
  temporaryIdentityPublicKeyDerBase64
);

Output:

Decoded signature length: 64
Decoded message length: 209
Decoded public key length: 44
Verification result: false

Screenshots
Screenshot 2024-10-16 at 08 08 53

The problem most likely is caused by THIS LINE, where we call ed25519.verify(message, signature, publicKey), but ed25519.verify expects the signature as first arg and message as second.

/**
 * Edwards Curve interface.
 * Main methods: `getPublicKey(priv)`, `sign(msg, priv)`, `verify(sig, msg, pub)`.
 */
export type CurveFn = {
  CURVE: ReturnType<typeof validateOpts>;
  getPublicKey: (privateKey: Hex) => Uint8Array;
  sign: (message: Hex, privateKey: Hex, options?: { context?: Hex }) => Uint8Array;
  verify: (
    sig: Hex,
    message: Hex,
    publicKey: Hex,
    options?: { context?: Hex; zip215: boolean }
  ) => boolean;
  ExtendedPoint: ExtPointConstructor;
  utils: {
    randomPrivateKey: () => Uint8Array;
    getExtendedPublicKey: (key: Hex) => {
      head: Uint8Array;
      prefix: Uint8Array;
      scalar: bigint;
      point: ExtPointType;
      pointBytes: Uint8Array;
    };
  };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant