SM9 (ShangMi #9), Chinese Standard GM/T 0044-2016, is a public-key algorithm based on elliptic curves and bilinear pairings. SM9 is based on the Elliptic Curve Discrete Logarithm Problem (ECDLP), which is considered computationally difficult to solve. The curve used in SM9 is BN256, which is a Weierstrass curve developed by Paulo S. L. M. Barreto (from Escola Politécnica da Universidade de São Paulo, Brazil) and Michael Naehrig (Microsoft). SM9 is used in security systems and identity-based public key infrastructure (IBE) and involves the following main steps: Key Generation, Digital Signature and Verification, and Secret Key Sharing.
The master key generation in the SM9 algorithm involves the creation of a master key \( D \) and a master public key \( Q \). The master key \( D \) is a random number \( k \), and the master public key \( Q \) is calculated as the point generated by scalar multiplication of the random number \( k \) with the base point \( P \). The process is as follows:
1. Input:
1.1. \( k \): Random number generated to be used as the master key.
1.2. \( P \): The base point of the elliptic curve.
2. Steps:
2.1. A random number \( k \) (master key \( D \)) is generated.
2.2. The public key \( Q \) is calculated as \( Q = k \cdot P \), where \( P \) is the base point of the curve.
In the SM9 algorithm, the private key \( d_u \) is generated as \( d_u = \left( \left( H_1(\text{UID}_A \parallel \text{HID}_A) + D \right)^{r-2} \mod r \right) \cdot D \).
Where:
1. \( \text{UID}_A \) is the unique identifier of user \( A \).
2. \( \text{HID}_A \) is the hierarchical identifier of user \( A \), used to indicate the user's hierarchy level or group within the SM9 system.
3. \( D \) is the master key.
4. \( r \) is the order of the group of the elliptic curve used in the algorithm.
5. \( H_1 \)(\( x \)) is a hash function applied to the input \( x \), generating a hash value suitable for the private key generation process.
Generate User Private Key:./edgetk -pkey setup -algorithm <sm9encrypt|sm9sign> -master "Master.pem" -pub "MasterPublic.pem"
Parse Keys:./edgetk -pkey keygen -algorithm <sm9encrypt|sm9sign> -master "Master.pem" -prv "Private.pem" -id "uid" -hid 1
./edgetk -pkey text -key "Master.pem" [-pass "passphrase"]
./edgetk -pkey text -key "Private.pem" [-pass "passphrase"]
./edgetk -pkey text -key "MasterPublic.pem"
The signing process in the SM9 algorithm involves signing a hash of the message with the user's private key \( d_u \). The algorithm is stochastic, meaning it uses a random value to ensure the signature is unique for each execution. The process is described as follows:
1. Input:
1.1. \( \text{hash} \): The hash of the message to be signed.
1.2. \( d_u \): The user's private key.
2. Steps:
2.1. Generate a random number \( r \).
2.2. Calculate \( w = r \cdot P \), where \( P \) is the base point of the elliptic curve.
2.3. Calculate \( h = H_2(\text{hash} \parallel w) \), using the hash function \( H_2 \) on the concatenation of `hash` and \( w \).
2.4. Adjust the value of \( r \) to \( r = r - h \mod r \).
2.5. Calculate \( s = r \cdot d_u \), where \( d_u \) is the user's private key.
2.6. Encode the signature in ASN.1 format, consisting of the values \( h \) and \( s \), and return it.
The signature verification is performed by the message receiver using the signer's master public key, the user identifier (UID), and the hierarchical user identifier (HID). The process is described as follows:
1. Input:
1.1. \( Q \): The signer's master public key.
1.2. \( \text{hash} \): The hash of the signed message.
1.3. \( \text{UID} \): The unique identifier of the user.
1.4. \( \text{HID} \): The hierarchical identifier of the user.
2. Steps:
2.1. Decode the signature to extract \( h \) and \( s \).
2.2. Check if \( h \) is not zero.
2.3. Calculate the user's public key \( p \) from the identifier: \( p = (H_1(\text{UID} \parallel \text{HID}) \cdot P) + Q \), where \( Q \) is the master public key.
2.4. Calculate the bilinear pairing \( u = e(s, p) \), where \( e \) is the bilinear pairing.
2.5. Calculate \( w = u + t \), where \( t = h \cdot P \), with \( P \) being the base point of the elliptic curve.
2.6. Calculate \( h_2 = H_2(\text{hash} \parallel w) \), using the hash function \( H_2 \), where \( \parallel \) indicates the concatenation of \( \text{hash} \) and \( w \).
2.7. If \( h_2 = h \), the signature is valid; otherwise, it is invalid.
Transmit the Signature:./edgetk -pkey sign -algorithm sm9signph -md sm3 -key "PrivateSign.pem" FILE > sign.txt
Verify Signature:sign=$(cat sign.txt|awk '{print $2}')
./edgetk -pkey verify -algorithm sm9signph -md sm3 -key "MasterSignPub.pem" -id "uid" -hid 3 -signature $sign FILE
echo $?
The key wrapping process in the SM9 algorithm creates a symmetric key \( K \) to protect the exchange of information, using the receiver's public key, a random number, and the user identifier.
1. Generate the symmetric key:
1.1. Generate a random number \( r \).
1.2. Calculate the user's public key \( p \) from the identifier: \( p = (H_1(\text{UID} \parallel \text{HID}) \cdot P) + Q \), where \( Q \) is the master public key.
1.3. Calculate the encrypted point \( C = r \cdot p \), where \( p \) is the user's public key.
1.4. Calculate \( w = r \cdot P \), where \( P \) is the base point of the elliptic curve.
1.5. Derive the symmetric key \( K = \text{KDF}(C \parallel w \parallel \text{UID}, kLen) \), where the user identifier is used to ensure uniqueness.
2. Transmission:
2.1. Package \( C \) to form the encrypted package.
The receiver uses their private key to recover the symmetric key \( K \) from the encrypted package \( C \).
1. Retrieve the symmetric key:
1.1. Calculate \( w = e(C, d_u) \), where \( d_u \) is the user's private key, using the pairing operation.
1.2. Derive the symmetric key \( K = \text{KDF}(C \parallel w \parallel \text{UID}, kLen) \).
2. Assignments:
2.1. The key \( K \) can be used for encryption or decryption.
Transmit the Ciphertext:./edgetk -pkey wrapkey -algorithm sm9encrypt -key "MasterPub.pem" -id "uid" -hid 3 [-bits 256] > cipher.txt
Unwrap Secret Key:ciphertext=$(cat cipher.txt|grep "Cipher"|awk '{print $2}')
./edgetk -pkey unwrapkey -algorithm sm9encrypt -key "PrivateKey.pem" -id "uid" [-bits 256] -cipher $ciphertext
Copyright (c) 2024 Pedro F. Albanese <pedroalbanese@hotmail.com>
Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.