bitwiseshiftleft / sjcl

Stanford Javascript Crypto Library
http://bitwiseshiftleft.github.com/sjcl/
Other
7.18k stars 986 forks source link

EC point not on the curve! (java to sjcl) #392

Open matteobertozzi opened 5 years ago

matteobertozzi commented 5 years ago

I'm trying to share EC public keys between java and javascript.

In java I'm using the KeyPairGenerator with "secp256r1", and for test I've exported a bunch of keys: base64(x + y)

public static KeyPair generateKeyPairP256()
    throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
  final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
  keyPairGenerator.initialize(new ECGenParameterSpec("secp256r1"));
  return keyPairGenerator.generateKeyPair();
}

// generate and export the keys to test
for (int i = 0; i < 20; ++i) {
  final ECPublicKey pubkey = (ECPublicKey)EcUtil.generateKeyPairP256().getPublic();
  System.out.println(Base64.getEncoder().encodeToString(BytesUtil.concat(
    pubkey.getW().getAffineX().toByteArray(),
    pubkey.getW().getAffineY().toByteArray()
  )));
}

In javascript I'm creating the public key from the base64(x + y) but only few keys seems to be valid, most of them are rejected as 'not on the curve'.

const keys = [
  /* not on the curve! */ 'ANLIxVyDuBnss2KeByZwmPDV+Y/YYxVrf/+cx+kbfM2hAOX5v8hK3TyzaufifwlBqFGdeaG2lQvxMndaSHl3mI45',
  /* ok */ 'O08/Q5Yhv9T1Rl+ci8hyTUt8TtJtK9iJ0bqIzdkonXQ084s2TuzdMkIN+vwY0sEvdvl/ww8kXnsYxHwOT63eag==',
  /* not on the curve! */ 'AJvBwTlKWvETW8h9He80q7ZPPemT0lF0Q3s1AK9YamwHAJ6KAPd1t4mWrbFXkD8xVBe9HSMvfoGQxfIFutgaGhV1',
  /* not on the curve! */ 'ALbm8zY++oby4etNH+k5ORdzHzHyQtVfevWg/0db3bGyVwf1QUdgGD13RcVTZwwt0xW4AB+C0gFCCTdRa6aEb0Q=',
  /* not on the curve! */ 'Y1wStfsy6o8GqsoqvLFhV2f0WZRw60QLSkA6hek7QZkA+tuU2SUoJmFVHa7g3oQLknwQWaKmzJYwQ6/zuqGLYUg=',
  /* not on the curve! */ 'ALYhkfg+rrBgAFNG29dG6CUHkIuYGSF3K45ao6C0R6hAAL7GvZR6v1d/J7p7hGDABRx1nUk8aIhFzpXPWBl0g/Z1',
  /* not on the curve! */ 'OyU6ExPtTgBRB4Gka5a3sGv3lTsAd0x7AxRV/+66WAQAgKotZoBsM53azsy7FLJz68AoJMc3UzOregIyvqC/WkI=',
  /* ok */ 'ZcTaVPTm3bHB33kHXqQX1Frbbp09zZhj6rLf3t4dBe09mnqnOi9AvG3oHNQcGoU4mBvWJ2wLc16WjJRk/gfyRQ==',
  /* not on the curve! */ 'AOSB0wyJkd/VrFmgEPp16S+vtkCZPEi+ca6Vd5bpjrCPAK1HzI8KCXvRHAtfXJyj70BmNR/y5NFDsd5XGVFisZAX',
  /* not on the curve! */ 'AJU6UPZHcMdWNv5CBl56phat9EHOTnQ9Z4ujzVRZKtouAJ/rjqSVRABTUYMxmRWbHA5usGRdnSKJg47gzoGnD+9+',
  /* not on the curve! */ 'AI8beSdfWlDNYVockAYvAjbtomN9I6Zr+j09o/f/Gx2OAIr88YdNQKCV716JEbDVVMO7X6eNOHFDakG/zPQkW3d2',
  /* ok */ 'IygMA2ErCPvfEzKcRLt9ICI26frZKVbN5UoorFn51FVJhOAUvoBv8YSDaFBeuidtfdE9NhKL3p5OFcoA9hpn7w==',
  /* not on the curve! */ 'SK1a8SIvjjyZQUGRXa2pLzV5d/bqH0MLeQrAvFky6BoAl0TB7B9K7Y+p2y14qEwgSI6UqGCwa4jAxeiL6b8pFto=',
  /* not on the curve! */ 'AIpM5MTWLNf/BvcaLseBx1Cn5w7NmVCJubr+9s2AOYTudyhTWPGzRzGF3/G/AjfKY1T3cQzOWc+CFN4BV3gohyM=',
  /* not on the curve! */ 'ALC9GT5WbO1cQbGCGPfC7Jgrnxf4nUnL6att+Ut2LEhLAN2S36VvA2jVfQi7VA4/fF383vkfRyyN2ROiJekO8gmu',
  /* ok */ 'fo18bFMaiX1eQPBIv9HtKwS0Zlng69bZ3pbIlyB5oMhceaRWBQZnlGPWvbM+RpWCkf4l3km/WWcQuSSneeldfg==',
  /* not on the curve! */ 'APg6AAdqPF/8el8QfARKNKewuqiJodz4oK7v9DXlKphJJzTuCHzeV8+w3CrEIsr9SslMTzoVox39RHIL/HMSi74=',
  /* not on the curve! */ 'AKwPjAvakqEtszhRbWae0gPUC3+Gg7/GMAMNH3d6tcbAHvXKj+YY4UF/+9woqMTYTpTWkmkQcHA6k1vVqNJI2dw=',
  /* not on the curve! */ 'AMTWHCNxCKGe7+Ml7EmjLPCpkWmIZMaVcrDKOds+Ev0VE4IyuSVAyqa62QrN22giZLsJCc9CR1iFP2uxY10MhMo=',
  /* ok */ 'cGeG8rOatkcrsJFkHcJ7bU+BqCLJKY552oM1K6czHhxycnZaf/N3A2G+w/+WZaSCWS3P7zKKAXl090GAeBw4qA==',
];
for (let i = 0; i < keys.length; ++i) {
  try {
    const pubkey = new sjcl.ecc.elGamal.publicKey(
      sjcl.ecc.curves.c256,
      sjcl.codec.base64.toBits(keys[i])
    );
    console.log('OK', keys[i], pubkey);
  } catch(e) {
    console.log(e.message, keys[i]);
  }
}

Are there more parameters required to pass to the java key generator or the sjcl publickey constructor, or is there a bug in the sjcl parse?

(if there are more parameters or different parameters required, maybe we can add a section to the wiki to show how to generate and export from java)

jmkf commented 5 years ago

I suspect on the Java side you make an error converting 256 bits to base 64 by going through a signed number. Make sure you don't leave off leading zeros or add one extra byte to keep a signed number positive. (That last one probably explains the Overrepresentation of leading A characters in the wrong points)Br Martijn On May 2, 2019 08:08, Matteo Bertozzi notifications@github.com wrote:I'm trying to share EC public keys between java and javascript. In java I'm using the KeyPairGenerator with "secp256r1", and for test I've exported a bunch of keys: base64(x + y) public static KeyPair generateKeyPairP256() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); keyPairGenerator.initialize(new ECGenParameterSpec("secp256r1")); return keyPairGenerator.generateKeyPair(); }

// generate and export the keys to test for (int i = 0; i < 20; ++i) { final ECPublicKey pubkey = (ECPublicKey)EcUtil.generateKeyPairP256().getPublic(); System.out.println(Base64.getEncoder().encodeToString(BytesUtil.concat( pubkey.getW().getAffineX().toByteArray(), pubkey.getW().getAffineY().toByteArray() ))); } In javascript I'm creating the public key from the base64(x + y) but only few keys seems to be valid, most of them are rejected as 'not on the curve'. const keys = [ / not on the curve! / 'ANLIxVyDuBnss2KeByZwmPDV+Y/YYxVrf/+cx+kbfM2hAOX5v8hK3TyzaufifwlBqFGdeaG2lQvxMndaSHl3mI45', / ok / 'O08/Q5Yhv9T1Rl+ci8hyTUt8TtJtK9iJ0bqIzdkonXQ084s2TuzdMkIN+vwY0sEvdvl/ww8kXnsYxHwOT63eag==', / not on the curve! / 'AJvBwTlKWvETW8h9He80q7ZPPemT0lF0Q3s1AK9YamwHAJ6KAPd1t4mWrbFXkD8xVBe9HSMvfoGQxfIFutgaGhV1', / not on the curve! / 'ALbm8zY++oby4etNH+k5ORdzHzHyQtVfevWg/0db3bGyVwf1QUdgGD13RcVTZwwt0xW4AB+C0gFCCTdRa6aEb0Q=', / not on the curve! / 'Y1wStfsy6o8GqsoqvLFhV2f0WZRw60QLSkA6hek7QZkA+tuU2SUoJmFVHa7g3oQLknwQWaKmzJYwQ6/zuqGLYUg=', / not on the curve! / 'ALYhkfg+rrBgAFNG29dG6CUHkIuYGSF3K45ao6C0R6hAAL7GvZR6v1d/J7p7hGDABRx1nUk8aIhFzpXPWBl0g/Z1', / not on the curve! / 'OyU6ExPtTgBRB4Gka5a3sGv3lTsAd0x7AxRV/+66WAQAgKotZoBsM53azsy7FLJz68AoJMc3UzOregIyvqC/WkI=', / ok / 'ZcTaVPTm3bHB33kHXqQX1Frbbp09zZhj6rLf3t4dBe09mnqnOi9AvG3oHNQcGoU4mBvWJ2wLc16WjJRk/gfyRQ==', / not on the curve! / 'AOSB0wyJkd/VrFmgEPp16S+vtkCZPEi+ca6Vd5bpjrCPAK1HzI8KCXvRHAtfXJyj70BmNR/y5NFDsd5XGVFisZAX', / not on the curve! / 'AJU6UPZHcMdWNv5CBl56phat9EHOTnQ9Z4ujzVRZKtouAJ/rjqSVRABTUYMxmRWbHA5usGRdnSKJg47gzoGnD+9+', / not on the curve! / 'AI8beSdfWlDNYVockAYvAjbtomN9I6Zr+j09o/f/Gx2OAIr88YdNQKCV716JEbDVVMO7X6eNOHFDakG/zPQkW3d2', / ok / 'IygMA2ErCPvfEzKcRLt9ICI26frZKVbN5UoorFn51FVJhOAUvoBv8YSDaFBeuidtfdE9NhKL3p5OFcoA9hpn7w==', / not on the curve! / 'SK1a8SIvjjyZQUGRXa2pLzV5d/bqH0MLeQrAvFky6BoAl0TB7B9K7Y+p2y14qEwgSI6UqGCwa4jAxeiL6b8pFto=', / not on the curve! / 'AIpM5MTWLNf/BvcaLseBx1Cn5w7NmVCJubr+9s2AOYTudyhTWPGzRzGF3/G/AjfKY1T3cQzOWc+CFN4BV3gohyM=', / not on the curve! / 'ALC9GT5WbO1cQbGCGPfC7Jgrnxf4nUnL6att+Ut2LEhLAN2S36VvA2jVfQi7VA4/fF383vkfRyyN2ROiJekO8gmu', / ok / 'fo18bFMaiX1eQPBIv9HtKwS0Zlng69bZ3pbIlyB5oMhceaRWBQZnlGPWvbM+RpWCkf4l3km/WWcQuSSneeldfg==', / not on the curve! / 'APg6AAdqPF/8el8QfARKNKewuqiJodz4oK7v9DXlKphJJzTuCHzeV8+w3CrEIsr9SslMTzoVox39RHIL/HMSi74=', / not on the curve! / 'AKwPjAvakqEtszhRbWae0gPUC3+Gg7/GMAMNH3d6tcbAHvXKj+YY4UF/+9woqMTYTpTWkmkQcHA6k1vVqNJI2dw=', / not on the curve! / 'AMTWHCNxCKGe7+Ml7EmjLPCpkWmIZMaVcrDKOds+Ev0VE4IyuSVAyqa62QrN22giZLsJCc9CR1iFP2uxY10MhMo=', / ok / 'cGeG8rOatkcrsJFkHcJ7bU+BqCLJKY552oM1K6czHhxycnZaf/N3A2G+w/+WZaSCWS3P7zKKAXl090GAeBw4qA==', ]; for (let i = 0; i < keys.length; ++i) { try { const pubkey = new sjcl.ecc.elGamal.publicKey( sjcl.ecc.curves.c256, sjcl.codec.base64.toBits(keys[i]) ); console.log('OK', keys[i], pubkey); } catch(e) { console.log(e.message, keys[i]); } } Are there more parameters required to pass to the java key generator or the sjcl publickey constructor, or is there a bug in the sjcl parse? (if there are more parameters or different parameters required, maybe we can add a section to the wiki to show how to generate and export from java)

—You are receiving this because you are subscribed to this thread.Reply to this email directly, view it on GitHub, or mute the thread.