github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/ECDH.go (about)

     1  /*
     2  Licensed to the Apache Software Foundation (ASF) under one
     3  or more contributor license agreements.  See the NOTICE file
     4  distributed with this work for additional information
     5  regarding copyright ownership.  The ASF licenses this file
     6  to you under the Apache License, Version 2.0 (the
     7  "License"); you may not use this file except in compliance
     8  with the License.  You may obtain a copy of the License at
     9  
    10    http://www.apache.org/licenses/LICENSE-2.0
    11  
    12  Unless required by applicable law or agreed to in writing,
    13  software distributed under the License is distributed on an
    14  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15  KIND, either express or implied.  See the License for the
    16  specific language governing permissions and limitations
    17  under the License.
    18  */
    19  
    20  /* Elliptic Curve API high-level functions  */
    21  
    22  package FP256BN
    23  
    24  import "github.com/hellobchain/third_party/hyperledger/fabric-amcl/amcl"
    25  
    26  const INVALID_PUBLIC_KEY int = -2
    27  const ERROR int = -3
    28  const INVALID int = -4
    29  const EFS int = int(MODBYTES)
    30  const EGS int = int(MODBYTES)
    31  
    32  //const EAS int=16
    33  //const EBS int=16
    34  
    35  //const ECDH_HASH_TYPE int=amcl.SHA512
    36  
    37  /* Convert Integer to n-byte array */
    38  func inttoBytes(n int, len int) []byte {
    39  	var b []byte
    40  	var i int
    41  	for i = 0; i < len; i++ {
    42  		b = append(b, 0)
    43  	}
    44  	i = len
    45  	for n > 0 && i > 0 {
    46  		i--
    47  		b[i] = byte(n & 0xff)
    48  		n /= 256
    49  	}
    50  	return b
    51  }
    52  
    53  func ehashit(sha int, A []byte, n int, B []byte, pad int) []byte {
    54  	var R []byte
    55  	if sha == amcl.SHA256 {
    56  		H := amcl.NewHASH256()
    57  		H.Process_array(A)
    58  		if n > 0 {
    59  			H.Process_num(int32(n))
    60  		}
    61  		if B != nil {
    62  			H.Process_array(B)
    63  		}
    64  		R = H.Hash()
    65  	}
    66  	if sha == amcl.SHA384 {
    67  		H := amcl.NewHASH384()
    68  		H.Process_array(A)
    69  		if n > 0 {
    70  			H.Process_num(int32(n))
    71  		}
    72  		if B != nil {
    73  			H.Process_array(B)
    74  		}
    75  		R = H.Hash()
    76  	}
    77  	if sha == amcl.SHA512 {
    78  		H := amcl.NewHASH512()
    79  		H.Process_array(A)
    80  		if n > 0 {
    81  			H.Process_num(int32(n))
    82  		}
    83  		if B != nil {
    84  			H.Process_array(B)
    85  		}
    86  		R = H.Hash()
    87  	}
    88  	if R == nil {
    89  		return nil
    90  	}
    91  
    92  	if pad == 0 {
    93  		return R
    94  	}
    95  	var W []byte
    96  	for i := 0; i < pad; i++ {
    97  		W = append(W, 0)
    98  	}
    99  	if pad <= sha {
   100  		for i := 0; i < pad; i++ {
   101  			W[i] = R[i]
   102  		}
   103  	} else {
   104  		for i := 0; i < sha; i++ {
   105  			W[i+pad-sha] = R[i]
   106  		}
   107  		for i := 0; i < pad-sha; i++ {
   108  			W[i] = 0
   109  		}
   110  
   111  		//for i:=0;i<sha;i++ {W[i]=R[i]}
   112  		//for i:=sha;i<pad;i++ {W[i]=0}
   113  	}
   114  	return W
   115  }
   116  
   117  /* Key Derivation Functions */
   118  /* Input octet Z */
   119  /* Output key of length olen */
   120  func ECDH_KDF1(sha int, Z []byte, olen int) []byte {
   121  	/* NOTE: the parameter olen is the length of the output K in bytes */
   122  	hlen := sha
   123  	var K []byte
   124  	k := 0
   125  
   126  	for i := 0; i < olen; i++ {
   127  		K = append(K, 0)
   128  	}
   129  
   130  	cthreshold := olen / hlen
   131  	if olen%hlen != 0 {
   132  		cthreshold++
   133  	}
   134  
   135  	for counter := 0; counter < cthreshold; counter++ {
   136  		B := ehashit(sha, Z, counter, nil, 0)
   137  		if k+hlen > olen {
   138  			for i := 0; i < olen%hlen; i++ {
   139  				K[k] = B[i]
   140  				k++
   141  			}
   142  		} else {
   143  			for i := 0; i < hlen; i++ {
   144  				K[k] = B[i]
   145  				k++
   146  			}
   147  		}
   148  	}
   149  	return K
   150  }
   151  
   152  func ECDH_KDF2(sha int, Z []byte, P []byte, olen int) []byte {
   153  	/* NOTE: the parameter olen is the length of the output k in bytes */
   154  	hlen := sha
   155  	var K []byte
   156  	k := 0
   157  
   158  	for i := 0; i < olen; i++ {
   159  		K = append(K, 0)
   160  	}
   161  
   162  	cthreshold := olen / hlen
   163  	if olen%hlen != 0 {
   164  		cthreshold++
   165  	}
   166  
   167  	for counter := 1; counter <= cthreshold; counter++ {
   168  		B := ehashit(sha, Z, counter, P, 0)
   169  		if k+hlen > olen {
   170  			for i := 0; i < olen%hlen; i++ {
   171  				K[k] = B[i]
   172  				k++
   173  			}
   174  		} else {
   175  			for i := 0; i < hlen; i++ {
   176  				K[k] = B[i]
   177  				k++
   178  			}
   179  		}
   180  	}
   181  	return K
   182  }
   183  
   184  /* Password based Key Derivation Function */
   185  /* Input password p, salt s, and repeat count */
   186  /* Output key of length olen */
   187  func ECDH_PBKDF2(sha int, Pass []byte, Salt []byte, rep int, olen int) []byte {
   188  	d := olen / sha
   189  	if olen%sha != 0 {
   190  		d++
   191  	}
   192  
   193  	var F []byte
   194  	var U []byte
   195  	var S []byte
   196  	var K []byte
   197  
   198  	for i := 0; i < sha; i++ {
   199  		F = append(F, 0)
   200  		U = append(U, 0)
   201  	}
   202  
   203  	for i := 1; i <= d; i++ {
   204  		for j := 0; j < len(Salt); j++ {
   205  			S = append(S, Salt[j])
   206  		}
   207  		N := inttoBytes(i, 4)
   208  		for j := 0; j < 4; j++ {
   209  			S = append(S, N[j])
   210  		}
   211  
   212  		HMAC(sha, S, Pass, F[:])
   213  
   214  		for j := 0; j < sha; j++ {
   215  			U[j] = F[j]
   216  		}
   217  		for j := 2; j <= rep; j++ {
   218  			HMAC(sha, U[:], Pass, U[:])
   219  			for k := 0; k < sha; k++ {
   220  				F[k] ^= U[k]
   221  			}
   222  		}
   223  		for j := 0; j < sha; j++ {
   224  			K = append(K, F[j])
   225  		}
   226  	}
   227  	var key []byte
   228  	for i := 0; i < olen; i++ {
   229  		key = append(key, K[i])
   230  	}
   231  	return key
   232  }
   233  
   234  /* Calculate HMAC of m using key k. HMAC is tag of length olen (which is length of tag) */
   235  func HMAC(sha int, M []byte, K []byte, tag []byte) int {
   236  	/* Input is from an octet m        *
   237  	* olen is requested output length in bytes. k is the key  *
   238  	* The output is the calculated tag */
   239  	var B []byte
   240  	b := 64
   241  	if sha > 32 {
   242  		b = 128
   243  	}
   244  
   245  	var K0 [128]byte
   246  	olen := len(tag)
   247  
   248  	if olen < 4 {
   249  		return 0
   250  	}
   251  
   252  	for i := 0; i < b; i++ {
   253  		K0[i] = 0
   254  	}
   255  
   256  	if len(K) > b {
   257  		B = ehashit(sha, K, 0, nil, 0)
   258  		for i := 0; i < sha; i++ {
   259  			K0[i] = B[i]
   260  		}
   261  	} else {
   262  		for i := 0; i < len(K); i++ {
   263  			K0[i] = K[i]
   264  		}
   265  	}
   266  
   267  	for i := 0; i < b; i++ {
   268  		K0[i] ^= 0x36
   269  	}
   270  	B = ehashit(sha, K0[0:b], 0, M, 0)
   271  
   272  	for i := 0; i < b; i++ {
   273  		K0[i] ^= 0x6a
   274  	}
   275  	B = ehashit(sha, K0[0:b], 0, B, olen)
   276  
   277  	for i := 0; i < olen; i++ {
   278  		tag[i] = B[i]
   279  	}
   280  
   281  	return 1
   282  }
   283  
   284  /* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
   285  func AES_CBC_IV0_ENCRYPT(K []byte, M []byte) []byte { /* AES CBC encryption, with Null IV and key K */
   286  	/* Input is from an octet string M, output is to an octet string C */
   287  	/* Input is padded as necessary to make up a full final block */
   288  	a := amcl.NewAES()
   289  	fin := false
   290  
   291  	var buff [16]byte
   292  	var C []byte
   293  
   294  	a.Init(amcl.AES_CBC, len(K), K, nil)
   295  
   296  	ipt := 0 //opt:=0
   297  	var i int
   298  	for true {
   299  		for i = 0; i < 16; i++ {
   300  			if ipt < len(M) {
   301  				buff[i] = M[ipt]
   302  				ipt++
   303  			} else {
   304  				fin = true
   305  				break
   306  			}
   307  		}
   308  		if fin {
   309  			break
   310  		}
   311  		a.Encrypt(buff[:])
   312  		for i = 0; i < 16; i++ {
   313  			C = append(C, buff[i])
   314  		}
   315  	}
   316  
   317  	/* last block, filled up to i-th index */
   318  
   319  	padlen := 16 - i
   320  	for j := i; j < 16; j++ {
   321  		buff[j] = byte(padlen)
   322  	}
   323  
   324  	a.Encrypt(buff[:])
   325  
   326  	for i = 0; i < 16; i++ {
   327  		C = append(C, buff[i])
   328  	}
   329  	a.End()
   330  	return C
   331  }
   332  
   333  /* returns plaintext if all consistent, else returns null string */
   334  func AES_CBC_IV0_DECRYPT(K []byte, C []byte) []byte { /* padding is removed */
   335  	a := amcl.NewAES()
   336  	var buff [16]byte
   337  	var MM []byte
   338  	var M []byte
   339  
   340  	var i int
   341  	ipt := 0
   342  	opt := 0
   343  
   344  	a.Init(amcl.AES_CBC, len(K), K, nil)
   345  
   346  	if len(C) == 0 {
   347  		return nil
   348  	}
   349  	ch := C[ipt]
   350  	ipt++
   351  
   352  	fin := false
   353  
   354  	for true {
   355  		for i = 0; i < 16; i++ {
   356  			buff[i] = ch
   357  			if ipt >= len(C) {
   358  				fin = true
   359  				break
   360  			} else {
   361  				ch = C[ipt]
   362  				ipt++
   363  			}
   364  		}
   365  		a.Decrypt(buff[:])
   366  		if fin {
   367  			break
   368  		}
   369  		for i = 0; i < 16; i++ {
   370  			MM = append(MM, buff[i])
   371  			opt++
   372  		}
   373  	}
   374  
   375  	a.End()
   376  	bad := false
   377  	padlen := int(buff[15])
   378  	if i != 15 || padlen < 1 || padlen > 16 {
   379  		bad = true
   380  	}
   381  	if padlen >= 2 && padlen <= 16 {
   382  		for i = 16 - padlen; i < 16; i++ {
   383  			if buff[i] != byte(padlen) {
   384  				bad = true
   385  			}
   386  		}
   387  	}
   388  
   389  	if !bad {
   390  		for i = 0; i < 16-padlen; i++ {
   391  			MM = append(MM, buff[i])
   392  			opt++
   393  		}
   394  	}
   395  
   396  	if bad {
   397  		return nil
   398  	}
   399  
   400  	for i = 0; i < opt; i++ {
   401  		M = append(M, MM[i])
   402  	}
   403  
   404  	return M
   405  }
   406  
   407  /* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
   408   * where S is the secret key and W is the public key
   409   * and G is fixed generator.
   410   * If RNG is NULL then the private key is provided externally in S
   411   * otherwise it is generated randomly internally */
   412  func ECDH_KEY_PAIR_GENERATE(RNG *amcl.RAND, S []byte, W []byte) int {
   413  	res := 0
   414  	//	var T [EFS]byte
   415  	var s *BIG
   416  	var G *ECP
   417  
   418  	G = ECP_generator()
   419  
   420  	r := NewBIGints(CURVE_Order)
   421  
   422  	if RNG == nil {
   423  		s = FromBytes(S)
   424  		s.Mod(r)
   425  	} else {
   426  		s = Randomnum(r, RNG)
   427  
   428  		//	s.ToBytes(T[:])
   429  		//	for i:=0;i<EGS;i++ {S[i]=T[i]}
   430  	}
   431  
   432  	//if AES_S>0 {
   433  	//	s.mod2m(2*AES_S)
   434  	//}
   435  	s.ToBytes(S)
   436  
   437  	WP := G.mul(s)
   438  
   439  	WP.ToBytes(W, false) // To use point compression on public keys, change to true
   440  
   441  	return res
   442  }
   443  
   444  /* validate public key */
   445  func ECDH_PUBLIC_KEY_VALIDATE(W []byte) int {
   446  	WP := ECP_fromBytes(W)
   447  	res := 0
   448  
   449  	r := NewBIGints(CURVE_Order)
   450  
   451  	if WP.Is_infinity() {
   452  		res = INVALID_PUBLIC_KEY
   453  	}
   454  	if res == 0 {
   455  
   456  		q := NewBIGints(Modulus)
   457  		nb := q.nbits()
   458  		k := NewBIGint(1)
   459  		k.shl(uint((nb + 4) / 2))
   460  		k.add(q)
   461  		k.div(r)
   462  
   463  		for k.parity() == 0 {
   464  			k.shr(1)
   465  			WP.dbl()
   466  		}
   467  
   468  		if !k.isunity() {
   469  			WP = WP.mul(k)
   470  		}
   471  		if WP.Is_infinity() {
   472  			res = INVALID_PUBLIC_KEY
   473  		}
   474  
   475  	}
   476  	return res
   477  }
   478  
   479  /* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
   480  func ECDH_ECPSVDP_DH(S []byte, WD []byte, Z []byte) int {
   481  	res := 0
   482  	var T [EFS]byte
   483  
   484  	s := FromBytes(S)
   485  
   486  	W := ECP_fromBytes(WD)
   487  	if W.Is_infinity() {
   488  		res = ERROR
   489  	}
   490  
   491  	if res == 0 {
   492  		r := NewBIGints(CURVE_Order)
   493  		s.Mod(r)
   494  		W = W.mul(s)
   495  		if W.Is_infinity() {
   496  			res = ERROR
   497  		} else {
   498  			W.GetX().ToBytes(T[:])
   499  			for i := 0; i < EFS; i++ {
   500  				Z[i] = T[i]
   501  			}
   502  		}
   503  	}
   504  	return res
   505  }
   506  
   507  /* IEEE ECDSA Signature, C and D are signature on F using private key S */
   508  func ECDH_ECPSP_DSA(sha int, RNG *amcl.RAND, S []byte, F []byte, C []byte, D []byte) int {
   509  	var T [EFS]byte
   510  
   511  	B := ehashit(sha, F, 0, nil, int(MODBYTES))
   512  	G := ECP_generator()
   513  
   514  	r := NewBIGints(CURVE_Order)
   515  
   516  	s := FromBytes(S)
   517  	f := FromBytes(B[:])
   518  
   519  	c := NewBIGint(0)
   520  	d := NewBIGint(0)
   521  	V := NewECP()
   522  
   523  	for d.iszilch() {
   524  		u := Randomnum(r, RNG)
   525  		w := Randomnum(r, RNG) /* side channel masking */
   526  		//if AES_S>0 {
   527  		//	u.mod2m(2*AES_S)
   528  		//}
   529  		V.Copy(G)
   530  		V = V.mul(u)
   531  		vx := V.GetX()
   532  		c.copy(vx)
   533  		c.Mod(r)
   534  		if c.iszilch() {
   535  			continue
   536  		}
   537  		u.copy(Modmul(u, w, r))
   538  		u.Invmodp(r)
   539  		d.copy(Modmul(s, c, r))
   540  		d.add(f)
   541  		d.copy(Modmul(d, w, r))
   542  		d.copy(Modmul(u, d, r))
   543  	}
   544  
   545  	c.ToBytes(T[:])
   546  	for i := 0; i < EFS; i++ {
   547  		C[i] = T[i]
   548  	}
   549  	d.ToBytes(T[:])
   550  	for i := 0; i < EFS; i++ {
   551  		D[i] = T[i]
   552  	}
   553  	return 0
   554  }
   555  
   556  /* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
   557  func ECDH_ECPVP_DSA(sha int, W []byte, F []byte, C []byte, D []byte) int {
   558  	res := 0
   559  
   560  	B := ehashit(sha, F, 0, nil, int(MODBYTES))
   561  
   562  	G := ECP_generator()
   563  	r := NewBIGints(CURVE_Order)
   564  
   565  	c := FromBytes(C)
   566  	d := FromBytes(D)
   567  	f := FromBytes(B[:])
   568  
   569  	if c.iszilch() || comp(c, r) >= 0 || d.iszilch() || comp(d, r) >= 0 {
   570  		res = INVALID
   571  	}
   572  
   573  	if res == 0 {
   574  		d.Invmodp(r)
   575  		f.copy(Modmul(f, d, r))
   576  		h2 := Modmul(c, d, r)
   577  
   578  		WP := ECP_fromBytes(W)
   579  		if WP.Is_infinity() {
   580  			res = ERROR
   581  		} else {
   582  			P := NewECP()
   583  			P.Copy(WP)
   584  
   585  			P = P.Mul2(h2, G, f)
   586  
   587  			if P.Is_infinity() {
   588  				res = INVALID
   589  			} else {
   590  				d = P.GetX()
   591  				d.Mod(r)
   592  
   593  				if comp(d, c) != 0 {
   594  					res = INVALID
   595  				}
   596  			}
   597  		}
   598  	}
   599  
   600  	return res
   601  }
   602  
   603  /* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
   604  func ECDH_ECIES_ENCRYPT(sha int, P1 []byte, P2 []byte, RNG *amcl.RAND, W []byte, M []byte, V []byte, T []byte) []byte {
   605  	var Z [EFS]byte
   606  	var VZ [3*EFS + 1]byte
   607  	var K1 [AESKEY]byte
   608  	var K2 [AESKEY]byte
   609  	var U [EGS]byte
   610  
   611  	if ECDH_KEY_PAIR_GENERATE(RNG, U[:], V) != 0 {
   612  		return nil
   613  	}
   614  	if ECDH_ECPSVDP_DH(U[:], W, Z[:]) != 0 {
   615  		return nil
   616  	}
   617  
   618  	for i := 0; i < 2*EFS+1; i++ {
   619  		VZ[i] = V[i]
   620  	}
   621  	for i := 0; i < EFS; i++ {
   622  		VZ[2*EFS+1+i] = Z[i]
   623  	}
   624  
   625  	K := ECDH_KDF2(sha, VZ[:], P1, 2*AESKEY)
   626  
   627  	for i := 0; i < AESKEY; i++ {
   628  		K1[i] = K[i]
   629  		K2[i] = K[AESKEY+i]
   630  	}
   631  
   632  	C := AES_CBC_IV0_ENCRYPT(K1[:], M)
   633  
   634  	L2 := inttoBytes(len(P2), 8)
   635  
   636  	var AC []byte
   637  
   638  	for i := 0; i < len(C); i++ {
   639  		AC = append(AC, C[i])
   640  	}
   641  	for i := 0; i < len(P2); i++ {
   642  		AC = append(AC, P2[i])
   643  	}
   644  	for i := 0; i < 8; i++ {
   645  		AC = append(AC, L2[i])
   646  	}
   647  
   648  	HMAC(sha, AC, K2[:], T)
   649  
   650  	return C
   651  }
   652  
   653  /* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
   654  func ECDH_ECIES_DECRYPT(sha int, P1 []byte, P2 []byte, V []byte, C []byte, T []byte, U []byte) []byte {
   655  	var Z [EFS]byte
   656  	var VZ [3*EFS + 1]byte
   657  	var K1 [AESKEY]byte
   658  	var K2 [AESKEY]byte
   659  
   660  	var TAG []byte = T[:]
   661  
   662  	if ECDH_ECPSVDP_DH(U, V, Z[:]) != 0 {
   663  		return nil
   664  	}
   665  
   666  	for i := 0; i < 2*EFS+1; i++ {
   667  		VZ[i] = V[i]
   668  	}
   669  	for i := 0; i < EFS; i++ {
   670  		VZ[2*EFS+1+i] = Z[i]
   671  	}
   672  
   673  	K := ECDH_KDF2(sha, VZ[:], P1, 2*AESKEY)
   674  
   675  	for i := 0; i < AESKEY; i++ {
   676  		K1[i] = K[i]
   677  		K2[i] = K[AESKEY+i]
   678  	}
   679  
   680  	M := AES_CBC_IV0_DECRYPT(K1[:], C)
   681  
   682  	if M == nil {
   683  		return nil
   684  	}
   685  
   686  	L2 := inttoBytes(len(P2), 8)
   687  
   688  	var AC []byte
   689  
   690  	for i := 0; i < len(C); i++ {
   691  		AC = append(AC, C[i])
   692  	}
   693  	for i := 0; i < len(P2); i++ {
   694  		AC = append(AC, P2[i])
   695  	}
   696  	for i := 0; i < 8; i++ {
   697  		AC = append(AC, L2[i])
   698  	}
   699  
   700  	HMAC(sha, AC, K2[:], TAG)
   701  
   702  	same := true
   703  	for i := 0; i < len(T); i++ {
   704  		if T[i] != TAG[i] {
   705  			same = false
   706  		}
   707  	}
   708  	if !same {
   709  		return nil
   710  	}
   711  
   712  	return M
   713  }