Public Key Extraction in Implicit Certificates (ECQV)

biscas <[email protected]> Tue, 16 Jul 2019 07:29:41 -0500 (CDT)
Newsgroups gmane.comp.encryption.bouncy-castle.devel
Message-ID <[email protected]>
Hi All,

I am currently using BouncyCastle 1.61 to create an application to generate
Implicit Certificates  (see
https://en.wikipedia.org/wiki/Implicit_certificate) and sign messages as
well as an application to extract the ECDSA Public Key, and verify the ECDSA
signature.

The goal is to use the application to generate Implicit Certificates AND
Signatures (it is a strange use case) so that devices in the field are able
to verify the ECDSA signature. 
The applications so far developed are working correctly against each other
that is:
1. The Verifier Application is able to extract the ECDSA Public Key from an
implicit certificate computed by the Signer Application.
2. The Verifier Application is then able to verify the ECDSA Signature.

Moreover:
3. the Verifier Application is able to extract ECDSA Public Keys and verify
signatures from third-parties.

However the devices themselves when receiving an implicit certificate
generated by the Signer Application are not able to extract the correct
ECDSA Public Key. We are absolutely sure that this is not due to the Hash
computations, as the implicit certificate hashes are correctly computed.
Given 1. 2. and 3. we are also quite sure that from the algorithmic point of
view the Verifier application is mathematically correct.
In particular Public Key extraction is done in BouncyCastle 1.61, where
CURVE = new SecT163K1Curve() by:

ECPoint certPublicKey = CURVE.decodePoint(publicReconstKey);

//CryptoClassUtils.matyasMeyersOseasHashing is the chosen hashing function
that returns a 16 byte //array, so well within floor(Log_2(CURVE.getN())))
byte[] hash = CryptoClassUtils.matyasMeyersOseasHashing(implicitCert));         
BigInteger ECDSA_SIGNING_CERTIFICATE_HASH = new BigInteger(1,hash);

ECPoint ecdsaPublicKey = certPublicKey
                .multiply(ECDSA_SIGNING_CERTIFICATE_HASH)
                .add(CURVE.decodePoint(caPublicKey));

Now, given this I wonder whether there is some encoding/decoding regarding
compressed points. For instance:

With:

implicitCert = {0x02, 0x03, 0x7f, 0xf5, 0x63, 0x64, 0x52, 0x15, 0x78, 0xf3,
0x09, 0xf4, 0x70, 0x39, 0x24, 0x1a, 0xa4, 0xf2, 0xac, 0x30, 0x72, 0x66,
0x00, 0x0f, 0x93, 0xff, 0xfd, 0x03, 0x06, 0x9e, 0x54, 0x45, 0x53, 0x54,
0x53, 0x45, 0x43, 0x41, 0x01, 0x09, 0x00, 0x00, 0x10, 0x63, 0x00, 0x00,
0x00, 0x00};

caPublicKey = {0x03, 0x00, 0x86, 0x0b, 0xda, 0x66, 0xb4, 0xf0, 0xb9, 0x2c,
0x7c, 0xac, 0x1c, 0xaa, 0xb5, 0x15, 0xac, 0x78, 0xda, 0x80, 0xa0, 0x89};

publicReconstrKey = {0x02, 0x03, 0x7f, 0xf5, 0x63, 0x64, 0x52, 0x15, 0x78,
0xf3, 0x09, 0xf4, 0x70, 0x39, 0x24, 0x1a, 0xa4, 0xf2, 0xac, 0x30, 0x72,
0x66};

hash = {0x4b, 0x1a, 0x9c, 0xb5, 0xfa, 0x64, 0x8a, 0x6a, 0x75, 0x20, 0xff,
0x19, 0x6c, 0x68, 0x08, 0x5d};

ECDSA_SIGNING_CERTIFICATE_HASH = 99830277875878979416225826737509369949;

The developed Verifier will output ECDSA Public Key:

ecdsaPublicKey = {0x02, 0x07, 0xb2, 0xcb, 0xfd, 0x35, 0xa2, 0x38, 0x01,
0xdc, 0x65, 0x3e, 0x54, 0x0d, 0x75, 0x89, 0x4e, 0xec, 0x23, 0x74, 0xa3,
0x1c}

Certicom's Public Key Extraction algorithms will output instead:

ecdsaPublicKeyByCerticom = {0x02,0x00,0x2F,0x4A,0x8C,0xE8,0xAB,
0xCA,0xAE,0x3A,0x56,0xAC, 0x5E, 0xD1, 0x54, 0xE9, 0x5E, 0xE8, 0x5D, 0xDF,
0x77, 0xE4};

This behaviour is completely deterministic. 

At this moment all I suspect is some kind of issue on encoding/decoding
elliptic curve points on these curves against Certicom's implementation. Do
you guys have any past experience integrating elliptic curve crypto against
Certicom's libs, specially those used in ZigBee?

Kindly,

Manuel 













--
Sent from: http://bouncy-castle.1462172.n4.nabble.com/Bouncy-Castle-Dev-f1462173.html