Wednesday, July 15, 2020

Bringing Together the Last 3 Cryptography Posts


The ATECC508A[0] is a cryptographic authentication chip developed by MicroChip Technology. A PCB that makes the ATECC508A’s pins easily accessible was developed by Pete Lewis at SparkFun (1).

In this tutorial, the 64 byte uncompressed NIST P256 / Curve P-256 / secp256r1 / prime256v1 public key represented by a hex array grouped by byte [for a comparison see [2]).

An example public key is:

uint8_t publicKey[64] = {
0xF9, 0xC3, 0x6F, 0x89, 0x64, 0x62, 0x33, 0x78, 0xBD, 0xC0, 0x68, 0xD4, 0xBC, 0xE0, 0x7E, 0xD1,
0x7C, 0x8F, 0xA4, 0x86, 0xF9, 0xAC, 0x0C, 0x26, 0x13, 0xCA, 0x3C, 0x8C, 0x30, 0x6D, 0x7B, 0xB6,
0x1C, 0xD3, 0x67, 0x17, 0xB8, 0xAC, 0x5E, 0x4F, 0xEA, 0x8A, 0xD2, 0x3D, 0xC8, 0xD0, 0x78, 0x3C,
0x23, 0x18, 0xEE, 0x4A, 0xD7, 0xA8, 0x0D, 0xB6, 0xE0, 0x02, 0x6A, 0xD0, 0xB0, 0x72, 0xA2, 0x4F
};


When working with a few cryptography libraries both 3rd party, and those produced by the manufacturer of the ATECC508A, MicroChipTech, I discovered a library called CryptoAuthTools.

In a file called ecdh.py in the CryptoAuthTools library [3], I found out about the structure of the data:

# Convert device public key to a cryptography public key object
    device_pub = ec.EllipticCurvePublicNumbers(
        curve=ec.SECP256R1(),
        x=int_from_bytes(device_pub[0:32], byteorder='big'),
        y=int_from_bytes(device_pub[32:64], byteorder='big'),
    ).public_key(default_backend())

The public key is a point. From the literature, I infer this is the uncompressed form. In Practical Cryptography for Developers, “The public keys in the ECC are EC points - pairs of integer coordinates {x, y}, laying on the curve.
Due to their special properties, EC points can be compressed to just one coordinate + 1 bit (odd or even). Thus the compressed public key, corresponding to a 256-bit ECC private key, is a 257-bit integer.”.

Further, to broaden understanding and utilize more literature I can look at the Koblitz curve behind Bitcoin, secp256k1 and compare it to secp256rl. In Bjoernsen’s paper [4], “The main difference between secp256k1 and secp256r1 is that secp256k1 is a Koblitz curve, while secp256r1 is a prime field curve. Koblitz curves are generally known to be a few bits weaker than prime field curves, but when talking about 256-bit curves, it has little impact.

Both secp256rl and secp256k1 are elliptic curves. These Elliptic curves have a Generator point G and an Order n for their key-pair.
An ECDSA key-pair consists of a private key which is an integer and a public key which is an elliptic curve point [7].
The relation between the public key and private key is (public key) = (private key) * G .
P-256 is the same as secp256rl according to Mrinal Wadhwa’s presentation [5]. The curve parameters, including the generator point and order n, for secp256rl are described in section D.1.2.3 and D.2.3 Curve P-256 in the FIPS PUB 186-4 : Digital Signature Standard (DSS) (page 100 and 102) [6].

A secp256rl public key can be encoded as a uncompressed public key with a 0x04 prefix or a compressed public key with an 0x03 or 0x02 prefix with the fast ecdsa library [8].

Due to the nature of the ECC curve, only one coordinate from the public key needs to be stored. It becomes a compressed public key. In technical terms: “ The public key EC point {x, y} can be compressed to just one of the coordinates + 1 bit (parity). For the secp256k1 curve, the private key is 256-bit integer (32 bytes) and the compressed public key is 257-bit integer (~ 33 bytes) [7].

The difference between the public and private key is described:
“public key: A coordinate that corresponds to a private key, but does not need to be kept secret.
A public key can be calculated from a private key, but not vice versa. A public key can be used to determine
if a signature is genuine by using ECDSA to validate that a signature was generated by the private key that corresponds
to the public key that has been proffered, without requiring the private key to be divulged. In Bitcoin, public keys are either compressed or uncompressed. Compressed public keys are 33 bytes, consisting of a prefix either 0x02 or 0x03, and a 256-bit integer called x. Uncompressed keys are 65 bytes, consisting of constant prefix (0x04), followed by two 256-bit integers called x and y (2 * 32 bytes). The prefix of a compressed key allows for the y value to be derived from the x value.” [9]

More information about ECC, including graphical explanations, can be found at [10].


I would like to do two things. One is to import the public key from the crpyto chip into a library hosted on my laptop. Two is to import the signed message and original message and verify it with the public key. I believe that a bridge to the answer to this starts with examining the "ECDSA Sign" and "ECDSA Verify Signature" sections in [7]

Early attempts at importing the public key with fastecdsa were unsuccessful. The points were not on the curve.


See:
https://gist.github.com/bshambaugh/6f0fe5a63f96b0e0a95b404cc103e9c4
Okay, it works now:
https://forum.sparkfun.com/viewtopic.php?f=102&t=53408&p=217284#p217284

The message and the signed message are as follows:

uint8_t message[32] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
};

uint8_t signature[64] = {
0xD1, 0x84, 0x7E, 0x48, 0xD1, 0x40, 0x52, 0x87, 0xFF, 0x97, 0x49, 0x65, 0x66, 0x7D, 0x57, 0xE7,
0xF4, 0x38, 0xF2, 0x02, 0xA9, 0x8C, 0x9D, 0x17, 0x27, 0x5C, 0x59, 0x92, 0x2D, 0x12, 0x2B, 0xE7,
0xF9, 0x0D, 0x7A, 0x68, 0xB1, 0x6A, 0xB0, 0x5D, 0x47, 0x2C, 0x59, 0x1A, 0xDF, 0xC3, 0xCA, 0x77,
0x20, 0x4E, 0xC6, 0xAB, 0x8A, 0xC7, 0x99, 0x53, 0xE5, 0x14, 0xD2, 0x82, 0x04, 0x4F, 0x50, 0xB9
};

[0] http://ww1.microchip.com/downloads/en/DeviceDoc/20005928A.pdf





Tuesday, July 14, 2020

scratch work for cryptography 3

The ATECC508A is in the SparkFun Tutorial (1). This tutorial outputs a 64 byte public key as a hex string grouped by byte (for the form, see 2).

An example public key is:

uint8_t publicKey[64] = {
0xF9, 0xC3, 0x6F, 0x89, 0x64, 0x62, 0x33, 0x78, 0xBD, 0xC0, 0x68, 0xD4, 0xBC, 0xE0, 0x7E, 0xD1,
0x7C, 0x8F, 0xA4, 0x86, 0xF9, 0xAC, 0x0C, 0x26, 0x13, 0xCA, 0x3C, 0x8C, 0x30, 0x6D, 0x7B, 0xB6,
0x1C, 0xD3, 0x67, 0x17, 0xB8, 0xAC, 0x5E, 0x4F, 0xEA, 0x8A, 0xD2, 0x3D, 0xC8, 0xD0, 0x78, 0x3C,
0x23, 0x18, 0xEE, 0x4A, 0xD7, 0xA8, 0x0D, 0xB6, 0xE0, 0x02, 0x6A, 0xD0, 0xB0, 0x72, 0xA2, 0x4F
};


When working with a few cryptography libraries both 3rd party and those produced by the manufacturer I discovered a library called CryptoAuthTools.

In a filed called ecdh.py in the CryptoAuthTools library I found out about the structure of the data.

    # Convert device public key to a cryptography public key object
    device_pub = ec.EllipticCurvePublicNumbers(
        curve=ec.SECP256R1(),
        x=int_from_bytes(device_pub[0:32], byteorder='big'),
        y=int_from_bytes(device_pub[32:64], byteorder='big'),
    ).public_key(default_backend())


https://github.com/MicrochipTech/cryptoauthtools/blob/master/python/examples/ecdh.py#L101-L105


I noticed that the first 32 (or 33 bytes?) represented the x par of the key and the last 32 (or 31 bytes?) represented the y part of the key.

It is a curve over a prime field with:


Order n =
115792089210356248762697446949407573530086143415290314195533631308867097853951

and generator points

G x = 6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296





and



G y = 4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5




but really the generator points can be anything as long as they are of order n.

These bytes are in the P-256 curve referenced in the ATECC508A data sheet and described mathematically in the Digital Signature Standard.

https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf


(1)https://www.sparkfun.com/products/15573(2) https://cryptii.com/pipes/base64-to-hex

Other key [it looks like R34-35 and ecc608a] -- R34-35 uses a CryptoChip.
https://www.mouser.com/datasheet/2/268/SAMR34-R35-Low-Power-LoRa-Sub-GHz-SiP-Data-Sheet-D-1507280.pdf

https://github.com/MicrochipTech/atsamr34_ecc608a_actility

https://www.microchip.com/Developmenttools/ProductDetails/DM320111