Skip to content

Cannot recover the correct public key from private keys #1

@samueltangz

Description

@samueltangz

Hi, I have been testing around with this library and found that the public key could not be correctly computed from the private keys.

import CryptoKit25519

let k1 = try! Curve25519.KeyAgreement.PrivateKey(rawRepresentation: Data([
  75, 157, 102, 134, 12, 57, 222, 49, 73, 43, 219, 59, 9, 5, 39, 191,
  102, 239, 30, 167, 95, 16, 91, 182, 248, 115, 40, 223, 187, 159, 227, 55]))
print("actual  ", Array(k1.publicKey.rawRepresentation))
print("expected", [30, 222, 35, 48, 128, 169, 48, 95, 101, 138, 236, 237, 7, 239, 4, 206, 211, 112, 181, 241, 187, 160, 153, 179, 171, 195, 158, 199, 180, 245, 168, 63])
// actual   [24, 233, 101, 77, 124, 166, 123, 38, 231, 73, 205, 242, 13, 207, 115, 34, 178, 98, 195, 39, 109, 223, 183, 78, 35, 64, 1, 165, 74, 213, 89, 46]
// expected [30, 222, 35, 48, 128, 169, 48, 95, 101, 138, 236, 237, 7, 239, 4, 206, 211, 112, 181, 241, 187, 160, 153, 179, 171, 195, 158, 199, 180, 245, 168, 63]

let k2 = try! Curve25519.KeyAgreement.PrivateKey(rawRepresentation: Data([
  0xc8, 0x06, 0x43, 0x9d, 0xc9, 0xd2, 0xc4, 0x76, 0xff, 0xed, 0x8f, 0x25, 0x80, 0xc0, 0x88, 0x8d,
  0x58, 0xab, 0x40, 0x6b, 0xf7, 0xae, 0x36, 0x98, 0x87, 0x90, 0x21, 0xb9, 0x6b, 0xb4, 0xbf, 0x59]))
print("actual  ", Array(k2.publicKey.rawRepresentation))
print("expected", [
  0x1b, 0xb7, 0x59, 0x66, 0xf2, 0xe9, 0x3a, 0x36, 0x91, 0xdf, 0xff, 0x94, 0x2b, 0xb2, 0xa4, 0x66,
  0xa1, 0xc0, 0x8b, 0x8d, 0x78, 0xca, 0x3f, 0x4d, 0x6d, 0xf8, 0xb8, 0xbf, 0xa2, 0xe4, 0xee, 0x28])
// actual   [27, 183, 89, 102, 242, 233, 58, 54, 145, 223, 255, 148, 43, 178, 164, 102, 161, 192, 139, 141, 120, 202, 63, 77, 109, 248, 184, 191, 162, 228, 238, 40]
// expected [27, 183, 89, 102, 242, 233, 58, 54, 145, 223, 255, 148, 43, 178, 164, 102, 161, 192, 139, 141, 120, 202, 63, 77, 109, 248, 184, 191, 162, 228, 238, 40]

The two test vectors are, respectively, extracted from test vector from Noise protocol, and the test case given in Curve25519 package.

(First test vector)
Private key: 4b9d66860c39de31492bdb3b090527bf66ef1ea75f105bb6f87328dfbb9fe337
Public key:  1ede233080a9305f658aeced07ef04ced370b5f1bba099b3abc39ec7b4f5a83f

The cause is, some of the bits in the secret key must be unset (and some otherwise need to be set) before computation:

func normalize(secretKey: [UInt8]) -> [UInt8] {
  var newSecretKey = secretKey
  newSecretKey[0] &= 0xf8
  newSecretKey[31] &= 0x3f
  newSecretKey[31] |= 0x40
  return newSecretKey
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions