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 }