How to properly parametrize a SECP256K1 curve using the SE051 IoT SDK?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to properly parametrize a SECP256K1 curve using the SE051 IoT SDK?

Jump to solution
335 Views
rupp_SCD
Contributor II

in order to use an elliptic curve such as the SECP256K1 curve (used by Bitcoin or Ethereum) in a SE051 IoT secure element(NXP) , it is required to firstly create that curve and to parametrize it using the function `SetECCurveParam`

NXP documentation doesn't say much about the parametrization in itself, only that all the parameters from the curve must be set one after the others (apparently without a precise order) and once the last parameter is received, the card will return the final status: Ok (0x9000) if all the parameters are valid, or an error message otherwise (something else than 0x9000)

The five parameters are defined as such:

 

 

 

CURVE_PARAM_A 0x01

CURVE_PARAM_B 0x02

CURVE_PARAM_G 0x04

CURVE_PARAM_N 0x08

CURVE_PARAM_PRIME 0x10

 

 

 



This should be explicit enough:
A is the 'A' parameter in the reduced Weierstrass form of the curve (y^2 = x^3 + Ax + B)
B is the 'B' parameter in the reduced Weierstrass form of the curve (y^2 = x^3 + Ax + B)
G is the base point of the curve
N is the order of the base point
PRIME is the order of F_p on which the curve is based

I end with this



 

 

 

byte PRIME[]={ 0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFE ,0xFF,0xFF,0xFC,0x2F};

byte A[] ={0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00};

byte B[] ={0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x07};

//uncompressed
byte G[]={0x04 ,0x79,0xBE,0x66,0x7E ,0xF9,0xDC,0xBB,0xAC ,0x55,0xA0,0x62,0x95 ,0xCE,0x87,0x0B,0x07 ,0x02,0x9B,0xFC,0xDB ,0x2D,0xCE,0x28,0xD9 ,0x59,0xF2,0x81,0x5B ,0x16,0xF8,0x17,0x98 ,0x48,0x3A,0xDA,0x77 ,0x26,0xA3,0xC4,0x65 ,0x5D,0xA4,0xFB,0xFC ,0x0E,0x11,0x08,0xA8 ,0xFD,0x17,0xB4,0x48 ,0xA6,0x85,0x54,0x19 ,0x9C,0x47,0xD0,0x8F ,0xFB,0x10,0xD4,0xB8};
//compressed
//byte G[]={0x02 ,0x79,0xBE,0x66,0x7E ,0xF9,0xDC,0xBB,0xAC ,0x55,0xA0,0x62,0x95 ,0xCE,0x87,0x0B,0x07 ,0x02,0x9B,0xFC,0xDB ,0x2D,0xCE,0x28,0xD9 ,0x59,0xF2,0x81,0x5B ,0x16,0xF8,0x17,0x98};

byte n[] = {0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFF ,0xFF,0xFF,0xFF,0xFE ,0xBA,0xAE,0xDC,0xE6 ,0xAF,0x48,0xA0,0x3B ,0xBFD,0x25,0xE8,0xC ,0xD0,0x36,0x41,0x41};

 

 

 

for these values (G compressed or uncompressed) I receive '0x6985' after the last parameter, indicating something is wrong. However, the parameters for SECP256K1 are well-known and after checking again and again I cannot see the reason for the error. It is also not an endianness issue.


Does someone have experienced a similar issue with the SE051 and what can be wrong there?

0 Kudos
1 Solution
272 Views
rupp_SCD
Contributor II

Thanks, Kan, for your eagle's eye and seeing the wrong byte among so many others.

View solution in original post

0 Kudos
5 Replies
273 Views
rupp_SCD
Contributor II

Thanks, Kan, for your eagle's eye and seeing the wrong byte among so many others.

0 Kudos
304 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi @rupp_SCD ,

 

Actually the MW shall have these parameters already built in. When you write/generate a key of this any curve the MW checks if the curve is available and if not, creates it automatically first(For SSS APIs only). For example, if you run the demo of ex_ecc, you may change the kSSS_CipherType_EC_NIST_P to kSSS_CipherType_EC_NIST_K, and have the following parameters setup automatically. 

APDU :DEBUG:ReadECCurveList []
smCom :DEBUG:H> (Len=4)
01 00 00 05
smCom :DEBUG:Tx> (Len=5)
80 02 0B 25 00
smCom :DEBUG:<H (Len=4)
01 00 00 17
smCom :DEBUG:<Rx (Len=23)
41 82 00 11 02 01 02 01 02 01 01 01 01 01 01 01
01 01 01 01 01 90 00

APDU :DEBUG:CreateECCurve []
APDU :DEBUG:kSE05x_TAG_1 [curve id] = 0x10
smCom :DEBUG:H> (Len=4)
01 00 00 08
smCom :DEBUG:Tx> (Len=8)
80 01 0B 04 03 41 01 10
smCom :DEBUG:<H (Len=4)
01 00 00 02
smCom :DEBUG:<Rx (Len=2)
90 00

APDU :DEBUG:SetECCurveParam []
APDU :DEBUG:kSE05x_TAG_1 [curve id] = 0x10
APDU :DEBUG:kSE05x_TAG_2 [ecCurveParam] = 0x1
APDU :DEBUG:kSE05x_TAG_3 [inputData] (Len=32)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
smCom :DEBUG:H> (Len=4)
01 00 00 2D
smCom :DEBUG:Tx> (Len=45)
80 01 0B 40 28 41 01 10 42 01 01 43 20 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00
smCom :DEBUG:<H (Len=4)
01 00 00 02
smCom :DEBUG:<Rx (Len=2)
90 00

APDU :DEBUG:SetECCurveParam []
APDU :DEBUG:kSE05x_TAG_1 [curve id] = 0x10
APDU :DEBUG:kSE05x_TAG_2 [ecCurveParam] = 0x2
APDU :DEBUG:kSE05x_TAG_3 [inputData] (Len=32)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07
smCom :DEBUG:H> (Len=4)
01 00 00 2D
smCom :DEBUG:Tx> (Len=45)
80 01 0B 40 28 41 01 10 42 01 02 43 20 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 07
smCom :DEBUG:<H (Len=4)
01 00 00 02
smCom :DEBUG:<Rx (Len=2)
90 00

APDU :DEBUG:SetECCurveParam []
APDU :DEBUG:kSE05x_TAG_1 [curve id] = 0x10
APDU :DEBUG:kSE05x_TAG_2 [ecCurveParam] = 0x4
APDU :DEBUG:kSE05x_TAG_3 [inputData] (Len=65)
04 79 BE 66 7E F9 DC BB AC 55 A0 62 95 CE 87 0B
07 02 9B FC DB 2D CE 28 D9 59 F2 81 5B 16 F8 17
98 48 3A DA 77 26 A3 C4 65 5D A4 FB FC 0E 11 08
A8 FD 17 B4 48 A6 85 54 19 9C 47 D0 8F FB 10 D4
B8
smCom :DEBUG:H> (Len=4)
01 00 00 4E
smCom :DEBUG:Tx> (Len=78)
80 01 0B 40 49 41 01 10 42 01 04 43 41 04 79 BE
66 7E F9 DC BB AC 55 A0 62 95 CE 87 0B 07 02 9B
FC DB 2D CE 28 D9 59 F2 81 5B 16 F8 17 98 48 3A
DA 77 26 A3 C4 65 5D A4 FB FC 0E 11 08 A8 FD 17
B4 48 A6 85 54 19 9C 47 D0 8F FB 10 D4 B8
smCom :DEBUG:<H (Len=4)
01 00 00 02
smCom :DEBUG:<Rx (Len=2)
90 00

APDU :DEBUG:SetECCurveParam []
APDU :DEBUG:kSE05x_TAG_1 [curve id] = 0x10
APDU :DEBUG:kSE05x_TAG_2 [ecCurveParam] = 0x8
APDU :DEBUG:kSE05x_TAG_3 [inputData] (Len=32)
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FE
BA AE DC E6 AF 48 A0 3B BF D2 5E 8C D0 36 41 41
smCom :DEBUG:H> (Len=4)
01 00 00 2D
smCom :DEBUG:Tx> (Len=45)
80 01 0B 40 28 41 01 10 42 01 08 43 20 FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FE BA AE DC
E6 AF 48 A0 3B BF D2 5E 8C D0 36 41 41
smCom :DEBUG:<H (Len=4)
01 00 00 02
smCom :DEBUG:<Rx (Len=2)
90 00

APDU :DEBUG:SetECCurveParam []
APDU :DEBUG:kSE05x_TAG_1 [curve id] = 0x10
APDU :DEBUG:kSE05x_TAG_2 [ecCurveParam] = 0x10
APDU :DEBUG:kSE05x_TAG_3 [inputData] (Len=32)
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FE FF FF FC 2F
smCom :DEBUG:H> (Len=4)
01 00 00 2D
smCom :DEBUG:Tx> (Len=45)
80 01 0B 40 28 41 01 10 42 01 10 43 20 FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FE FF FF FC 2F
smCom :DEBUG:<H (Len=4)
01 00 00 02
smCom :DEBUG:<Rx (Len=2)
90 00

 

Hope that helps,

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
300 Views
rupp_SCD
Contributor II

hi Kan, I am not using the NXP MW, we use a custom MW that we developed ourselves. 

However, the APDU flow is exactly the same as the one you posted:

as you can see first the curve is created then all 5 parameters are set, when the last one is inputted, it returns 0x6985. 

 

---------------------------------------------------------------------------
------SECP256K1 CURVE CREATION AND PARAMETRIZATION (SECURE CHANNEL)--------
---------------------------------------------------------------------------
wrapping apdu session=0:
80 01 0B 04 03 410110
[00:00:00.651,000] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 04 18 D6 D1 5B 7E 1C 42 A3 48 7D 9B D2 34 97 8D A4 9D EA 89 D1 B5 E6 EC A5 35 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 28 41011042010143200000000000000000000000000000000000000000000000000000000000000000
[00:00:08.443,511] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 38 B1 89 12 0D 05 E1 EC FC 11 A5 AD 8C 9C 8A 43 89 2F 6A 0B B5 E9 20 35 D5 F3 CB 7A 0F 01 3F 1C 5F C0 C5 90 15 CD E4 9F 6C 25 D7 C2 75 98 1B BB 34 70 1D 69 78 08 52 3C 3B 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 28 41011042010243200000000000000000000000000000000000000000000000000000000000000007
[00:00:10.111,602] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 38 B8 F2 2C DE E5 37 38 2F DB 92 29 E1 E6 73 9F CC 36 B6 85 AD F2 D7 59 9D 6F 2B BB C3 FC 04 7E F2 D3 92 47 25 37 EF 49 4A 83 22 42 06 90 1B C3 8E 2C E4 C9 58 64 EB 07 4D 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 49 41011042010443410479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
[00:00:11.771,026] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 58 43 FB 13 5E DE 51 6B D7 05 B5 12 CE 97 46 ED 16 68 01 9E A4 D7 85 F3 FA 0A A2 FA CB 20 31 CE F3 1A BC 72 9E DF 01 5A AE FF 39 C0 04 21 51 E5 49 33 58 90 B9 40 78 80 02 08 06 09 08 52 63 E4 BD 28 30 40 4A 41 8B 94 11 E5 88 69 A6 CD F3 31 8F 58 CF 7A 95 77 25 E0 68 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 28 4101104201084320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BFD25E80CD0364141
[00:00:15.862,579] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 38 F6 C6 9A 62 87 8C E8 6A 67 44 A6 45 FC DD 10 38 89 30 73 55 3A 71 21 FD FE C3 53 43 B4 51 A6 C7 2E C5 35 74 84 0F D9 D5 77 6E 86 3B F6 E6 1E A2 9E 48 6E 2D 50 61 AC 20 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 28 4101104201104320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
[00:00:17.591,583] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 38 A1 6B 2F FC 85 BB 4F A4 02 76 A0 77 5E 75 9C DC B0 6C 7D 15 25 51 A2 87 05 3D AC CB 45 00 58 53 10 48 5F 51 35 67 AC B7 8F D6 44 A6 FD E8 D8 42 1A 74 9B B8 F0 28 67 6A 00
<-- 69 85
SW1SW2 = 69 85
error parametrizing SECP256K1 curve

0 Kudos
277 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi @rupp_SCD ,

 

Actually supporting a custom MW is out of my service range, but I think your issue is due to the parameter N you provided for SECP256K1, there was one byte split in the end, which should be "BF D2 5E 8C D0 36 41 41".

Kan_Li_0-1708410168246.png

 

Hope that helps,

 

Have a great day,
Kan


-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

 

 

 

0 Kudos
275 Views
rupp_SCD
Contributor II

yes that was the reason, I checked the bytes array twice but did not spot that problem

 

---------------------------------------------------------------------------
------SECP256K1 CURVE CREATION AND PARAMETRIZATION (SECURE CHANNEL)--------
---------------------------------------------------------------------------
wrapping apdu session=0:
80 01 0B 04 03 410110
[00:00:00.704,711] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 04 18 5E EA 4B B5 D3 60 E9 C3 B3 C9 BC B7 9B 87 51 F4 CB AB 57 5A 37 A5 B2 92 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 28 41011042010143200000000000000000000000000000000000000000000000000000000000000000
[00:00:06.724,487] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 38 91 9B 02 78 53 57 55 7F 06 C4 81 D5 46 8D 9E B2 82 6F 34 2C 41 40 0F 73 04 9A EE 3D 8F DF 66 D6 48 D7 1B 13 C4 DC B7 9A 02 48 7F A8 B1 8B 8F A7 AE 4F DC 90 7D 34 42 AC 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 28 41011042010243200000000000000000000000000000000000000000000000000000000000000007
[00:00:08.151,428] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 38 26 5A F4 2B D7 DC 89 B0 12 BC 80 FB 44 A4 3A 74 CC 04 A6 86 A2 74 5C ED D2 42 3C 31 E9 48 CD 47 61 C1 90 19 C5 37 2E B3 8A 6A 6C 1F 86 04 68 58 C1 87 71 F4 99 45 D8 E3 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 49 41011042010443410479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
[00:00:09.613,037] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 58 D4 9B B3 61 11 43 45 60 61 DB F4 ED 61 C1 40 71 FA C6 20 38 0A F1 B7 5A 58 65 1C 43 D1 7C 58 7C 5C 4F 07 09 FD 72 ED 80 88 84 A6 6A 56 DB 54 A6 0E 86 AE 96 14 AF 5B 16 9F FE 4D 3F 5C 8A BD 07 6A 29 5F AD 2D B8 7B ED 2D B5 EE 45 33 3D AB D7 DE F2 59 F1 5E 92 47 A4 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 28 4101104201084320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
[00:00:11.267,456] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 38 A5 DB CC 0F CD AC 9C 26 4C 69 71 F2 87 7C 72 35 70 E2 3A CE 97 9D F6 AD 41 F7 28 09 E4 3D 8C 44 B5 A7 DF C9 13 AC 65 D8 8E 63 F4 0D 82 D9 7A 6C 64 A3 B9 50 FE 5D 41 A1 00
<-- 90 00
SW1SW2 = 90 00
wrapping apdu session=0:
80 01 0B 40 28 4101104201104320FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
[00:00:12.829,772] <inf> main: 16 bytes were generated by CMAC

--> 84 01 0B 40 38 AB CF 61 DA 46 35 72 FC 8F 74 5A DA 3B FE 7E F1 CD A2 2C 90 81 58 40 81 53 CA A4 F9 62 7B C7 FD 7C 6B 4E B4 DE 35 96 FF 9C 5B 61 A0 C3 66 F1 02 4E 6B A1 13 27 D2 81 BA 00
<-- 90 00
SW1SW2 = 90 00

0 Kudos