github.com/emmansun/gmsm@v0.29.1/internal/sm2ec/sm2p256_mqv.go (about)

     1  package sm2ec
     2  
     3  import (
     4  	"encoding/binary"
     5  	"errors"
     6  	"math/bits"
     7  )
     8  
     9  var p256Order = [4]uint64{0x53bbf40939d54123, 0x7203df6b21c6052b,
    10  	0xffffffffffffffff, 0xfffffffeffffffff}
    11  
    12  func fromBytes(bytes []byte) (*[4]uint64, error) {
    13  	if len(bytes) != 32 {
    14  		return nil, errors.New("invalid scalar length")
    15  	}
    16  	var t [4]uint64
    17  	t[0] = binary.BigEndian.Uint64(bytes[24:])
    18  	t[1] = binary.BigEndian.Uint64(bytes[16:])
    19  	t[2] = binary.BigEndian.Uint64(bytes[8:])
    20  	t[3] = binary.BigEndian.Uint64(bytes)
    21  	return &t, nil
    22  }
    23  
    24  func toBytes(t *[4]uint64) []byte {
    25  	var bytes [32]byte
    26  
    27  	binary.BigEndian.PutUint64(bytes[:], t[3])
    28  	binary.BigEndian.PutUint64(bytes[8:], t[2])
    29  	binary.BigEndian.PutUint64(bytes[16:], t[1])
    30  	binary.BigEndian.PutUint64(bytes[24:], t[0])
    31  
    32  	return bytes[:]
    33  }
    34  
    35  // p256OrdAdd sets res = x + y.
    36  func p256OrdAdd(res, x, y *[4]uint64) {
    37  	var c, b uint64
    38  	t1 := make([]uint64, 4)
    39  	t1[0], c = bits.Add64(x[0], y[0], 0)
    40  	t1[1], c = bits.Add64(x[1], y[1], c)
    41  	t1[2], c = bits.Add64(x[2], y[2], c)
    42  	t1[3], c = bits.Add64(x[3], y[3], c)
    43  	t2 := make([]uint64, 4)
    44  	t2[0], b = bits.Sub64(t1[0], p256Order[0], 0)
    45  	t2[1], b = bits.Sub64(t1[1], p256Order[1], b)
    46  	t2[2], b = bits.Sub64(t1[2], p256Order[2], b)
    47  	t2[3], b = bits.Sub64(t1[3], p256Order[3], b)
    48  	// Three options:
    49  	//   - a+b < p
    50  	//     then c is 0, b is 1, and t1 is correct
    51  	//   - p <= a+b < 2^256
    52  	//     then c is 0, b is 0, and t2 is correct
    53  	//   - 2^256 <= a+b
    54  	//     then c is 1, b is 1, and t2 is correct
    55  	t2Mask := (c ^ b) - 1
    56  	res[0] = (t1[0] & ^t2Mask) | (t2[0] & t2Mask)
    57  	res[1] = (t1[1] & ^t2Mask) | (t2[1] & t2Mask)
    58  	res[2] = (t1[2] & ^t2Mask) | (t2[2] & t2Mask)
    59  	res[3] = (t1[3] & ^t2Mask) | (t2[3] & t2Mask)
    60  }
    61  
    62  func ImplicitSig(sPriv, ePriv, t []byte) ([]byte, error) {
    63  	mulRes, err := P256OrdMul(ePriv, t)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  	t1, err := fromBytes(mulRes)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	t2, err := fromBytes(sPriv)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	var t3 [4]uint64
    76  	p256OrdAdd(&t3, t1, t2)
    77  	return toBytes(&t3), nil
    78  }