diff --git a/Gopkg.lock b/Gopkg.lock index f2913e6a48f..b2001a67c32 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -370,14 +370,14 @@ [[projects]] branch = "master" - digest = "1:0606c84c601a8974f4a830bfd9b7777bff894e0ce8adb27771df627301fac210" + digest = "1:b1c26a7393cb28a859e794f8eb364f5bae72ad9762e301325c50c7fa43544667" name = "github.com/hyperledger/fabric-amcl" packages = [ - "core", - "core/FP256BN", + "amcl", + "amcl/FP256BN", ] pruneopts = "NUT" - revision = "4cd1fa8b40d1e8f6a747f2d19fdb49d2376d1693" + revision = "5ccba6eab8d6b39aa2cdd88db202bba0e25da5d7" [[projects]] branch = "master" @@ -1060,8 +1060,8 @@ "github.com/gorilla/mux", "github.com/grpc-ecosystem/go-grpc-middleware", "github.com/hashicorp/go-version", - "github.com/hyperledger/fabric-amcl/core", - "github.com/hyperledger/fabric-amcl/core/FP256BN", + "github.com/hyperledger/fabric-amcl/amcl", + "github.com/hyperledger/fabric-amcl/amcl/FP256BN", "github.com/hyperledger/fabric-chaincode-go/pkg/statebased", "github.com/hyperledger/fabric-chaincode-go/shim", "github.com/hyperledger/fabric-chaincode-go/shimtest", diff --git a/bccsp/idemix/bridge/bridge_suite_test.go b/bccsp/idemix/bridge/bridge_suite_test.go index 94ef1d79bae..5f8640430fd 100644 --- a/bccsp/idemix/bridge/bridge_suite_test.go +++ b/bccsp/idemix/bridge/bridge_suite_test.go @@ -8,7 +8,7 @@ package bridge_test import ( "testing" - amcl "github.com/hyperledger/fabric-amcl/core" + "github.com/hyperledger/fabric-amcl/amcl" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) diff --git a/bccsp/idemix/bridge/bridge_test.go b/bccsp/idemix/bridge/bridge_test.go index 53c6aab49fd..e0a4f7e6024 100644 --- a/bccsp/idemix/bridge/bridge_test.go +++ b/bccsp/idemix/bridge/bridge_test.go @@ -10,7 +10,7 @@ import ( "fmt" "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/idemix/bridge" "github.com/hyperledger/fabric/bccsp/idemix/handlers" diff --git a/bccsp/idemix/bridge/credential.go b/bccsp/idemix/bridge/credential.go index 4673e0a34a1..ae5859b4418 100644 --- a/bccsp/idemix/bridge/credential.go +++ b/bccsp/idemix/bridge/credential.go @@ -9,8 +9,8 @@ import ( "bytes" "github.com/golang/protobuf/proto" - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/idemix/handlers" cryptolib "github.com/hyperledger/fabric/idemix" diff --git a/bccsp/idemix/bridge/credrequest.go b/bccsp/idemix/bridge/credrequest.go index 5ce29392343..a7e1c638924 100644 --- a/bccsp/idemix/bridge/credrequest.go +++ b/bccsp/idemix/bridge/credrequest.go @@ -9,7 +9,7 @@ import ( "bytes" "github.com/golang/protobuf/proto" - amcl "github.com/hyperledger/fabric-amcl/core" + "github.com/hyperledger/fabric-amcl/amcl" "github.com/hyperledger/fabric/bccsp/idemix/handlers" cryptolib "github.com/hyperledger/fabric/idemix" "github.com/pkg/errors" diff --git a/bccsp/idemix/bridge/issuer.go b/bccsp/idemix/bridge/issuer.go index 3164e151c68..6ef2f608326 100644 --- a/bccsp/idemix/bridge/issuer.go +++ b/bccsp/idemix/bridge/issuer.go @@ -9,7 +9,7 @@ import ( "fmt" "github.com/golang/protobuf/proto" - amcl "github.com/hyperledger/fabric-amcl/core" + "github.com/hyperledger/fabric-amcl/amcl" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/idemix/handlers" cryptolib "github.com/hyperledger/fabric/idemix" diff --git a/bccsp/idemix/bridge/math.go b/bccsp/idemix/bridge/math.go index ba842d370df..f04d65c8d5e 100644 --- a/bccsp/idemix/bridge/math.go +++ b/bccsp/idemix/bridge/math.go @@ -6,7 +6,7 @@ SPDX-License-Identifier: Apache-2.0 package bridge import ( - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/hyperledger/fabric/idemix" ) diff --git a/bccsp/idemix/bridge/nymsignaturescheme.go b/bccsp/idemix/bridge/nymsignaturescheme.go index 8c946831852..1cdd6da7fde 100644 --- a/bccsp/idemix/bridge/nymsignaturescheme.go +++ b/bccsp/idemix/bridge/nymsignaturescheme.go @@ -6,7 +6,7 @@ SPDX-License-Identifier: Apache-2.0 package bridge import ( - amcl "github.com/hyperledger/fabric-amcl/core" + "github.com/hyperledger/fabric-amcl/amcl" "github.com/hyperledger/fabric/bccsp/idemix/handlers" "github.com/golang/protobuf/proto" diff --git a/bccsp/idemix/bridge/rand.go b/bccsp/idemix/bridge/rand.go index 992ed382086..629f416ed83 100644 --- a/bccsp/idemix/bridge/rand.go +++ b/bccsp/idemix/bridge/rand.go @@ -6,7 +6,7 @@ SPDX-License-Identifier: Apache-2.0 package bridge import ( - amcl "github.com/hyperledger/fabric-amcl/core" + "github.com/hyperledger/fabric-amcl/amcl" cryptolib "github.com/hyperledger/fabric/idemix" ) diff --git a/bccsp/idemix/bridge/revocation.go b/bccsp/idemix/bridge/revocation.go index 3c5a7a9b7d8..9170bb43cfe 100644 --- a/bccsp/idemix/bridge/revocation.go +++ b/bccsp/idemix/bridge/revocation.go @@ -9,7 +9,7 @@ import ( "crypto/ecdsa" "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/hyperledger/fabric/bccsp" cryptolib "github.com/hyperledger/fabric/idemix" "github.com/pkg/errors" diff --git a/bccsp/idemix/bridge/signaturescheme.go b/bccsp/idemix/bridge/signaturescheme.go index 7812a5e6ea7..7ccd1a13e54 100644 --- a/bccsp/idemix/bridge/signaturescheme.go +++ b/bccsp/idemix/bridge/signaturescheme.go @@ -9,8 +9,8 @@ import ( "crypto/ecdsa" "github.com/golang/protobuf/proto" - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/hyperledger/fabric/bccsp" "github.com/hyperledger/fabric/bccsp/idemix/handlers" cryptolib "github.com/hyperledger/fabric/idemix" diff --git a/bccsp/idemix/bridge/user.go b/bccsp/idemix/bridge/user.go index 14bd912530b..a0300487f66 100644 --- a/bccsp/idemix/bridge/user.go +++ b/bccsp/idemix/bridge/user.go @@ -6,8 +6,8 @@ SPDX-License-Identifier: Apache-2.0 package bridge import ( - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/hyperledger/fabric/bccsp/idemix/handlers" cryptolib "github.com/hyperledger/fabric/idemix" "github.com/pkg/errors" diff --git a/common/tools/idemixgen/idemixca/idemixca.go b/common/tools/idemixgen/idemixca/idemixca.go index cc2511ca06e..c162f026ce5 100644 --- a/common/tools/idemixgen/idemixca/idemixca.go +++ b/common/tools/idemixgen/idemixca/idemixca.go @@ -10,7 +10,7 @@ import ( "crypto/ecdsa" "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" m "github.com/hyperledger/fabric-protos-go/msp" "github.com/hyperledger/fabric/idemix" "github.com/hyperledger/fabric/msp" diff --git a/idemix/credential.go b/idemix/credential.go index e307008d244..28ebc2df939 100644 --- a/idemix/credential.go +++ b/idemix/credential.go @@ -7,8 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package idemix import ( - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/idemix/credrequest.go b/idemix/credrequest.go index 932882b151f..6d3b18280f6 100644 --- a/idemix/credrequest.go +++ b/idemix/credrequest.go @@ -7,8 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package idemix import ( - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/idemix/idemix_test.go b/idemix/idemix_test.go index df8513f7da0..1c76a796621 100644 --- a/idemix/idemix_test.go +++ b/idemix/idemix_test.go @@ -10,7 +10,7 @@ import ( "bytes" "testing" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/stretchr/testify/assert" ) diff --git a/idemix/issuerkey.go b/idemix/issuerkey.go index 065f63f51de..6092b8da2ff 100644 --- a/idemix/issuerkey.go +++ b/idemix/issuerkey.go @@ -8,8 +8,8 @@ package idemix import ( "github.com/golang/protobuf/proto" - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/idemix/nonrevocation-prover.go b/idemix/nonrevocation-prover.go index 2b03f544af8..fd259abc6cd 100644 --- a/idemix/nonrevocation-prover.go +++ b/idemix/nonrevocation-prover.go @@ -7,8 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package idemix import ( - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/idemix/nonrevocation-verifier.go b/idemix/nonrevocation-verifier.go index a9d29d8db5c..75526342d5f 100644 --- a/idemix/nonrevocation-verifier.go +++ b/idemix/nonrevocation-verifier.go @@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0 package idemix import ( - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/idemix/nymsignature.go b/idemix/nymsignature.go index 19c905e07ec..061fb5b1ad0 100644 --- a/idemix/nymsignature.go +++ b/idemix/nymsignature.go @@ -7,8 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package idemix import ( - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/idemix/revocation_authority.go b/idemix/revocation_authority.go index e3298bd8748..1835f17bca3 100644 --- a/idemix/revocation_authority.go +++ b/idemix/revocation_authority.go @@ -15,8 +15,8 @@ import ( "math/big" "github.com/golang/protobuf/proto" - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/idemix/signature.go b/idemix/signature.go index b58066dcd35..a0e40642fbb 100644 --- a/idemix/signature.go +++ b/idemix/signature.go @@ -10,8 +10,8 @@ import ( "crypto/ecdsa" "sort" - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/idemix/util.go b/idemix/util.go index 88829bb3bdb..43a336dca15 100644 --- a/idemix/util.go +++ b/idemix/util.go @@ -10,8 +10,8 @@ import ( "crypto/rand" "crypto/sha256" - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) @@ -68,10 +68,7 @@ func EcpToBytes(E *FP256BN.ECP) []byte { } func appendBytesG2(data []byte, index int, E *FP256BN.ECP2) int { length := 4 * FieldBytes - bytes := make([]byte, length+1) - E.ToBytes(bytes, false) - // need to strip first byte as ToBytes now adds an extra byte for type - copy(data[index:index+length], bytes[1:]) + E.ToBytes(data[index : index+length]) return index + length } func appendBytesBig(data []byte, index int, B *FP256BN.BIG) int { diff --git a/idemix/weak-bb.go b/idemix/weak-bb.go index ecb40540aa5..1b696afcbe1 100644 --- a/idemix/weak-bb.go +++ b/idemix/weak-bb.go @@ -7,8 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package idemix import ( - amcl "github.com/hyperledger/fabric-amcl/core" - "github.com/hyperledger/fabric-amcl/core/FP256BN" + "github.com/hyperledger/fabric-amcl/amcl" + "github.com/hyperledger/fabric-amcl/amcl/FP256BN" "github.com/pkg/errors" ) diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/AES.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/AES.go new file mode 100644 index 00000000000..7566d1ba9c7 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/AES.go @@ -0,0 +1,634 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* AES Encryption */ + +package amcl + + + +const AES_ECB int=0 +const AES_CBC int=1 +const AES_CFB1 int=2 +const AES_CFB2 int=3 +const AES_CFB4 int=5 +const AES_OFB1 int=14 +const AES_OFB2 int=15 +const AES_OFB4 int=17 +const AES_OFB8 int=21 +const AES_OFB16 int=29 +const AES_CTR1 int=30 +const AES_CTR2 int=31 +const AES_CTR4 int=33 +const AES_CTR8 int=37 +const AES_CTR16 int=45 + +var aes_InCo = [...]byte {0xB,0xD,0x9,0xE} /* Inverse Coefficients */ + +var aes_ptab = [...]byte { + 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, + 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, + 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, + 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, + 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, + 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, + 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, + 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, + 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, + 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, + 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, + 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, + 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, + 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, + 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, + 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1} + +var aes_ltab = [...]byte { + 0, 255, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3, + 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193, + 125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120, + 101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142, + 150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, + 102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, + 126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186, + 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87, + 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232, + 44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160, + 127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183, + 204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, + 151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, + 83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171, + 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165, + 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7} + + +var aes_fbsub = [...]byte { + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22} + +var aes_rbsub = [...]byte { + 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, + 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, + 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, + 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, + 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, + 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, + 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, + 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, + 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, + 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, + 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, + 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, + 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, + 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, + 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, + 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125} + + +var aes_rco = [...]byte {1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47} + +var aes_ftable = [...]uint32 { + 0xa56363c6,0x847c7cf8,0x997777ee,0x8d7b7bf6,0xdf2f2ff,0xbd6b6bd6, + 0xb16f6fde,0x54c5c591,0x50303060,0x3010102,0xa96767ce,0x7d2b2b56, + 0x19fefee7,0x62d7d7b5,0xe6abab4d,0x9a7676ec,0x45caca8f,0x9d82821f, + 0x40c9c989,0x877d7dfa,0x15fafaef,0xeb5959b2,0xc947478e,0xbf0f0fb, + 0xecadad41,0x67d4d4b3,0xfda2a25f,0xeaafaf45,0xbf9c9c23,0xf7a4a453, + 0x967272e4,0x5bc0c09b,0xc2b7b775,0x1cfdfde1,0xae93933d,0x6a26264c, + 0x5a36366c,0x413f3f7e,0x2f7f7f5,0x4fcccc83,0x5c343468,0xf4a5a551, + 0x34e5e5d1,0x8f1f1f9,0x937171e2,0x73d8d8ab,0x53313162,0x3f15152a, + 0xc040408,0x52c7c795,0x65232346,0x5ec3c39d,0x28181830,0xa1969637, + 0xf05050a,0xb59a9a2f,0x907070e,0x36121224,0x9b80801b,0x3de2e2df, + 0x26ebebcd,0x6927274e,0xcdb2b27f,0x9f7575ea,0x1b090912,0x9e83831d, + 0x742c2c58,0x2e1a1a34,0x2d1b1b36,0xb26e6edc,0xee5a5ab4,0xfba0a05b, + 0xf65252a4,0x4d3b3b76,0x61d6d6b7,0xceb3b37d,0x7b292952,0x3ee3e3dd, + 0x712f2f5e,0x97848413,0xf55353a6,0x68d1d1b9,0x0,0x2cededc1, + 0x60202040,0x1ffcfce3,0xc8b1b179,0xed5b5bb6,0xbe6a6ad4,0x46cbcb8d, + 0xd9bebe67,0x4b393972,0xde4a4a94,0xd44c4c98,0xe85858b0,0x4acfcf85, + 0x6bd0d0bb,0x2aefefc5,0xe5aaaa4f,0x16fbfbed,0xc5434386,0xd74d4d9a, + 0x55333366,0x94858511,0xcf45458a,0x10f9f9e9,0x6020204,0x817f7ffe, + 0xf05050a0,0x443c3c78,0xba9f9f25,0xe3a8a84b,0xf35151a2,0xfea3a35d, + 0xc0404080,0x8a8f8f05,0xad92923f,0xbc9d9d21,0x48383870,0x4f5f5f1, + 0xdfbcbc63,0xc1b6b677,0x75dadaaf,0x63212142,0x30101020,0x1affffe5, + 0xef3f3fd,0x6dd2d2bf,0x4ccdcd81,0x140c0c18,0x35131326,0x2fececc3, + 0xe15f5fbe,0xa2979735,0xcc444488,0x3917172e,0x57c4c493,0xf2a7a755, + 0x827e7efc,0x473d3d7a,0xac6464c8,0xe75d5dba,0x2b191932,0x957373e6, + 0xa06060c0,0x98818119,0xd14f4f9e,0x7fdcdca3,0x66222244,0x7e2a2a54, + 0xab90903b,0x8388880b,0xca46468c,0x29eeeec7,0xd3b8b86b,0x3c141428, + 0x79dedea7,0xe25e5ebc,0x1d0b0b16,0x76dbdbad,0x3be0e0db,0x56323264, + 0x4e3a3a74,0x1e0a0a14,0xdb494992,0xa06060c,0x6c242448,0xe45c5cb8, + 0x5dc2c29f,0x6ed3d3bd,0xefacac43,0xa66262c4,0xa8919139,0xa4959531, + 0x37e4e4d3,0x8b7979f2,0x32e7e7d5,0x43c8c88b,0x5937376e,0xb76d6dda, + 0x8c8d8d01,0x64d5d5b1,0xd24e4e9c,0xe0a9a949,0xb46c6cd8,0xfa5656ac, + 0x7f4f4f3,0x25eaeacf,0xaf6565ca,0x8e7a7af4,0xe9aeae47,0x18080810, + 0xd5baba6f,0x887878f0,0x6f25254a,0x722e2e5c,0x241c1c38,0xf1a6a657, + 0xc7b4b473,0x51c6c697,0x23e8e8cb,0x7cdddda1,0x9c7474e8,0x211f1f3e, + 0xdd4b4b96,0xdcbdbd61,0x868b8b0d,0x858a8a0f,0x907070e0,0x423e3e7c, + 0xc4b5b571,0xaa6666cc,0xd8484890,0x5030306,0x1f6f6f7,0x120e0e1c, + 0xa36161c2,0x5f35356a,0xf95757ae,0xd0b9b969,0x91868617,0x58c1c199, + 0x271d1d3a,0xb99e9e27,0x38e1e1d9,0x13f8f8eb,0xb398982b,0x33111122, + 0xbb6969d2,0x70d9d9a9,0x898e8e07,0xa7949433,0xb69b9b2d,0x221e1e3c, + 0x92878715,0x20e9e9c9,0x49cece87,0xff5555aa,0x78282850,0x7adfdfa5, + 0x8f8c8c03,0xf8a1a159,0x80898909,0x170d0d1a,0xdabfbf65,0x31e6e6d7, + 0xc6424284,0xb86868d0,0xc3414182,0xb0999929,0x772d2d5a,0x110f0f1e, + 0xcbb0b07b,0xfc5454a8,0xd6bbbb6d,0x3a16162c} + +var aes_rtable = [...]uint32 { + 0x50a7f451,0x5365417e,0xc3a4171a,0x965e273a,0xcb6bab3b,0xf1459d1f, + 0xab58faac,0x9303e34b,0x55fa3020,0xf66d76ad,0x9176cc88,0x254c02f5, + 0xfcd7e54f,0xd7cb2ac5,0x80443526,0x8fa362b5,0x495ab1de,0x671bba25, + 0x980eea45,0xe1c0fe5d,0x2752fc3,0x12f04c81,0xa397468d,0xc6f9d36b, + 0xe75f8f03,0x959c9215,0xeb7a6dbf,0xda595295,0x2d83bed4,0xd3217458, + 0x2969e049,0x44c8c98e,0x6a89c275,0x78798ef4,0x6b3e5899,0xdd71b927, + 0xb64fe1be,0x17ad88f0,0x66ac20c9,0xb43ace7d,0x184adf63,0x82311ae5, + 0x60335197,0x457f5362,0xe07764b1,0x84ae6bbb,0x1ca081fe,0x942b08f9, + 0x58684870,0x19fd458f,0x876cde94,0xb7f87b52,0x23d373ab,0xe2024b72, + 0x578f1fe3,0x2aab5566,0x728ebb2,0x3c2b52f,0x9a7bc586,0xa50837d3, + 0xf2872830,0xb2a5bf23,0xba6a0302,0x5c8216ed,0x2b1ccf8a,0x92b479a7, + 0xf0f207f3,0xa1e2694e,0xcdf4da65,0xd5be0506,0x1f6234d1,0x8afea6c4, + 0x9d532e34,0xa055f3a2,0x32e18a05,0x75ebf6a4,0x39ec830b,0xaaef6040, + 0x69f715e,0x51106ebd,0xf98a213e,0x3d06dd96,0xae053edd,0x46bde64d, + 0xb58d5491,0x55dc471,0x6fd40604,0xff155060,0x24fb9819,0x97e9bdd6, + 0xcc434089,0x779ed967,0xbd42e8b0,0x888b8907,0x385b19e7,0xdbeec879, + 0x470a7ca1,0xe90f427c,0xc91e84f8,0x0,0x83868009,0x48ed2b32, + 0xac70111e,0x4e725a6c,0xfbff0efd,0x5638850f,0x1ed5ae3d,0x27392d36, + 0x64d90f0a,0x21a65c68,0xd1545b9b,0x3a2e3624,0xb1670a0c,0xfe75793, + 0xd296eeb4,0x9e919b1b,0x4fc5c080,0xa220dc61,0x694b775a,0x161a121c, + 0xaba93e2,0xe52aa0c0,0x43e0223c,0x1d171b12,0xb0d090e,0xadc78bf2, + 0xb9a8b62d,0xc8a91e14,0x8519f157,0x4c0775af,0xbbdd99ee,0xfd607fa3, + 0x9f2601f7,0xbcf5725c,0xc53b6644,0x347efb5b,0x7629438b,0xdcc623cb, + 0x68fcedb6,0x63f1e4b8,0xcadc31d7,0x10856342,0x40229713,0x2011c684, + 0x7d244a85,0xf83dbbd2,0x1132f9ae,0x6da129c7,0x4b2f9e1d,0xf330b2dc, + 0xec52860d,0xd0e3c177,0x6c16b32b,0x99b970a9,0xfa489411,0x2264e947, + 0xc48cfca8,0x1a3ff0a0,0xd82c7d56,0xef903322,0xc74e4987,0xc1d138d9, + 0xfea2ca8c,0x360bd498,0xcf81f5a6,0x28de7aa5,0x268eb7da,0xa4bfad3f, + 0xe49d3a2c,0xd927850,0x9bcc5f6a,0x62467e54,0xc2138df6,0xe8b8d890, + 0x5ef7392e,0xf5afc382,0xbe805d9f,0x7c93d069,0xa92dd56f,0xb31225cf, + 0x3b99acc8,0xa77d1810,0x6e639ce8,0x7bbb3bdb,0x97826cd,0xf418596e, + 0x1b79aec,0xa89a4f83,0x656e95e6,0x7ee6ffaa,0x8cfbc21,0xe6e815ef, + 0xd99be7ba,0xce366f4a,0xd4099fea,0xd67cb029,0xafb2a431,0x31233f2a, + 0x3094a5c6,0xc066a235,0x37bc4e74,0xa6ca82fc,0xb0d090e0,0x15d8a733, + 0x4a9804f1,0xf7daec41,0xe50cd7f,0x2ff69117,0x8dd64d76,0x4db0ef43, + 0x544daacc,0xdf0496e4,0xe3b5d19e,0x1b886a4c,0xb81f2cc1,0x7f516546, + 0x4ea5e9d,0x5d358c01,0x737487fa,0x2e410bfb,0x5a1d67b3,0x52d2db92, + 0x335610e9,0x1347d66d,0x8c61d79a,0x7a0ca137,0x8e14f859,0x893c13eb, + 0xee27a9ce,0x35c961b7,0xede51ce1,0x3cb1477a,0x59dfd29c,0x3f73f255, + 0x79ce1418,0xbf37c773,0xeacdf753,0x5baafd5f,0x146f3ddf,0x86db4478, + 0x81f3afca,0x3ec468b9,0x2c342438,0x5f40a3c2,0x72c31d16,0xc25e2bc, + 0x8b493c28,0x41950dff,0x7101a839,0xdeb30c08,0x9ce4b4d8,0x90c15664, + 0x6184cb7b,0x70b632d5,0x745c6c48,0x4257b8d0} + +type AES struct { + Nk int + Nr int + mode int + fkey [60]uint32 + rkey [60]uint32 + f [16]byte +} + +/* Rotates 32-bit word left by 1, 2 or 3 byte */ + +func aes_ROTL8(x uint32) uint32 { + return (((x)<<8)|((x)>>24)) +} + +func aes_ROTL16(x uint32) uint32 { + return (((x)<<16)|((x)>>16)) +} + +func aes_ROTL24(x uint32) uint32 { + return (((x)<<24)|((x)>>8)) +} + +func aes_pack(b [4]byte) uint32 { /* pack bytes into a 32-bit Word */ + return ((uint32(b[3])&0xff)<<24)|((uint32(b[2])&0xff)<<16)|((uint32(b[1])&0xff)<<8)|(uint32(b[0])&0xff) +} + +func aes_unpack(a uint32) [4]byte { /* unpack bytes from a word */ + var b=[4]byte{byte(a&0xff),byte((a>>8)&0xff),byte((a>>16)&0xff),byte((a>>24)&0xff)} + return b; +} + +func aes_bmul(x byte,y byte) byte { /* x.y= AntiLog(Log(x) + Log(y)) */ + + ix:=int(x)&0xff + iy:=int(y)&0xff + lx:=int(aes_ltab[ix])&0xff + ly:=int(aes_ltab[iy])&0xff + + if x != 0 && y != 0 { + return aes_ptab[(lx+ly)%255] + } else {return byte(0)} +} + +func aes_SubByte(a uint32) uint32 { + b:=aes_unpack(a) + b[0]=aes_fbsub[int(b[0])] + b[1]=aes_fbsub[int(b[1])] + b[2]=aes_fbsub[int(b[2])] + b[3]=aes_fbsub[int(b[3])] + return aes_pack(b); +} + +func aes_product(x uint32,y uint32) byte { /* dot product of two 4-byte arrays */ + xb:=aes_unpack(x) + yb:=aes_unpack(y) + + return (aes_bmul(xb[0],yb[0])^aes_bmul(xb[1],yb[1])^aes_bmul(xb[2],yb[2])^aes_bmul(xb[3],yb[3])) +} + +func aes_InvMixCol(x uint32) uint32 { /* matrix Multiplication */ + var b [4]byte + m:=aes_pack(aes_InCo) + b[3]=aes_product(m,x) + m=aes_ROTL24(m) + b[2]=aes_product(m,x) + m=aes_ROTL24(m) + b[1]=aes_product(m,x) + m=aes_ROTL24(m) + b[0]=aes_product(m,x) + var y=aes_pack(b) + return y +} + +func aes_increment(f []byte) { + for i:=0;i<16;i++ { + f[i]++ + if f[i]!=0 {break} + } +} + +/* reset cipher */ +func (A *AES) Reset(m int,iv []byte) { /* reset mode, or reset iv */ + A.mode=m; + for i:=0;i<16;i++ {A.f[i]=0} + if (A.mode != AES_ECB) && (iv != nil) { + for i:=0;i<16;i++ {A.f[i]=iv[i]} + } +} + +func (A *AES) Init(m int,nk int,key []byte,iv []byte) bool { +/* Key Scheduler. Create expanded encryption key */ + var CipherKey [8]uint32 + var b [4]byte + nk/=4 + if nk!=4 && nk!=6 && nk!=8 {return false} + nr:=6+nk + A.Nk=nk + A.Nr=nr + A.Reset(m,iv); + N:=4*(nr+1) + + j:=0 + for i:=0;i>8)&0xff)])^aes_ROTL16(aes_ftable[int((p[2]>>16)&0xff)])^aes_ROTL24(aes_ftable[int((p[3]>>24)&0xff)]) + + q[1]=A.fkey[k+1]^aes_ftable[int(p[1]&0xff)]^aes_ROTL8(aes_ftable[int((p[2]>>8)&0xff)])^aes_ROTL16(aes_ftable[int((p[3]>>16)&0xff)])^aes_ROTL24(aes_ftable[int((p[0]>>24)&0xff)]) + + q[2]=A.fkey[k+2]^aes_ftable[int(p[2]&0xff)]^aes_ROTL8(aes_ftable[int((p[3]>>8)&0xff)])^aes_ROTL16(aes_ftable[int((p[0]>>16)&0xff)])^aes_ROTL24(aes_ftable[int((p[1]>>24)&0xff)]) + + q[3]=A.fkey[k+3]^aes_ftable[int(p[3]&0xff)]^aes_ROTL8(aes_ftable[int((p[0]>>8)&0xff)])^aes_ROTL16(aes_ftable[int((p[1]>>16)&0xff)])^aes_ROTL24(aes_ftable[int((p[2]>>24)&0xff)]) + + k+=4; + for j=0;j<4;j++ { + t:=p[j]; p[j]=q[j]; q[j]=t + } + } + + /* Last Round */ + + q[0]=A.fkey[k]^uint32(aes_fbsub[int(p[0]&0xff)])^aes_ROTL8(uint32(aes_fbsub[int((p[1]>>8)&0xff)]))^aes_ROTL16(uint32(aes_fbsub[int((p[2]>>16)&0xff)]))^aes_ROTL24(uint32(aes_fbsub[int((p[3]>>24)&0xff)])) + + q[1]=A.fkey[k+1]^uint32(aes_fbsub[int(p[1]&0xff)])^aes_ROTL8(uint32(aes_fbsub[int((p[2]>>8)&0xff)]))^aes_ROTL16(uint32(aes_fbsub[int((p[3]>>16)&0xff)]))^aes_ROTL24(uint32(aes_fbsub[int((p[0]>>24)&0xff)])) + + q[2]=A.fkey[k+2]^uint32(aes_fbsub[int(p[2]&0xff)])^aes_ROTL8(uint32(aes_fbsub[int((p[3]>>8)&0xff)]))^aes_ROTL16(uint32(aes_fbsub[int((p[0]>>16)&0xff)]))^aes_ROTL24(uint32(aes_fbsub[int((p[1]>>24)&0xff)])) + + q[3]=A.fkey[k+3]^uint32(aes_fbsub[int(p[3]&0xff)])^aes_ROTL8(uint32(aes_fbsub[int((p[0]>>8)&0xff)]))^aes_ROTL16(uint32(aes_fbsub[int((p[1]>>16)&0xff)]))^aes_ROTL24(uint32(aes_fbsub[int((p[2]>>24)&0xff)])) + + j=0 + for i:=0;i<4;i++ { + b=aes_unpack(q[i]) + for k=0;k<4;k++ {buff[j+k]=b[k]} + j+=4 + } +} + + /* Decrypt a single block */ +func (A *AES) ecb_decrypt(buff []byte) { + var b [4]byte + var p [4]uint32 + var q [4]uint32 + + j:=0 + for i:=0;i<4;i++ { + for k:=0;k<4;k++ {b[k]=buff[j+k]} + p[i]=aes_pack(b) + p[i]^=A.rkey[i] + j+=4 + } + + k:=4 + + /* State alternates between p and q */ + for i:=1;i>8)&0xff)])^aes_ROTL16(aes_rtable[int((p[2]>>16)&0xff)])^aes_ROTL24(aes_rtable[int((p[1]>>24)&0xff)]) + + q[1]=A.rkey[k+1]^aes_rtable[int(p[1]&0xff)]^aes_ROTL8(aes_rtable[int((p[0]>>8)&0xff)])^aes_ROTL16(aes_rtable[int((p[3]>>16)&0xff)])^aes_ROTL24(aes_rtable[int((p[2]>>24)&0xff)]) + + + q[2]=A.rkey[k+2]^aes_rtable[int(p[2]&0xff)]^aes_ROTL8(aes_rtable[int((p[1]>>8)&0xff)])^aes_ROTL16(aes_rtable[int((p[0]>>16)&0xff)])^aes_ROTL24(aes_rtable[int((p[3]>>24)&0xff)]) + + q[3]=A.rkey[k+3]^aes_rtable[int(p[3]&0xff)]^aes_ROTL8(aes_rtable[int((p[2]>>8)&0xff)])^aes_ROTL16(aes_rtable[int((p[1]>>16)&0xff)])^aes_ROTL24(aes_rtable[int((p[0]>>24)&0xff)]) + + + k+=4; + for j:=0;j<4;j++ { + t:=p[j]; p[j]=q[j]; q[j]=t + } + } + + /* Last Round */ + + q[0]=A.rkey[k]^uint32(aes_rbsub[int(p[0]&0xff)])^aes_ROTL8(uint32(aes_rbsub[int((p[3]>>8)&0xff)]))^aes_ROTL16(uint32(aes_rbsub[int((p[2]>>16)&0xff)]))^aes_ROTL24(uint32(aes_rbsub[int((p[1]>>24)&0xff)])) + + q[1]=A.rkey[k+1]^uint32(aes_rbsub[int(p[1]&0xff)])^aes_ROTL8(uint32(aes_rbsub[int((p[0]>>8)&0xff)]))^aes_ROTL16(uint32(aes_rbsub[int((p[3]>>16)&0xff)]))^aes_ROTL24(uint32(aes_rbsub[int((p[2]>>24)&0xff)])) + + + q[2]=A.rkey[k+2]^uint32(aes_rbsub[int(p[2]&0xff)])^aes_ROTL8(uint32(aes_rbsub[int((p[1]>>8)&0xff)]))^aes_ROTL16(uint32(aes_rbsub[int((p[0]>>16)&0xff)]))^aes_ROTL24(uint32(aes_rbsub[int((p[3]>>24)&0xff)])) + + q[3]=A.rkey[k+3]^uint32(aes_rbsub[int((p[3])&0xff)])^aes_ROTL8(uint32(aes_rbsub[int((p[2]>>8)&0xff)]))^aes_ROTL16(uint32(aes_rbsub[int((p[1]>>16)&0xff)]))^aes_ROTL24(uint32(aes_rbsub[int((p[0]>>24)&0xff)])) + + j=0 + for i:=0;i<4;i++ { + b=aes_unpack(q[i]); + for k:=0;k<4;k++ {buff[j+k]=b[k]} + j+=4 + } +} + +/* Encrypt using selected mode of operation */ +func (A *AES) Encrypt(buff []byte) uint32 { + var st [16]byte + + // Supported Modes of Operation + + var fell_off uint32=0 + switch A.mode { + case AES_ECB: + A.ecb_encrypt(buff) + return 0 + case AES_CBC: + for j:=0;j<16;j++ {buff[j]^=A.f[j]} + A.ecb_encrypt(buff) + for j:=0;j<16;j++ {A.f[j]=buff[j]} + return 0 + + case AES_CFB1: + fallthrough + case AES_CFB2: + fallthrough + case AES_CFB4: + bytes:=A.mode-AES_CFB1+1 + for j:=0;j>BASEBITS)!=0 { + ok=false + } + } + return ok; +} +*/ +/***************** 64-bit specific code ****************/ + +/* First the 32/64-bit dependent BIG code */ +/* Note that because of the lack of a 128-bit integer, 32 and 64-bit code needs to be done differently */ + +/* return a*b as DBIG */ +func mul(a *BIG,b *BIG) *DBIG { + c:=NewDBIG() + carry:= Chunk(0) +// a.norm() +// b.norm() + +// if !a.isok() || !b.isok() {fmt.Printf("Problem in mul\n")} + + + for i:=0;i>HBITS) + y0:=b&HMASK; + y1:=(b>>HBITS) + bot:=x0*y0 + top:=x1*y1 + mid:=x0*y1+x1*y0 + x0=mid&HMASK; + x1=(mid>>HBITS) + bot+=x0<>BASEBITS + bot&=BMASK + top+=carry + return top,bot +} + +/************************************************************/ + +func (r *BIG) get(i int) Chunk { + return r.w[i] +} + +func (r *BIG) set(i int,x Chunk) { + r.w[i]=x +} + +func (r *BIG) xortop(x Chunk) { + r.w[NLEN-1]^=x +} + +/* normalise BIG - force all digits < 2^BASEBITS */ +func (r *BIG) norm() Chunk { + carry:=Chunk(0) + for i:=0;i>BASEBITS + } + r.w[NLEN-1]=(r.w[NLEN-1]+carry) + return (r.w[NLEN-1]>>((8*MODBYTES)%BASEBITS)) +} + +/* Shift right by less than a word */ +func (r *BIG) fshr(k uint) int { + w:=r.w[0]&((Chunk(1)<>k)|((r.w[i+1]<<(BASEBITS-k))&BMASK) + } + r.w[NLEN-1]=r.w[NLEN-1]>>k + return int(w) +} + +/* Shift right by less than a word */ +func (r *BIG) fshl(k uint) int { + r.w[NLEN-1]=((r.w[NLEN-1]<>(BASEBITS-k)) + for i:=NLEN-2;i>0;i-- { + r.w[i]=((r.w[i]<>(BASEBITS-k)) + } + r.w[0]=(r.w[0]<>((8*MODBYTES)%BASEBITS)) /* return excess - only used in ff.c */ +} + +func NewBIG() *BIG { + b:=new(BIG) + for i:=0;i>n)|((r.w[m+i+1]<<(BASEBITS-n))&BMASK) + } + r.w[NLEN-m-1]=r.w[NLEN-1]>>n; + for i:=NLEN-m;i=m+2 {r.w[NLEN-1]|=(r.w[NLEN-m-2]>>(BASEBITS-n))} + for i:=NLEN-2;i>m;i-- { + r.w[i]=((r.w[i-m]<>(BASEBITS-n)) + } + r.w[m]=(r.w[0]<=0 && t.w[k]==0) {k--} + if k<0 {return 0} + bts:=int(BASEBITS)*k; + c:=t.w[k]; + for c!=0 {c/=2; bts++} + return bts +} + +/* Convert to Hex String */ +func (r *BIG) toString() string { + s:="" + len:=r.nbits() + + if len%4==0 { + len/=4 + } else { + len/=4 + len++ + + } + MB:=int(MODBYTES*2) + if len=0;i-- { + b:=NewBIGcopy(r) + + b.shr(uint(i*4)) + s+=strconv.FormatInt(int64(b.w[0]&15),16) + } + return s +} + +func (r *BIG) add(x *BIG) { + for i:=0;iNEXCESS */ +func (r *BIG) pmul(c int) Chunk { + carry:=Chunk(0) +// r.norm(); + for i:=0;i=0;i-- { + b[i+n]=byte(c.w[0]) + c.fshr(8) + } +} + +/* convert from byte array to BIG */ +func frombytearray(b []byte,n int) *BIG { + m:=NewBIG(); + for i:=0;i=0;i-- { + ak:=(carry*base+r.w[i]) + r.w[i]=ak/3; + carry=ak%3; + } + return int(carry) +} + +/* return a*b where result fits in a BIG */ +func smul(a *BIG,b *BIG) *BIG { + carry:=Chunk(0) + c:=NewBIG() + for i:=0;ib. Inputs must be normalised */ +func comp(a *BIG,b *BIG) int { + for i:=NLEN-1;i>=0;i-- { + if a.w[i]==b.w[i] {continue} + if a.w[i]>b.w[i] { + return 1 + } else {return -1} + } + return 0 +} + +/* return parity */ +func (r *BIG) parity() int { + return int(r.w[0]%2) +} + +/* return n-th bit */ +func (r *BIG) bit(n int) int { + if (r.w[n/int(BASEBITS)]&(Chunk(1)<<(uint(n)%BASEBITS)))>0 {return 1} + return 0; +} + +/* return n last bits */ +func (r *BIG) lastbits(n int) int { + msk:=(1<=0 { + m.fshl(1) + k++; + } + + for k>0 { + m.fshr(1); + + sr.copy(r) + sr.sub(m) + sr.norm() + r.cmove(sr,int(1-((sr.w[NLEN-1]>>uint(CHUNK-1))&1))); +/* + if comp(r,m)>=0 { + r.sub(m) + r.norm() + } */ + k--; + } +} + +/* divide this by m */ +func (r *BIG) div(m1 *BIG) { + m:=NewBIGcopy(m1) + var d int + k:=0 + r.norm(); + sr:=NewBIG(); + e:=NewBIGint(1) + b:=NewBIGcopy(r) + r.zero(); + + for (comp(b,m)>=0) { + e.fshl(1) + m.fshl(1) + k++ + } + + for k>0 { + m.fshr(1) + e.fshr(1) + + sr.copy(b); + sr.sub(m); + sr.norm(); + d=int(1-((sr.w[NLEN-1]>>uint(CHUNK-1))&1)); + b.cmove(sr,d); + sr.copy(r); + sr.add(e); + sr.norm(); + r.cmove(sr,d); +/* + if comp(b,m)>=0 { + r.add(e) + r.norm() + b.sub(m) + b.norm() + } */ + k-- + } +} + +/* get 8*MODBYTES size random number */ +func random(rng *amcl.RAND) *BIG { + m:=NewBIG() + var j int=0 + var r byte=0 +/* generate random BIG */ + for i:=0;i<8*int(MODBYTES);i++ { + if j==0 { + r=rng.GetByte() + } else {r>>=1} + + b:=Chunk(int(r&1)) + m.shl(1); m.w[0]+=b// m.inc(b) + j++; j&=7; + } + return m; +} + +/* Create random BIG in portable way, one bit at a time */ +func Randomnum(q *BIG,rng *amcl.RAND) *BIG { + d:=NewDBIG(); + var j int=0 + var r byte=0 + for i:=0;i<2*q.nbits();i++ { + if (j==0) { + r=rng.GetByte(); + } else {r>>=1} + + b:=Chunk(int(r&1)) + d.shl(1); d.w[0]+=b// m.inc(b); + j++; j&=7 + } + m:=d.mod(q) + return m; +} + + +/* return NAF value as +/- 1, 3 or 5. x and x3 should be normed. +nbs is number of bits processed, and nzs is number of trailing 0s detected */ +/* +func nafbits(x *BIG,x3 *BIG ,i int) [3]int { + var n [3]int + var j int + nb:=x3.bit(i)-x.bit(i) + + + n[1]=1 + n[0]=0 + if nb==0 {n[0]=0; return n} + if i==0 {n[0]=nb; return n} + if nb>0 { + n[0]=1; + } else {n[0]=(-1)} + + for j=i-1;j>0;j-- { + n[1]++ + n[0]*=2 + nb=x3.bit(j)-x.bit(j) + if nb>0 {n[0]+=1} + if nb<0 {n[0]-=1} + if (n[0]>5 || n[0] < -5) {break} + } + + if n[0]%2!=0 && j!=0 { // backtrack + if nb>0 {n[0]=(n[0]-1)/2} + if nb<0 {n[0]=(n[0]+1)/2} + n[1]-- + } + for n[0]%2==0 { // remove trailing zeros + n[0]/=2 + n[2]++ + n[1]-- + } + return n; +} +*/ + +/* return a*b mod m */ +func Modmul(a1,b1,m *BIG) *BIG { + a:=NewBIGcopy(a1) + b:=NewBIGcopy(b1) + a.Mod(m) + b.Mod(m) + d:=mul(a,b); + return d.mod(m) +} + +/* return a^2 mod m */ +func Modsqr(a1,m *BIG) *BIG { + a:=NewBIGcopy(a1) + a.Mod(m) + d:=sqr(a) + return d.mod(m) +} + +/* return -a mod m */ +func Modneg(a1,m *BIG) *BIG { + a:=NewBIGcopy(a1) + a.Mod(m) + return m.Minus(a) +} + +/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */ +func (r *BIG) Jacobi(p *BIG) int { + m:=0; + t:=NewBIGint(0) + x:=NewBIGint(0) + n:=NewBIGint(0) + zilch:=NewBIGint(0) + one:=NewBIGint(1) + if (p.parity()==0 || comp(r,zilch)==0 || comp(p,one)<=0) {return 0} + r.norm() + x.copy(r) + n.copy(p) + x.Mod(p) + + for comp(n,one)>0 { + if comp(x,zilch)==0 {return 0} + n8:=n.lastbits(3) + k:=0 + for x.parity()==0 { + k++ + x.shr(1) + } + if k%2==1 {m+=(n8*n8-1)/8} + m+=(n8-1)*(x.lastbits(2)-1)/4 + t.copy(n) + t.Mod(x) + n.copy(x) + x.copy(t) + m%=2 + + } + if m==0 {return 1} + return -1 +} + +/* this=1/this mod p. Binary method */ +func (r *BIG) Invmodp(p *BIG) { + r.Mod(p) + u:=NewBIGcopy(r) + + v:=NewBIGcopy(p) + x1:=NewBIGint(1) + x2:=NewBIGint(0) + t:=NewBIGint(0) + one:=NewBIGint(1) + for (comp(u,one)!=0 && comp(v,one)!=0) { + for u.parity()==0 { + u.fshr(1); + if x1.parity()!=0 { + x1.add(p) + x1.norm() + } + x1.fshr(1) + } + for v.parity()==0 { + v.fshr(1); + if x2.parity()!=0 { + x2.add(p) + x2.norm() + } + x2.fshr(1) + } + if comp(u,v)>=0 { + u.sub(v) + u.norm() + if comp(x1,x2)>=0 { + x1.sub(x2) + } else { + t.copy(p) + t.sub(x2) + x1.add(t) + } + x1.norm() + } else { + v.sub(u) + v.norm() + if comp(x2,x1)>=0 { + x2.sub(x1) + } else { + t.copy(p) + t.sub(x1) + x2.add(t) + } + x2.norm() + } + } + if comp(u,one)==0 { + r.copy(x1) + } else {r.copy(x2)} +} + +/* return this^e mod m */ +func (r *BIG) powmod(e1 *BIG,m *BIG) *BIG { + e:=NewBIGcopy(e1) + r.norm() + e.norm() + a:=NewBIGint(1) + z:=NewBIGcopy(e) + s:=NewBIGcopy(r) + for true { + bt:=z.parity() + z.fshr(1) + if bt==1 {a=Modmul(a,s,m)} + if z.iszilch() {break} + s=Modsqr(s,m) + } + return a; +} + +/* Arazi and Qi inversion mod 256 */ +func invmod256(a int) int { + var t1 int=0 + c:=(a>>1)&1 + t1+=c + t1&=1 + t1=2-t1 + t1<<=1 + U:=t1+1; + +// i=2 + b:=a&3; + t1=U*b; t1>>=2 + c=(a>>2)&3 + t2:=(U*c)&3 + t1+=t2; + t1*=U; t1&=3 + t1=4-t1 + t1<<=2 + U+=t1 + +// i=4 + b=a&15 + t1=U*b; t1>>=4 + c=(a>>4)&15 + t2=(U*c)&15 + t1+=t2 + t1*=U; t1&=15 + t1=16-t1 + t1<<=4 + U+=t1 + + return U; +} + +func logb2(w uint32) uint { + v:=w + v |= (v >> 1) + v |= (v >> 2) + v |= (v >> 4) + v |= (v >> 8) + v |= (v >> 16) + + v = v - ((v >> 1) & 0x55555555) + v = (v & 0x33333333) + ((v >> 2) & 0x33333333) + r:= uint(( ((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24) + return (r) +} + + +/* +func main() { + a := NewBIGint(3) + m := NewBIGints(Modulus) + + fmt.Printf("Modulus= "+m.toString()) + fmt.Printf("\n") + + + e := NewBIGcopy(m); + e.dec(1); e.norm(); + fmt.Printf("Exponent= "+e.toString()) + fmt.Printf("\n") + a=a.powmod(e,m); + fmt.Printf("Result= "+a.toString()) +} +*/ diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/DBIG.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/DBIG.go new file mode 100644 index 00000000000..92a9b223c62 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/DBIG.go @@ -0,0 +1,273 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* MiotCL double length DBIG number class */ + + +package FP256BN + +import "strconv" + + +func NewDBIG() *DBIG { + b:=new(DBIG) + for i:=0;i>BASEBITS + + for i:=NLEN+1;i>BASEBITS + } + r.w[DNLEN-1]=(r.w[DNLEN-1]+carry) +} + +/* split DBIG at position n, return higher half, keep lower half */ +func (r *DBIG) split(n uint) *BIG { + t:=NewBIG() + m:=n%BASEBITS; + carry:=r.w[DNLEN-1]<<(BASEBITS-m) + + for i:=DNLEN-2;i>=NLEN-1;i-- { + nw:=(r.w[i]>>m)|carry; + carry=(r.w[i]<<(BASEBITS-m))&BMASK; + t.set(i-NLEN+1,nw); + } + r.w[NLEN-1]&=((Chunk(1)<b. Inputs must be normalised */ +func dcomp(a *DBIG,b *DBIG) int { + for i:=DNLEN-1;i>=0;i-- { + if a.w[i]==b.w[i] {continue} + if a.w[i]>b.w[i] { + return 1 + } else {return -1} + } + return 0 +} + +/* Copy from another DBIG */ +func (r *DBIG) copy(x *DBIG) { + for i:=0;i>(BASEBITS-n)) + for i:=DNLEN-2;i>m;i-- { + r.w[i]=((r.w[i-m]<>(BASEBITS-n)) + } + r.w[m]=(r.w[0]<>n)|((r.w[m+i+1]<<(BASEBITS-n))&BMASK) + } + r.w[DNLEN-m-1]=r.w[DNLEN-1]>>n; + for i:=DNLEN-m;i=0 { + m.shl(1); + k++; + } + + for k>0 { + m.shr(1); + + dr.copy(r); + dr.sub(m); + dr.norm(); + r.cmove(dr,int(1-((dr.w[DNLEN-1]>>uint(CHUNK-1))&1))); +/* + if dcomp(r,m)>=0 { + r.sub(m); + r.norm(); + } */ + k--; + } + return NewBIGdcopy(r) +} + +/* return this/c */ +func (r *DBIG) div(c *BIG) *BIG { + var d int + k:=0 + m:=NewDBIGscopy(c) + a:=NewBIGint(0) + e:=NewBIGint(1) + sr:=NewBIG() + dr:=NewDBIG() + r.norm() + + for dcomp(r,m)>=0 { + e.fshl(1) + m.shl(1) + k++ + } + + for k>0 { + m.shr(1) + e.shr(1) + + dr.copy(r); + dr.sub(m); + dr.norm(); + d=int(1-((dr.w[DNLEN-1]>>uint(CHUNK-1))&1)); + r.cmove(dr,d); + sr.copy(a); + sr.add(e); + sr.norm(); + a.cmove(sr,d); + +/* + if dcomp(r,m)>0 { + a.add(e) + a.norm() + r.sub(m) + r.norm() + } */ + k-- + } + return a +} + +/* Convert to Hex String */ +func (r *DBIG) toString() string { + s:="" + len:=r.nbits() + + if len%4==0 { + len/=4 + } else { + len/=4 + len++ + + } + + for i:=len-1;i>=0;i-- { + b:=NewDBIGcopy(r) + + b.shr(uint(i*4)) + s+=strconv.FormatInt(int64(b.w[0]&15),16) + } + return s +} + +/* return number of bits */ +func (r *DBIG) nbits() int { + k:=DNLEN-1 + r.norm() + for (k>=0 && r.w[k]==0) {k--} + if k<0 {return 0} + bts:=int(BASEBITS)*k; + c:=r.w[k]; + for c!=0 {c/=2; bts++} + return bts +} + diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/ECDH.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/ECDH.go new file mode 100644 index 00000000000..3882d43748a --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/ECDH.go @@ -0,0 +1,553 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* Elliptic Curve API high-level functions */ + +package FP256BN + + +import "github.com/hyperledger/fabric-amcl/amcl" + +const INVALID_PUBLIC_KEY int=-2 +const ERROR int=-3 +const INVALID int=-4 +const EFS int=int(MODBYTES) +const EGS int=int(MODBYTES) +//const EAS int=16 +//const EBS int=16 + + +//const ECDH_HASH_TYPE int=amcl.SHA512 + +/* Convert Integer to n-byte array */ +func inttoBytes(n int,len int) []byte { + var b []byte + var i int + for i=0;i0 && i>0) { + i--; + b[i]=byte(n&0xff) + n/=256 + } + return b +} + +func ehashit(sha int,A []byte,n int,B []byte,pad int) []byte { + var R []byte + if sha==amcl.SHA256 { + H:=amcl.NewHASH256() + H.Process_array(A) + if n>0 {H.Process_num(int32(n))} + if B!=nil {H.Process_array(B)} + R=H.Hash() + } + if sha==amcl.SHA384 { + H:=amcl.NewHASH384() + H.Process_array(A) + if n>0 {H.Process_num(int32(n))} + if B!=nil {H.Process_array(B)} + R=H.Hash() + } + if sha==amcl.SHA512 { + H:=amcl.NewHASH512() + H.Process_array(A) + if n>0 {H.Process_num(int32(n))} + if B!=nil {H.Process_array(B)} + R=H.Hash() + } + if R==nil {return nil} + + if pad==0 {return R} + var W []byte + for i:=0;iolen { + for i:=0;iolen { + for i:=0;i32 {b=128} + + var K0 [128]byte + olen:=len(tag) + + if (olen<4 /*|| olen>sha */) {return 0} + + for i:=0;i b { + B=ehashit(sha,K,0,nil,0) + for i:=0;i=len(C) { + fin=true; break + } else {ch=C[ipt]; ipt++ } + } + a.Decrypt(buff[:]) + if fin {break} + for i=0;i<16;i++ { + MM=append(MM,buff[i]); opt++ + } + } + + a.End(); + bad:=false + padlen:=int(buff[15]) + if (i!=15 || padlen<1 || padlen>16) {bad=true} + if (padlen>=2 && padlen<=16) { + for i=16-padlen;i<16;i++ { + if buff[i]!=byte(padlen) {bad=true} + } + } + + if !bad { + for i=0;i<16-padlen;i++ { + MM=append(MM,buff[i]); opt++ + } + } + + if bad {return nil} + + for i=0;i0 { + // s.mod2m(2*AES_S) + //} + s.ToBytes(S) + + WP:=G.mul(s) + + WP.ToBytes(W,false) // To use point compression on public keys, change to true + + return res +} + +/* validate public key */ +func ECDH_PUBLIC_KEY_VALIDATE(W []byte) int { + WP:=ECP_fromBytes(W) + res:=0 + + r:=NewBIGints(CURVE_Order) + + if WP.Is_infinity() {res=INVALID_PUBLIC_KEY} + if res==0 { + + q:=NewBIGints(Modulus) + nb:=q.nbits() + k:=NewBIGint(1); k.shl(uint((nb+4)/2)) + k.add(q) + k.div(r) + + for (k.parity()==0) { + k.shr(1) + WP.dbl() + } + + if !k.isunity() { + WP=WP.mul(k) + } + if WP.Is_infinity() {res=INVALID_PUBLIC_KEY} + + } + return res +} + +/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */ +func ECDH_ECPSVDP_DH(S []byte,WD []byte,Z []byte) int { + res:=0; + var T [EFS]byte + + s:=FromBytes(S) + + W:=ECP_fromBytes(WD) + if W.Is_infinity() {res=ERROR} + + if res==0 { + r:=NewBIGints(CURVE_Order) + s.Mod(r) + W=W.mul(s) + if W.Is_infinity() { + res=ERROR + } else { + W.GetX().ToBytes(T[:]) + for i:=0;i0 { + // u.mod2m(2*AES_S) + //} + V.Copy(G) + V=V.mul(u) + vx:=V.GetX() + c.copy(vx) + c.Mod(r); + if c.iszilch() {continue} + u.copy(Modmul(u,w,r)) + u.Invmodp(r) + d.copy(Modmul(s,c,r)) + d.add(f) + d.copy(Modmul(d,w,r)) + d.copy(Modmul(u,d,r)) + } + + c.ToBytes(T[:]) + for i:=0;i=0 || d.iszilch() || comp(d,r)>=0) { + res=INVALID; + } + + if res==0 { + d.Invmodp(r) + f.copy(Modmul(f,d,r)) + h2:=Modmul(c,d,r) + + WP:=ECP_fromBytes(W) + if WP.Is_infinity() { + res=ERROR + } else { + P:=NewECP() + P.Copy(WP) + + P=P.Mul2(h2,G,f) + + if P.Is_infinity() { + res=INVALID; + } else { + d=P.GetX() + d.Mod(r) + + if comp(d,c)!=0 {res=INVALID} + } + } + } + + return res +} + +/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */ +func ECDH_ECIES_ENCRYPT(sha int,P1 []byte,P2 []byte,RNG *amcl.RAND,W []byte,M []byte,V []byte,T []byte) []byte { + var Z [EFS]byte + var VZ [3*EFS+1]byte + var K1 [AESKEY]byte + var K2 [AESKEY]byte + var U [EGS]byte + + if ECDH_KEY_PAIR_GENERATE(RNG,U[:],V)!=0 {return nil} + if ECDH_ECPSVDP_DH(U[:],W,Z[:])!=0 {return nil} + + for i:=0;i<2*EFS+1;i++ {VZ[i]=V[i]} + for i:=0;i>31)&1) +} + +/* this=P */ +func (E *ECP) Copy(P *ECP) { + E.x.copy(P.x); + if CURVETYPE!=MONTGOMERY {E.y.copy(P.y)} + E.z.copy(P.z); +// E.INF=P.INF; +} + +/* this=-this */ +func (E *ECP) neg() { +// if E.Is_infinity() {return} + if CURVETYPE==WEIERSTRASS { + E.y.neg(); E.y.norm() + } + if CURVETYPE==EDWARDS { + E.x.neg(); E.x.norm() + } + return; +} + +/* Constant time select from pre-computed table */ +func (E *ECP) selector(W []*ECP,b int32) { + MP:=NewECP() + m:=b>>31; + babs:=(b^m)-m; + + babs=(babs-1)/2 + + E.cmove(W[0],teq(babs,0)) // conditional move + E.cmove(W[1],teq(babs,1)) + E.cmove(W[2],teq(babs,2)) + E.cmove(W[3],teq(babs,3)) + E.cmove(W[4],teq(babs,4)) + E.cmove(W[5],teq(babs,5)) + E.cmove(W[6],teq(babs,6)) + E.cmove(W[7],teq(babs,7)) + + MP.Copy(E); + MP.neg() + E.cmove(MP,int(m&1)); +} + +/* set this=O */ +func (E *ECP) inf() { +// E.INF=true; + E.x.zero() + if CURVETYPE!=MONTGOMERY {E.y.one()} + if CURVETYPE!=EDWARDS { + E.z.zero() + } else {E.z.one()} +} + +/* Test P == Q */ +func( E *ECP) Equals(Q *ECP) bool { +// if E.Is_infinity() && Q.Is_infinity() {return true} +// if E.Is_infinity() || Q.Is_infinity() {return false} + + a:=NewFPint(0) + b:=NewFPint(0) + a.copy(E.x); a.mul(Q.z); a.reduce() + b.copy(Q.x); b.mul(E.z); b.reduce() + if !a.Equals(b) {return false} + if CURVETYPE!=MONTGOMERY { + a.copy(E.y); a.mul(Q.z); a.reduce() + b.copy(Q.y); b.mul(E.z); b.reduce() + if !a.Equals(b) {return false} + } + + return true +} + +/* Calculate RHS of curve equation */ +func RHS(x *FP) *FP { + x.norm() + r:=NewFPcopy(x) + r.sqr(); + + if CURVETYPE==WEIERSTRASS { // x^3+Ax+B + b:=NewFPbig(NewBIGints(CURVE_B)) + r.mul(x); + if CURVE_A==-3 { + cx:=NewFPcopy(x) + cx.imul(3) + cx.neg(); cx.norm() + r.add(cx) + } + r.add(b) + } + if CURVETYPE==EDWARDS { // (Ax^2-1)/(Bx^2-1) + b:=NewFPbig(NewBIGints(CURVE_B)) + + one:=NewFPint(1) + b.mul(r) + b.sub(one) + b.norm() + if CURVE_A==-1 {r.neg()} + r.sub(one); r.norm() + b.inverse() + r.mul(b) + } + if CURVETYPE==MONTGOMERY { // x^3+Ax^2+x + x3:=NewFPint(0) + x3.copy(r) + x3.mul(x) + r.imul(CURVE_A) + r.add(x3) + r.add(x) + } + r.reduce() + return r +} + +/* set to affine - from (x,y,z) to (x,y) */ +func (E *ECP) Affine() { + if E.Is_infinity() {return} + one:=NewFPint(1) + if E.z.Equals(one) {return} + E.z.inverse() + E.x.mul(E.z); E.x.reduce() + + if CURVETYPE!=MONTGOMERY { + E.y.mul(E.z); E.y.reduce() + } + E.z.copy(one) +} + +/* extract x as a BIG */ +func (E *ECP) GetX() *BIG { + W:=NewECP(); W.Copy(E) + W.Affine() + return W.x.redc() +} +/* extract y as a BIG */ +func (E *ECP) GetY() *BIG { + W:=NewECP(); W.Copy(E) + W.Affine() + return W.y.redc() +} + +/* get sign of Y */ +func (E *ECP) GetS() int { + //E.Affine() + y:=E.GetY() + return y.parity() +} +/* extract x as an FP */ +func (E *ECP) getx() *FP { + return E.x; +} +/* extract y as an FP */ +func (E *ECP) gety() *FP { + return E.y +} +/* extract z as an FP */ +func (E *ECP) getz() *FP { + return E.z +} + +/* convert to byte array */ +func (E *ECP) ToBytes(b []byte,compress bool) { + var t [int(MODBYTES)]byte + MB:=int(MODBYTES) + W:=NewECP(); W.Copy(E); + W.Affine() + W.x.redc().ToBytes(t[:]) + for i:=0;i=0 {return NewECP()} + + if CURVETYPE==MONTGOMERY { + return NewECPbig(px) + } + + if b[0]==0x04 { + for i:=0;i=0 {return NewECP()} + return NewECPbigs(px,py) + } + + if b[0]==0x02 || b[0]==0x03 { + return NewECPbigint(px,int(b[0]&1)) + } + + return NewECP() +} + +/* convert to hex string */ +func (E *ECP) toString() string { + W:=NewECP(); W.Copy(E); + W.Affine() + if W.Is_infinity() {return "infinity"} + if CURVETYPE==MONTGOMERY { + return "("+W.x.redc().toString()+")" + } else {return "("+W.x.redc().toString()+","+W.y.redc().toString()+")"} +} + +/* this*=2 */ +func (E *ECP) dbl() { + +// if E.INF {return} + if CURVETYPE==WEIERSTRASS { + if CURVE_A==0 { + t0:=NewFPcopy(E.y) /*** Change ***/ // Edits made + t0.sqr() + t1:=NewFPcopy(E.y) + t1.mul(E.z) + t2:=NewFPcopy(E.z) + t2.sqr() + + E.z.copy(t0) + E.z.add(t0); E.z.norm(); + E.z.add(E.z); E.z.add(E.z); E.z.norm() + t2.imul(3*CURVE_B_I) + + x3:=NewFPcopy(t2) + x3.mul(E.z) + + y3:=NewFPcopy(t0) + y3.add(t2); y3.norm() + E.z.mul(t1) + t1.copy(t2); t1.add(t2); t2.add(t1) + t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3) + t1.copy(E.x); t1.mul(E.y) + E.x.copy(t0); E.x.norm(); E.x.mul(t1); E.x.add(E.x) + E.x.norm(); + E.y.copy(y3); E.y.norm(); + } else { + t0:=NewFPcopy(E.x) + t1:=NewFPcopy(E.y) + t2:=NewFPcopy(E.z) + t3:=NewFPcopy(E.x) + z3:=NewFPcopy(E.z) + y3:=NewFPint(0) + x3:=NewFPint(0) + b:=NewFPint(0) + + if CURVE_B_I==0 {b.copy(NewFPbig(NewBIGints(CURVE_B)))} + + t0.sqr() //1 x^2 + t1.sqr() //2 y^2 + t2.sqr() //3 + + t3.mul(E.y) //4 + t3.add(t3); t3.norm() //5 + z3.mul(E.x); //6 + z3.add(z3); z3.norm()//7 + y3.copy(t2) + + if CURVE_B_I==0 { + y3.mul(b) + } else { + y3.imul(CURVE_B_I) + } + + y3.sub(z3) //y3.norm(); //9 *** + x3.copy(y3); x3.add(y3); x3.norm() //10 + + y3.add(x3) //y3.norm();//11 + x3.copy(t1); x3.sub(y3); x3.norm() //12 + y3.add(t1); y3.norm() //13 + y3.mul(x3) //14 + x3.mul(t3) //15 + t3.copy(t2); t3.add(t2) //t3.norm(); //16 + t2.add(t3) //t2.norm(); //17 + + if CURVE_B_I==0 { + z3.mul(b) + } else { + z3.imul(CURVE_B_I) + } + + z3.sub(t2) //z3.norm();//19 + z3.sub(t0); z3.norm()//20 *** + t3.copy(z3); t3.add(z3) //t3.norm();//21 + + z3.add(t3); z3.norm() //22 + t3.copy(t0); t3.add(t0) //t3.norm(); //23 + t0.add(t3) //t0.norm();//24 + t0.sub(t2); t0.norm() //25 + + t0.mul(z3) //26 + y3.add(t0) //y3.norm();//27 + t0.copy(E.y); t0.mul(E.z)//28 + t0.add(t0); t0.norm() //29 + z3.mul(t0)//30 + x3.sub(z3) //x3.norm();//31 + t0.add(t0); t0.norm() //32 + t1.add(t1); t1.norm() //33 + z3.copy(t0); z3.mul(t1) //34 + + E.x.copy(x3); E.x.norm() + E.y.copy(y3); E.y.norm() + E.z.copy(z3); E.z.norm() + } + } + + if CURVETYPE==EDWARDS { + C:=NewFPcopy(E.x) + D:=NewFPcopy(E.y) + H:=NewFPcopy(E.z) + J:=NewFPint(0) + + E.x.mul(E.y); E.x.add(E.x); E.x.norm() + C.sqr() + D.sqr() + if CURVE_A==-1 {C.neg()} + E.y.copy(C); E.y.add(D); E.y.norm() + + H.sqr(); H.add(H) + E.z.copy(E.y) + J.copy(E.y); J.sub(H); J.norm() + E.x.mul(J) + C.sub(D); C.norm() + E.y.mul(C) + E.z.mul(J) + + + } + if CURVETYPE==MONTGOMERY { + A:=NewFPcopy(E.x) + B:=NewFPcopy(E.x) + AA:=NewFPint(0) + BB:=NewFPint(0) + C:=NewFPint(0) + + // if E.INF {return} + + A.add(E.z); A.norm() + AA.copy(A); AA.sqr() + B.sub(E.z); B.norm() + BB.copy(B); BB.sqr() + C.copy(AA); C.sub(BB) + C.norm() + + E.x.copy(AA); E.x.mul(BB) + + A.copy(C); A.imul((CURVE_A+2)/4) + + BB.add(A); BB.norm() + E.z.copy(BB); E.z.mul(C) + } + return; +} + +/* this+=Q */ +func (E *ECP) Add(Q *ECP) { +/* + if E.INF { + E.Copy(Q) + return + } + if Q.INF {return} +*/ + if CURVETYPE==WEIERSTRASS { + if CURVE_A==0 { + b:=3*CURVE_B_I + t0:=NewFPcopy(E.x) + t0.mul(Q.x) + t1:=NewFPcopy(E.y) + t1.mul(Q.y) + t2:=NewFPcopy(E.z) + t2.mul(Q.z) + t3:=NewFPcopy(E.x) + t3.add(E.y); t3.norm() + t4:=NewFPcopy(Q.x) + t4.add(Q.y); t4.norm() + t3.mul(t4) + t4.copy(t0); t4.add(t1) + + t3.sub(t4); t3.norm() + t4.copy(E.y) + t4.add(E.z); t4.norm() + x3:=NewFPcopy(Q.y) + x3.add(Q.z); x3.norm() + + t4.mul(x3) + x3.copy(t1) + x3.add(t2) + + t4.sub(x3); t4.norm() + x3.copy(E.x); x3.add(E.z); x3.norm() + y3:=NewFPcopy(Q.x) + y3.add(Q.z); y3.norm() + x3.mul(y3) + y3.copy(t0) + y3.add(t2) + y3.rsub(x3); y3.norm() + x3.copy(t0); x3.add(t0) + t0.add(x3); t0.norm() + t2.imul(b) + + z3:=NewFPcopy(t1); z3.add(t2); z3.norm() + t1.sub(t2); t1.norm() + y3.imul(b) + + x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2) + y3.mul(t0); t1.mul(z3); y3.add(t1) + t0.mul(t3); z3.mul(t4); z3.add(t0) + + E.x.copy(x3); E.x.norm() + E.y.copy(y3); E.y.norm() + E.z.copy(z3); E.z.norm() + } else { + + t0:=NewFPcopy(E.x) + t1:=NewFPcopy(E.y) + t2:=NewFPcopy(E.z) + t3:=NewFPcopy(E.x) + t4:=NewFPcopy(Q.x) + z3:=NewFPint(0) + y3:=NewFPcopy(Q.x) + x3:=NewFPcopy(Q.y) + b:=NewFPint(0) + + if CURVE_B_I==0 {b.copy(NewFPbig(NewBIGints(CURVE_B)))} + + t0.mul(Q.x) //1 + t1.mul(Q.y) //2 + t2.mul(Q.z) //3 + + t3.add(E.y); t3.norm() //4 + t4.add(Q.y); t4.norm() //5 + t3.mul(t4) //6 + t4.copy(t0); t4.add(t1) //t4.norm(); //7 + t3.sub(t4); t3.norm() //8 + t4.copy(E.y); t4.add(E.z); t4.norm() //9 + x3.add(Q.z); x3.norm() //10 + t4.mul(x3) //11 + x3.copy(t1); x3.add(t2) //x3.norm();//12 + + t4.sub(x3); t4.norm() //13 + x3.copy(E.x); x3.add(E.z); x3.norm() //14 + y3.add(Q.z); y3.norm() //15 + + x3.mul(y3) //16 + y3.copy(t0); y3.add(t2) //y3.norm();//17 + + y3.rsub(x3); y3.norm() //18 + z3.copy(t2) + + if CURVE_B_I==0 { + z3.mul(b) + } else { + z3.imul(CURVE_B_I) + } + + x3.copy(y3); x3.sub(z3); x3.norm() //20 + z3.copy(x3); z3.add(x3) //z3.norm(); //21 + + x3.add(z3) //x3.norm(); //22 + z3.copy(t1); z3.sub(x3); z3.norm() //23 + x3.add(t1); x3.norm() //24 + + if CURVE_B_I==0 { + y3.mul(b) + } else { + y3.imul(CURVE_B_I) + } + + t1.copy(t2); t1.add(t2); //t1.norm();//26 + t2.add(t1) //t2.norm();//27 + + y3.sub(t2) //y3.norm(); //28 + + y3.sub(t0); y3.norm() //29 + t1.copy(y3); t1.add(y3) //t1.norm();//30 + y3.add(t1); y3.norm() //31 + + t1.copy(t0); t1.add(t0) //t1.norm(); //32 + t0.add(t1) //t0.norm();//33 + t0.sub(t2); t0.norm() //34 + t1.copy(t4); t1.mul(y3) //35 + t2.copy(t0); t2.mul(y3) //36 + y3.copy(x3); y3.mul(z3) //37 + y3.add(t2) //y3.norm();//38 + x3.mul(t3) //39 + x3.sub(t1) //40 + z3.mul(t4) //41 + t1.copy(t3); t1.mul(t0) //42 + z3.add(t1) + E.x.copy(x3); E.x.norm() + E.y.copy(y3); E.y.norm() + E.z.copy(z3); E.z.norm() + + } + } + if CURVETYPE==EDWARDS { + b:=NewFPbig(NewBIGints(CURVE_B)) + A:=NewFPcopy(E.z) + B:=NewFPint(0) + C:=NewFPcopy(E.x) + D:=NewFPcopy(E.y) + EE:=NewFPint(0) + F:=NewFPint(0) + G:=NewFPint(0) + + A.mul(Q.z); + B.copy(A); B.sqr() + C.mul(Q.x) + D.mul(Q.y) + + EE.copy(C); EE.mul(D); EE.mul(b) + F.copy(B); F.sub(EE) + G.copy(B); G.add(EE) + + if CURVE_A==1 { + EE.copy(D); EE.sub(C) + } + C.add(D) + + B.copy(E.x); B.add(E.y) + D.copy(Q.x); D.add(Q.y) + B.norm(); D.norm() + B.mul(D) + B.sub(C) + B.norm(); F.norm() + B.mul(F) + E.x.copy(A); E.x.mul(B) + G.norm() + if CURVE_A==1 { + EE.norm(); C.copy(EE); C.mul(G) + } + if CURVE_A==-1 { + C.norm(); C.mul(G) + } + E.y.copy(A); E.y.mul(C) + E.z.copy(F); E.z.mul(G) + } + return +} + +/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */ +func (E *ECP) dadd(Q *ECP,W *ECP) { + A:=NewFPcopy(E.x) + B:=NewFPcopy(E.x) + C:=NewFPcopy(Q.x) + D:=NewFPcopy(Q.x) + DA:=NewFPint(0) + CB:=NewFPint(0) + + A.add(E.z) + B.sub(E.z) + + C.add(Q.z) + D.sub(Q.z) + A.norm(); D.norm() + + DA.copy(D); DA.mul(A) + C.norm(); B.norm() + + CB.copy(C); CB.mul(B) + + A.copy(DA); A.add(CB); A.norm(); A.sqr() + B.copy(DA); B.sub(CB); B.norm(); B.sqr() + + E.x.copy(A) + E.z.copy(W.x); E.z.mul(B) + +// if E.z.iszilch() { +// E.inf() +// } else {E.INF=false;} + +} + +/* this-=Q */ +func (E *ECP) Sub(Q *ECP) { + NQ:=NewECP(); NQ.Copy(Q); + NQ.neg() + E.Add(NQ) +} + +/* constant time multiply by small integer of length bts - use ladder */ +func (E *ECP) pinmul(e int32,bts int32) *ECP { + if CURVETYPE==MONTGOMERY { + return E.mul(NewBIGint(int(e))) + } else { + P:=NewECP() + R0:=NewECP() + R1:=NewECP(); R1.Copy(E) + + for i:=bts-1;i>=0;i-- { + b:=int((e>>uint32(i))&1) + P.Copy(R1) + P.Add(R0) + R0.cswap(R1,b) + R1.Copy(P) + R0.dbl() + R0.cswap(R1,b) + } + P.Copy(R0) + P.Affine() + return P + } +} + +/* return e.this */ + +func (E *ECP) mul(e *BIG) *ECP { + if (e.iszilch() || E.Is_infinity()) {return NewECP()} + P:=NewECP() + if CURVETYPE==MONTGOMERY { +/* use Ladder */ + D:=NewECP(); + R0:=NewECP(); R0.Copy(E) + R1:=NewECP(); R1.Copy(E) + R1.dbl() + D.Copy(E); D.Affine() + nb:=e.nbits() + for i:=nb-2;i>=0;i-- { + b:=int(e.bit(i)) + P.Copy(R1) + P.dadd(R0,D) + R0.cswap(R1,b) + R1.Copy(P) + R0.dbl() + R0.cswap(R1,b) + } + P.Copy(R0) + } else { +// fixed size windows + mt:=NewBIG() + t:=NewBIG() + Q:=NewECP() + C:=NewECP() + + var W []*ECP + var w [1+(NLEN*int(BASEBITS)+3)/4]int8 + + //E.Affine(); + + Q.Copy(E); + Q.dbl(); + + W=append(W,NewECP()); + W[0].Copy(E); + + for i:=1;i<8;i++ { + W=append(W,NewECP()) + W[i].Copy(W[i-1]) + W[i].Add(Q) + } + +// make exponent odd - add 2P if even, P if odd + t.copy(e) + s:=int(t.parity()) + t.inc(1); t.norm(); ns:=int(t.parity()); mt.copy(t); mt.inc(1); mt.norm() + t.cmove(mt,s) + Q.cmove(E,ns) + C.Copy(Q) + + nb:=1+(t.nbits()+3)/4 + +// convert exponent to signed 4-bit window + for i:=0;i=0;i-- { + Q.selector(W,int32(w[i])) + P.dbl() + P.dbl() + P.dbl() + P.dbl() + P.Add(Q) + } + P.Sub(C) /* apply correction */ + } + P.Affine() + return P +} + +/* Public version */ +func (E *ECP) Mul(e *BIG) *ECP { + return E.mul(e) +} + +/* Return e.this+f.Q */ + +func (E *ECP) Mul2(e *BIG,Q *ECP,f *BIG) *ECP { + te:=NewBIG() + tf:=NewBIG() + mt:=NewBIG() + S:=NewECP() + T:=NewECP() + C:=NewECP() + var W [] *ECP + //ECP[] W=new ECP[8]; + var w [1+(NLEN*int(BASEBITS)+1)/2]int8 + + //E.Affine() + //Q.Affine() + + te.copy(e) + tf.copy(f) + +// precompute table + for i:=0;i<8;i++ { + W=append(W,NewECP()) + } + W[1].Copy(E); W[1].Sub(Q) + W[2].Copy(E); W[2].Add(Q); + S.Copy(Q); S.dbl(); + W[0].Copy(W[1]); W[0].Sub(S); + W[3].Copy(W[2]); W[3].Add(S); + T.Copy(E); T.dbl(); + W[5].Copy(W[1]); W[5].Add(T); + W[6].Copy(W[2]); W[6].Add(T); + W[4].Copy(W[5]); W[4].Sub(S); + W[7].Copy(W[6]); W[7].Add(S); + +// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction + + s:=int(te.parity()); + te.inc(1); te.norm(); ns:=int(te.parity()); mt.copy(te); mt.inc(1); mt.norm() + te.cmove(mt,s) + T.cmove(E,ns) + C.Copy(T) + + s=int(tf.parity()) + tf.inc(1); tf.norm(); ns=int(tf.parity()); mt.copy(tf); mt.inc(1); mt.norm() + tf.cmove(mt,s) + S.cmove(Q,ns) + C.Add(S) + + mt.copy(te); mt.add(tf); mt.norm() + nb:=1+(mt.nbits()+1)/2 + +// convert exponent to signed 2-bit window + for i:=0;i=0;i-- { + T.selector(W,int32(w[i])); + S.dbl() + S.dbl() + S.Add(T) + } + S.Sub(C) /* apply correction */ + S.Affine() + return S +} + +func (E *ECP) cfp() { + cf:=CURVE_Cof_I; + if cf==1 {return} + if cf==4 { + E.dbl(); E.dbl() + //E.Affine(); + return; + } + if cf==8 { + E.dbl(); E.dbl(); E.dbl() + //E.Affine(); + return; + } + c:=NewBIGints(CURVE_Cof); + E.Copy(E.mul(c)); +} + +func ECP_mapit(h []byte) *ECP { + q:=NewBIGints(Modulus) + x:=FromBytes(h[:]) + x.Mod(q) + var P *ECP + + for true { + for true { + if CURVETYPE!=MONTGOMERY { + P=NewECPbigint(x,0) + } else { + P=NewECPbig(x) + } + x.inc(1); x.norm() + if !P.Is_infinity() {break} + } + P.cfp() + if !P.Is_infinity() {break} + } + + return P +} + +func ECP_generator() *ECP { + var G *ECP + + gx:=NewBIGints(CURVE_Gx) + if CURVETYPE!=MONTGOMERY { + gy:=NewBIGints(CURVE_Gy) + G=NewECPbigs(gx,gy) + } else { + G=NewECPbig(gx) + } + return G +} + +/* +func main() { + Gx:=NewBIGints(CURVE_Gx); + var Gy *BIG + var P *ECP + + if CURVETYPE!=MONTGOMERY {Gy=NewBIGints(CURVE_Gy)} + r:=NewBIGints(CURVE_Order) + + //r.dec(7); + + fmt.Printf("Gx= "+Gx.toString()) + fmt.Printf("\n") + + if CURVETYPE!=MONTGOMERY { + fmt.Printf("Gy= "+Gy.toString()) + fmt.Printf("\n") + } + + if CURVETYPE!=MONTGOMERY { + P=NewECPbigs(Gx,Gy) + } else {P=NewECPbig(Gx)} + + fmt.Printf("P= "+P.toString()); + fmt.Printf("\n") + + R:=P.mul(r); + //for (int i=0;i<10000;i++) + // R=P.mul(r); + + fmt.Printf("R= "+R.toString()) + fmt.Printf("\n") +} +*/ \ No newline at end of file diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/ECP2.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/ECP2.go new file mode 100644 index 00000000000..e8d3c5ff14d --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/ECP2.go @@ -0,0 +1,699 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* MiotCL Weierstrass elliptic curve functions over FP2 */ + +package FP256BN + + + +type ECP2 struct { + x *FP2 + y *FP2 + z *FP2 +// INF bool +} + +func NewECP2() *ECP2 { + E:=new(ECP2) + E.x=NewFP2int(0) + E.y=NewFP2int(1) + E.z=NewFP2int(0) +// E.INF=true + return E +} + +/* Test this=O? */ +func (E *ECP2) Is_infinity() bool { +// if E.INF {return true} + E.x.reduce(); E.y.reduce(); E.z.reduce() + return E.x.iszilch() && E.z.iszilch() +} +/* copy this=P */ +func (E *ECP2) Copy(P *ECP2) { + E.x.copy(P.x) + E.y.copy(P.y) + E.z.copy(P.z) +// E.INF=P.INF +} +/* set this=O */ +func (E *ECP2) inf() { +// E.INF=true + E.x.zero() + E.y.one() + E.z.zero() +} + +/* set this=-this */ +func (E *ECP2) neg() { +// if E.Is_infinity() {return} + E.y.norm(); E.y.neg(); E.y.norm() +} + +/* Conditional move of Q to P dependant on d */ +func (E *ECP2) cmove(Q *ECP2,d int) { + E.x.cmove(Q.x,d) + E.y.cmove(Q.y,d) + E.z.cmove(Q.z,d) +/* + var bd bool + if (d==0) { + bd=false + } else {bd=true} + E.INF=(E.INF!=(E.INF!=Q.INF)&&bd) +*/ +} + +/* Constant time select from pre-computed table */ +func (E *ECP2) selector(W []*ECP2,b int32) { + MP:=NewECP2() + m:=b>>31 + babs:=(b^m)-m + + babs=(babs-1)/2 + + E.cmove(W[0],teq(babs,0)) // conditional move + E.cmove(W[1],teq(babs,1)) + E.cmove(W[2],teq(babs,2)) + E.cmove(W[3],teq(babs,3)) + E.cmove(W[4],teq(babs,4)) + E.cmove(W[5],teq(babs,5)) + E.cmove(W[6],teq(babs,6)) + E.cmove(W[7],teq(babs,7)) + + MP.Copy(E) + MP.neg() + E.cmove(MP,int(m&1)) +} + +/* Test if P == Q */ +func (E *ECP2) Equals(Q *ECP2) bool { +// if E.Is_infinity() && Q.Is_infinity() {return true} +// if E.Is_infinity() || Q.Is_infinity() {return false} + + a:=NewFP2copy(E.x) + b:=NewFP2copy(Q.x) + a.mul(Q.z); b.mul(E.z) + + if !a.Equals(b) {return false} + a.copy(E.y); b.copy(Q.y) + a.mul(Q.z); b.mul(E.z); + if !a.Equals(b) {return false} + + return true +} + +/* set to Affine - (x,y,z) to (x,y) */ +func (E *ECP2) Affine() { + if E.Is_infinity() {return} + one:=NewFP2int(1) + if E.z.Equals(one) {E.x.reduce(); E.y.reduce(); return} + E.z.inverse() + + E.x.mul(E.z); E.x.reduce() + E.y.mul(E.z); E.y.reduce() + E.z.copy(one) +} + +/* extract affine x as FP2 */ +func (E *ECP2) GetX() *FP2 { + W:=NewECP2(); W.Copy(E) + W.Affine() + return W.x +} +/* extract affine y as FP2 */ +func (E *ECP2) GetY() *FP2 { + W:=NewECP2(); W.Copy(E) + W.Affine() + return W.y; +} +/* extract projective x */ +func (E *ECP2) getx() *FP2 { + return E.x +} +/* extract projective y */ +func (E *ECP2) gety() *FP2 { + return E.y +} +/* extract projective z */ +func (E *ECP2) getz() *FP2 { + return E.z +} + +/* convert to byte array */ +func (E *ECP2) ToBytes(b []byte) { + var t [int(MODBYTES)]byte + MB:=int(MODBYTES) + + W:=NewECP2(); W.Copy(E); + W.Affine() + + W.x.GetA().ToBytes(t[:]) + for i:=0;i=0;i-- { + Q.selector(W,int32(w[i])) + P.dbl() + P.dbl() + P.dbl() + P.dbl() + P.Add(Q) + } + P.Sub(C) + P.Affine() + return P +} + +/* Public version */ +func (E *ECP2) Mul(e *BIG) *ECP2 { + return E.mul(e) +} + +/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */ +// Bos & Costello https://eprint.iacr.org/2013/458.pdf +// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf +// Side channel attack secure +func mul4(Q []*ECP2,u []*BIG) *ECP2 { + W:=NewECP2() + P:=NewECP2() + var T [] *ECP2 + mt:=NewBIG() + var t [] *BIG + + var w [NLEN*int(BASEBITS)+1]int8 + var s [NLEN*int(BASEBITS)+1]int8 + + for i:=0;i<4;i++ { + t=append(t,NewBIGcopy(u[i])); + //Q[i].Affine(); + } + + T=append(T,NewECP2()); T[0].Copy(Q[0]) // Q[0] + T=append(T,NewECP2()); T[1].Copy(T[0]); T[1].Add(Q[1]) // Q[0]+Q[1] + T=append(T,NewECP2()); T[2].Copy(T[0]); T[2].Add(Q[2]) // Q[0]+Q[2] + T=append(T,NewECP2()); T[3].Copy(T[1]); T[3].Add(Q[2]) // Q[0]+Q[1]+Q[2] + T=append(T,NewECP2()); T[4].Copy(T[0]); T[4].Add(Q[3]) // Q[0]+Q[3] + T=append(T,NewECP2()); T[5].Copy(T[1]); T[5].Add(Q[3]) // Q[0]+Q[1]+Q[3] + T=append(T,NewECP2()); T[6].Copy(T[2]); T[6].Add(Q[3]) // Q[0]+Q[2]+Q[3] + T=append(T,NewECP2()); T[7].Copy(T[3]); T[7].Add(Q[3]) // Q[0]+Q[1]+Q[2]+Q[3] + +// Make it odd + pb:=1-t[0].parity() + t[0].inc(pb) +// t[0].norm(); + +// Number of bits + mt.zero() + for i:=0;i<4;i++ { + t[i].norm() + mt.or(t[i]) + } + + nb:=1+mt.nbits(); + +// Sign pivot + s[nb-1]=1 + for i:=0;i>1) + t[j].norm() + w[i]+=bt*int8(k) + k*=2 + } + } + +// Main loop + P.selector(T,int32(2*w[nb-1]+1)) + for i:=nb-2;i>=0;i-- { + P.dbl() + W.selector(T,int32(2*w[i]+s[i])) + P.Add(W) + } + +// apply correction + W.Copy(P) + W.Sub(Q[0]) + P.cmove(W,pb) + + P.Affine() + return P +} + +/* +func mul4(Q []*ECP2,u []*BIG) *ECP2 { + var a [4]int8 + T:=NewECP2() + C:=NewECP2() + P:=NewECP2() + + var W [] *ECP2 + + mt:=NewBIG() + var t []*BIG + + var w [NLEN*int(BASEBITS)+1]int8 + + for i:=0;i<4;i++ { + t=append(t,NewBIGcopy(u[i])); + Q[i].Affine(); + } + +// precompute table + + W=append(W,NewECP2()); W[0].Copy(Q[0]); W[0].Sub(Q[1]) + W=append(W,NewECP2()); W[1].Copy(W[0]) + W=append(W,NewECP2()); W[2].Copy(W[0]) + W=append(W,NewECP2()); W[3].Copy(W[0]) + W=append(W,NewECP2()); W[4].Copy(Q[0]); W[4].Add(Q[1]) + W=append(W,NewECP2()); W[5].Copy(W[4]) + W=append(W,NewECP2()); W[6].Copy(W[4]) + W=append(W,NewECP2()); W[7].Copy(W[4]) + + T.Copy(Q[2]); T.Sub(Q[3]) + W[1].Sub(T) + W[2].Add(T) + W[5].Sub(T) + W[6].Add(T) + T.Copy(Q[2]); T.Add(Q[3]) + W[0].Sub(T) + W[3].Add(T) + W[4].Sub(T) + W[7].Add(T) + +// if multiplier is even add 1 to multiplier, and add P to correction + mt.zero(); C.inf() + for i:=0;i<4;i++ { + if t[i].parity()==0 { + t[i].inc(1); t[i].norm() + C.Add(Q[i]) + } + mt.add(t[i]); mt.norm() + } + + nb:=1+mt.nbits(); + +// convert exponent to signed 1-bit window + for j:=0;j=0;i-- { + T.selector(W,int32(w[i])) + P.dbl() + P.Add(T) + } + P.Sub(C) // apply correction + + P.Affine() + return P +} +*/ + +/* needed for SOK */ +func ECP2_mapit(h []byte) *ECP2 { + q:=NewBIGints(Modulus) + x:=FromBytes(h[:]) + one:=NewBIGint(1) + var X *FP2 + var Q,T,K,xQ,x2Q *ECP2 + x.Mod(q) + for true { + X=NewFP2bigs(one,x) + Q=NewECP2fp2(X) + if !Q.Is_infinity() {break} + x.inc(1); x.norm() + } +/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */ + Fra:=NewBIGints(Fra) + Frb:=NewBIGints(Frb) + X=NewFP2bigs(Fra,Frb) + if SEXTIC_TWIST == M_TYPE { + X.inverse() + X.norm() + } + + x=NewBIGints(CURVE_Bnx) + + if CURVE_PAIRING_TYPE==BN { + T=NewECP2(); T.Copy(Q) + T=T.mul(x); + if SIGN_OF_X==NEGATIVEX { + T.neg() + } + + K=NewECP2(); K.Copy(T) + K.dbl(); K.Add(T); //K.Affine() + + K.frob(X) + Q.frob(X); Q.frob(X); Q.frob(X) + Q.Add(T); Q.Add(K) + T.frob(X); T.frob(X) + Q.Add(T) + } + if CURVE_PAIRING_TYPE==BLS { +// xQ=NewECP2() +// x2Q=NewECP2() + + xQ=Q.mul(x) + x2Q=xQ.mul(x) + + if SIGN_OF_X==NEGATIVEX { + xQ.neg() + } + + x2Q.Sub(xQ) + x2Q.Sub(Q) + + xQ.Sub(Q) + xQ.frob(X) + + Q.dbl() + Q.frob(X) + Q.frob(X) + + Q.Add(x2Q) + Q.Add(xQ) + } + Q.Affine() + return Q +} + +func ECP2_generator() *ECP2 { + var G *ECP2 + G=NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa),NewBIGints(CURVE_Pxb)),NewFP2bigs(NewBIGints(CURVE_Pya),NewBIGints(CURVE_Pyb))) + return G +} diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP.go new file mode 100644 index 00000000000..ff7fe5e0df5 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP.go @@ -0,0 +1,414 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* Finite Field arithmetic */ +/* CLINT mod p functions */ + +package FP256BN + + + +const NOT_SPECIAL int=0 +const PSEUDO_MERSENNE int=1 +const MONTGOMERY_FRIENDLY int=2 +const GENERALISED_MERSENNE int=3 + +const MODBITS uint=256 /* Number of bits in Modulus */ +const MOD8 uint=3 /* Modulus mod 8 */ +const MODTYPE int=NOT_SPECIAL //NOT_SPECIAL + +const FEXCESS int32=(int32(1)<<24) +const OMASK Chunk= ((Chunk(-1))<<(MODBITS%BASEBITS)) +const TBITS uint=MODBITS%BASEBITS // Number of active bits in top word +const TMASK Chunk=(Chunk(1)<>TBITS)+(v<<(BASEBITS-TBITS)))) + + t.norm() + return t + // b.add(t) + // b.norm() + // return b + } + if MODTYPE==MONTGOMERY_FRIENDLY { + for i:=0;i>TBITS + b.w[NLEN-1]&=TMASK + b.w[0]+=carry + + b.w[224/BASEBITS]+=carry<<(224%BASEBITS); + b.norm() + return b + } + + if MODTYPE==NOT_SPECIAL { + md:=NewBIGints(Modulus) + return monty(md,MConst,d) + } + return NewBIG() +} + + +/* reduce this mod Modulus */ +func (F *FP) reduce() { + p:=NewBIGints(Modulus) + F.x.Mod(p) + F.XES=1 +} + +/* test this=0? */ +func (F *FP) iszilch() bool { + W:=NewFPcopy(F) + W.reduce() + return W.x.iszilch() +} + +/* copy from FP b */ +func (F *FP) copy(b *FP ) { + F.x.copy(b.x) + F.XES=b.XES +} + +/* set this=0 */ +func (F *FP) zero() { + F.x.zero() + F.XES=1 +} + +/* set this=1 */ +func (F *FP) one() { + F.x.one(); F.nres() +} + +/* normalise this */ +func (F *FP) norm() { + F.x.norm() +} + +/* swap FPs depending on d */ +func (F *FP) cswap(b *FP,d int) { + c:=int32(d) + c=^(c-1) + t:=c&(F.XES^b.XES) + F.XES^=t + b.XES^=t + F.x.cswap(b.x,d) +} + +/* copy FPs depending on d */ +func (F *FP) cmove(b *FP,d int) { + F.x.cmove(b.x,d) + c:=int32(-d) + F.XES^=(F.XES^b.XES)&c +} + +/* this*=b mod Modulus */ +func (F *FP) mul(b *FP) { + + if int64(F.XES)*int64(b.XES)>int64(FEXCESS) {F.reduce()} + + d:=mul(F.x,b.x) + F.x.copy(mod(d)) + F.XES=2 +} + +/* this = -this mod Modulus */ +func (F *FP) neg() { + m:=NewBIGints(Modulus) + sb:=logb2(uint32(F.XES-1)) + + m.fshl(sb) + F.x.rsub(m) + + F.XES=(1<FEXCESS {F.reduce()} +} + + +/* this*=c mod Modulus, where c is a small int */ +func (F *FP) imul(c int) { +// F.norm() + s:=false + if (c<0) { + c=-c + s=true + } + + if MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE { + d:=F.x.pxmul(c) + F.x.copy(mod(d)) + F.XES=2 + } else { + if F.XES*int32(c)<=FEXCESS { + F.x.pmul(c) + F.XES*=int32(c) + } else { + n:=NewFPint(c) + F.mul(n) + } + } + if s {F.neg(); F.norm()} +} + +/* this*=this mod Modulus */ +func (F *FP) sqr() { + if int64(F.XES)*int64(F.XES)>int64(FEXCESS) {F.reduce()} + d:=sqr(F.x) + F.x.copy(mod(d)) + F.XES=2 +} + +/* this+=b */ +func (F *FP) add(b *FP) { + F.x.add(b.x) + F.XES+=b.XES + if (F.XES>FEXCESS) {F.reduce()} +} + +/* this-=b */ +func (F *FP) sub(b *FP) { + n:=NewFPcopy(b) + n.neg() + F.add(n) +} + +func (F *FP) rsub(b *FP) { + F.neg() + F.add(b) +} + +/* this/=2 mod Modulus */ +func (F *FP) div2() { +// F.x.norm() + if (F.x.parity()==0) { + F.x.fshr(1) + } else { + p:=NewBIGints(Modulus); + F.x.add(p) + F.x.norm() + F.x.fshr(1) + } +} + +/* this=1/this mod Modulus */ +func (F *FP) inverse() { +/* + p:=NewBIGints(Modulus); + r:=F.redc() + r.Invmodp(p) + F.x.copy(r) + F.nres() +*/ + + m2:=NewBIGints(Modulus); + m2.dec(2); m2.norm() + F.copy(F.pow(m2)) + +} + +/* return TRUE if this==a */ +func (F *FP) Equals(a *FP) bool { + f:=NewFPcopy(F) + s:=NewFPcopy(a); + + s.reduce() + f.reduce() + if (comp(s.x,f.x)==0) {return true} + return false +} + +/* return this^e mod Modulus */ +/* +func (F *FP) pow(e *BIG) *FP { + r:=NewFPint(1) + e.norm() + F.norm() + m:=NewFPcopy(F) + for true { + bt:=e.parity() + e.fshr(1) + if bt==1 {r.mul(m)} + if e.iszilch() {break} + m.sqr() + } + r.reduce() + return r +} +*/ + + +func (F *FP) pow(e *BIG) *FP { + var tb []*FP + var w [1+(NLEN*int(BASEBITS)+3)/4]int8 + F.norm() + t:=NewBIGcopy(e) + t.norm() + nb:=1+(t.nbits()+3)/4 + + for i:=0;i=0;i-- { + r.sqr() + r.sqr() + r.sqr() + r.sqr() + r.mul(tb[w[i]]) + } + r.reduce() + return r +} + + +/* return sqrt(this) mod Modulus */ +func (F *FP) sqrt() *FP { + F.reduce(); + p:=NewBIGints(Modulus); + b:=NewBIGcopy(p) + if MOD8==5 { + b.dec(5); b.norm(); b.shr(3) + i:=NewFPcopy(F); i.x.shl(1) + v:=i.pow(b) + i.mul(v); i.mul(v) + i.x.dec(1) + r:=NewFPcopy(F) + r.mul(v); r.mul(i) + r.reduce() + return r + } else { + b.inc(1); b.norm(); b.shr(2) + return F.pow(b); + } +} + +/* return jacobi symbol (this/Modulus) */ +func (F *FP) jacobi() int { + w:=F.redc(); + p:=NewBIGints(Modulus); + return w.Jacobi(p) +} diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP12.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP12.go new file mode 100644 index 00000000000..84d37dc4468 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP12.go @@ -0,0 +1,763 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* MiotCL Fp^12 functions */ +/* FP12 elements are of the form a+i.b+i^2.c */ + +package FP256BN + + + +type FP12 struct { + a *FP4 + b *FP4 + c *FP4 +} + +/* Constructors */ +func NewFP12fp4(d *FP4) *FP12 { + F:=new(FP12) + F.a=NewFP4copy(d) + F.b=NewFP4int(0) + F.c=NewFP4int(0) + return F +} + +func NewFP12int(d int) *FP12 { + F:=new(FP12) + F.a=NewFP4int(d) + F.b=NewFP4int(0) + F.c=NewFP4int(0) + return F +} + +func NewFP12fp4s(d *FP4,e *FP4,f *FP4) *FP12 { + F:=new(FP12) + F.a=NewFP4copy(d) + F.b=NewFP4copy(e) + F.c=NewFP4copy(f) + return F +} + +func NewFP12copy(x *FP12) *FP12 { + F:=new(FP12) + F.a=NewFP4copy(x.a) + F.b=NewFP4copy(x.b) + F.c=NewFP4copy(x.c) + return F +} + +/* reduce all components of this mod Modulus */ +func (F *FP12) reduce() { + F.a.reduce() + F.b.reduce() + F.c.reduce() +} +/* normalise all components of this */ +func (F *FP12) norm() { + F.a.norm() + F.b.norm() + F.c.norm() +} +/* test x==0 ? */ +func (F *FP12) iszilch() bool { + //F.reduce() + return (F.a.iszilch() && F.b.iszilch() && F.c.iszilch()) +} + +/* Conditional move */ +func (F *FP12) cmove(g *FP12,d int) { + F.a.cmove(g.a,d) + F.b.cmove(g.b,d) + F.c.cmove(g.c,d) +} + +/* Constant time select from pre-computed table */ +func (F *FP12) selector(g []*FP12,b int32) { + + m:=b>>31 + babs:=(b^m)-m + + babs=(babs-1)/2 + + F.cmove(g[0],teq(babs,0)) // conditional move + F.cmove(g[1],teq(babs,1)) + F.cmove(g[2],teq(babs,2)) + F.cmove(g[3],teq(babs,3)) + F.cmove(g[4],teq(babs,4)) + F.cmove(g[5],teq(babs,5)) + F.cmove(g[6],teq(babs,6)) + F.cmove(g[7],teq(babs,7)) + + invF:=NewFP12copy(F) + invF.conj() + F.cmove(invF,int(m&1)) +} + +/* test x==1 ? */ +func (F *FP12) Isunity() bool { + one:=NewFP4int(1) + return (F.a.Equals(one) && F.b.iszilch() && F.c.iszilch()) +} +/* return 1 if x==y, else 0 */ +func (F *FP12) Equals(x *FP12) bool { + return (F.a.Equals(x.a) && F.b.Equals(x.b) && F.c.Equals(x.c)) +} + +/* extract a from this */ +func (F *FP12) geta() *FP4 { + return F.a +} +/* extract b */ +func (F *FP12) getb() *FP4 { + return F.b +} +/* extract c */ +func (F *FP12) getc() *FP4 { + return F.c +} +/* copy this=x */ +func (F *FP12) Copy(x *FP12) { + F.a.copy(x.a) + F.b.copy(x.b) + F.c.copy(x.c) +} +/* set this=1 */ +func (F *FP12) one() { + F.a.one() + F.b.zero() + F.c.zero() +} +/* this=conj(this) */ +func (F *FP12) conj() { + F.a.conj() + F.b.nconj() + F.c.conj() +} + +/* Granger-Scott Unitary Squaring */ +func (F *FP12) usqr() { + A:=NewFP4copy(F.a) + B:=NewFP4copy(F.c) + C:=NewFP4copy(F.b) + D:=NewFP4int(0) + + F.a.sqr() + D.copy(F.a); D.add(F.a) + F.a.add(D) + + F.a.norm(); + A.nconj() + + A.add(A) + F.a.add(A) + B.sqr() + B.times_i() + + D.copy(B); D.add(B) + B.add(D) + B.norm(); + + C.sqr() + D.copy(C); D.add(C) + C.add(D) + C.norm(); + + F.b.conj() + F.b.add(F.b) + F.c.nconj() + + F.c.add(F.c) + F.b.add(B) + F.c.add(C) + F.reduce() + +} + +/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */ +func (F *FP12) sqr() { + A:=NewFP4copy(F.a) + B:=NewFP4copy(F.b) + C:=NewFP4copy(F.c) + D:=NewFP4copy(F.a) + + A.sqr() + B.mul(F.c) + B.add(B); B.norm() + C.sqr() + D.mul(F.b) + D.add(D) + + F.c.add(F.a) + F.c.add(F.b); F.c.norm() + F.c.sqr() + + F.a.copy(A) + + A.add(B) + A.norm(); + A.add(C) + A.add(D) + A.norm(); + + A.neg() + B.times_i(); + C.times_i() + + F.a.add(B) + + F.b.copy(C); F.b.add(D) + F.c.add(A) + F.norm() +} + +/* FP12 full multiplication this=this*y */ +func (F *FP12) Mul(y *FP12) { + z0:=NewFP4copy(F.a) + z1:=NewFP4int(0) + z2:=NewFP4copy(F.b) + z3:=NewFP4int(0) + t0:=NewFP4copy(F.a) + t1:=NewFP4copy(y.a) + + z0.mul(y.a) + z2.mul(y.b) + + t0.add(F.b); t0.norm() + t1.add(y.b); t1.norm() + + z1.copy(t0); z1.mul(t1) + t0.copy(F.b); t0.add(F.c); t0.norm() + + t1.copy(y.b); t1.add(y.c); t1.norm() + z3.copy(t0); z3.mul(t1) + + t0.copy(z0); t0.neg() + t1.copy(z2); t1.neg() + + z1.add(t0) + //z1.norm(); + F.b.copy(z1); F.b.add(t1) + + z3.add(t1) + z2.add(t0) + + t0.copy(F.a); t0.add(F.c); t0.norm() + t1.copy(y.a); t1.add(y.c); t1.norm() + t0.mul(t1) + z2.add(t0) + + t0.copy(F.c); t0.mul(y.c) + t1.copy(t0); t1.neg() + + F.c.copy(z2); F.c.add(t1) + z3.add(t1) + t0.times_i() + F.b.add(t0) + z3.norm() + z3.times_i() + F.a.copy(z0); F.a.add(z3) + F.norm() +} + +/* Special case of multiplication arises from special form of ATE pairing line function */ +func (F *FP12) smul(y *FP12,twist int ) { + if twist==D_TYPE { + z0:=NewFP4copy(F.a) + z2:=NewFP4copy(F.b) + z3:=NewFP4copy(F.b) + t0:=NewFP4int(0) + t1:=NewFP4copy(y.a) + + z0.mul(y.a) + z2.pmul(y.b.real()); + F.b.add(F.a) + t1.real().add(y.b.real()) + + t1.norm(); F.b.norm() + F.b.mul(t1) + z3.add(F.c); z3.norm() + z3.pmul(y.b.real()) + + t0.copy(z0); t0.neg() + t1.copy(z2); t1.neg() + + F.b.add(t0) + //F.b.norm(); + + F.b.add(t1) + z3.add(t1); z3.norm() + z2.add(t0) + + t0.copy(F.a); t0.add(F.c); t0.norm() + t0.mul(y.a) + F.c.copy(z2); F.c.add(t0) + + z3.times_i() + F.a.copy(z0); F.a.add(z3) + } + if twist==M_TYPE { + z0:=NewFP4copy(F.a) + z1:=NewFP4int(0) + z2:=NewFP4int(0) + z3:=NewFP4int(0) + t0:=NewFP4copy(F.a) + t1:=NewFP4int(0) + + z0.mul(y.a) + t0.add(F.b) + t0.norm() + + z1.copy(t0); z1.mul(y.a) + t0.copy(F.b); t0.add(F.c) + t0.norm() + + z3.copy(t0) //z3.mul(y.c); + z3.pmul(y.c.getb()) + z3.times_i() + + t0.copy(z0); t0.neg() + + z1.add(t0) + F.b.copy(z1) + z2.copy(t0) + + t0.copy(F.a); t0.add(F.c) + t1.copy(y.a); t1.add(y.c) + + t0.norm() + t1.norm() + + t0.mul(t1) + z2.add(t0) + + t0.copy(F.c) + + t0.pmul(y.c.getb()) + t0.times_i() + + t1.copy(t0); t1.neg() + + F.c.copy(z2); F.c.add(t1) + z3.add(t1) + t0.times_i() + F.b.add(t0) + z3.norm() + z3.times_i() + F.a.copy(z0); F.a.add(z3) + } + F.norm() +} + +/* this=1/this */ +func (F *FP12) Inverse() { + f0:=NewFP4copy(F.a) + f1:=NewFP4copy(F.b) + f2:=NewFP4copy(F.a) + f3:=NewFP4int(0) + + F.norm() + f0.sqr() + f1.mul(F.c) + f1.times_i() + f0.sub(f1); f0.norm() + + f1.copy(F.c); f1.sqr() + f1.times_i() + f2.mul(F.b) + f1.sub(f2); f1.norm() + + f2.copy(F.b); f2.sqr() + f3.copy(F.a); f3.mul(F.c) + f2.sub(f3); f2.norm() + + f3.copy(F.b); f3.mul(f2) + f3.times_i() + F.a.mul(f0) + f3.add(F.a) + F.c.mul(f1) + F.c.times_i() + + f3.add(F.c); f3.norm() + f3.inverse() + F.a.copy(f0); F.a.mul(f3) + F.b.copy(f1); F.b.mul(f3) + F.c.copy(f2); F.c.mul(f3) +} + +/* this=this^p using Frobenius */ +func (F *FP12) frob(f *FP2) { + f2:=NewFP2copy(f) + f3:=NewFP2copy(f) + + f2.sqr() + f3.mul(f2) + + F.a.frob(f3); + F.b.frob(f3); + F.c.frob(f3); + + F.b.pmul(f); + F.c.pmul(f2); +} + +/* trace function */ +func (F *FP12) trace() *FP4 { + t:=NewFP4int(0) + t.copy(F.a) + t.imul(3) + t.reduce() + return t; +} + +/* convert from byte array to FP12 */ +func FP12_fromBytes(w []byte) *FP12 { + var t [int(MODBYTES)]byte + MB:=int(MODBYTES) + + for i:=0;i=1;i-- { + w.usqr() + bt:=e3.bit(i)-e.bit(i) + if bt==1 { + w.Mul(F) + } + if bt==-1 { + F.conj() + w.Mul(F) + F.conj() + } + } + w.reduce() + return w +/* + for true { + bt:=z.parity() + z.fshr(1) + if bt==1 {r.Mul(w)} + if z.iszilch() {break} + w.usqr() + } + r.reduce(); + return r; */ +} + +/* constant time powering by small integer of max length bts */ +func (F *FP12) pinpow(e int,bts int) { + var R []*FP12 + R=append(R,NewFP12int(1)) + R=append(R,NewFP12copy(F)) + + for i:=bts-1;i>=0;i-- { + b:=(e>>uint(i))&1 + R[1-b].Mul(R[b]) + R[b].usqr() + } + F.Copy(R[0]) +} + +/* Fast compressed FP4 power of unitary FP12 */ +func (F *FP12) Compow(e *BIG,r *BIG) *FP4 { + q:=NewBIGints(Modulus) + //r:=NewBIGints(CURVE_Order) + f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) + + m:=NewBIGcopy(q) + m.Mod(r) + + a:=NewBIGcopy(e) + a.Mod(m) + + b:=NewBIGcopy(e) + b.div(m) + + g1:=NewFP12copy(F); + c:=g1.trace() + + if b.iszilch() { + c=c.xtr_pow(e) + return c + } + + g2:=NewFP12copy(F) + g2.frob(f) + cp:=g2.trace() + + g1.conj() + g2.Mul(g1) + cpm1:=g2.trace() + g2.Mul(g1) + cpm2:=g2.trace() + + c=c.xtr_pow2(cp,cpm1,cpm2,a,b) + return c +} + +/* p=q0^u0.q1^u1.q2^u2.q3^u3 */ +// Bos & Costello https://eprint.iacr.org/2013/458.pdf +// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf +// Side channel attack secure + +func pow4(q []*FP12,u []*BIG) *FP12 { + var g []*FP12 + var w [NLEN*int(BASEBITS)+1]int8 + var s [NLEN*int(BASEBITS)+1]int8 + var t []*BIG + r:=NewFP12int(0) + p:=NewFP12int(0) + mt:=NewBIGint(0) + + for i:=0;i<4;i++ { + t=append(t,NewBIGcopy(u[i])) + } + + g=append(g,NewFP12copy(q[0])) // q[0] + g=append(g,NewFP12copy(g[0])); g[1].Mul(q[1]) // q[0].q[1] + g=append(g,NewFP12copy(g[0])); g[2].Mul(q[2]) // q[0].q[2] + g=append(g,NewFP12copy(g[1])); g[3].Mul(q[2]) // q[0].q[1].q[2] + g=append(g,NewFP12copy(g[0])); g[4].Mul(q[3]) // q[0].q[3] + g=append(g,NewFP12copy(g[1])); g[5].Mul(q[3]) // q[0].q[1].q[3] + g=append(g,NewFP12copy(g[2])); g[6].Mul(q[3]) // q[0].q[2].q[3] + g=append(g,NewFP12copy(g[3])); g[7].Mul(q[3]) // q[0].q[1].q[2].q[3] + +// Make it odd + pb:=1-t[0].parity() + t[0].inc(pb) +// t[0].norm(); + +// Number of bits + mt.zero() + for i:=0;i<4;i++ { + t[i].norm() + mt.or(t[i]) + } + + nb:=1+mt.nbits(); + +// Sign pivot + s[nb-1]=1 + for i:=0;i>1) + t[j].norm() + w[i]+=bt*int8(k) + k*=2 + } + } + +// Main loop + p.selector(g,int32(2*w[nb-1]+1)) + for i:=nb-2;i>=0;i-- { + p.usqr() + r.selector(g,int32(2*w[i]+s[i])) + p.Mul(r) + } + +// apply correction + r.Copy(q[0]); r.conj() + r.Mul(p) + p.cmove(r,pb) + + p.reduce() + return p; +} + +/* +func pow4(q []*FP12,u []*BIG) *FP12 { + var a [4]int8 + var g []*FP12 + var s []*FP12 + c:=NewFP12int(1) + p:=NewFP12int(0) + var w [NLEN*int(BASEBITS)+1]int8 + var t []*BIG + mt:=NewBIGint(0) + + for i:=0;i<4;i++ { + t=append(t,NewBIGcopy(u[i])) + } + + s=append(s,NewFP12int(0)) + s=append(s,NewFP12int(0)) + + g=append(g,NewFP12copy(q[0])); s[0].Copy(q[1]); s[0].conj(); g[0].Mul(s[0]) + g=append(g,NewFP12copy(g[0])) + g=append(g,NewFP12copy(g[0])) + g=append(g,NewFP12copy(g[0])) + g=append(g,NewFP12copy(q[0])); g[4].Mul(q[1]) + g=append(g,NewFP12copy(g[4])) + g=append(g,NewFP12copy(g[4])) + g=append(g,NewFP12copy(g[4])) + + s[1].Copy(q[2]); s[0].Copy(q[3]); s[0].conj(); s[1].Mul(s[0]) + s[0].Copy(s[1]); s[0].conj(); g[1].Mul(s[0]) + g[2].Mul(s[1]) + g[5].Mul(s[0]) + g[6].Mul(s[1]) + s[1].Copy(q[2]); s[1].Mul(q[3]) + s[0].Copy(s[1]); s[0].conj(); g[0].Mul(s[0]) + g[3].Mul(s[1]) + g[4].Mul(s[0]) + g[7].Mul(s[1]) + +// if power is even add 1 to power, and add q to correction + + for i:=0;i<4;i++ { + if t[i].parity()==0 { + t[i].inc(1); t[i].norm() + c.Mul(q[i]) + } + mt.add(t[i]); mt.norm() + } + c.conj() + nb:=1+mt.nbits() + +// convert exponent to signed 1-bit window + for j:=0;j=0;i-- { + m:=w[i]>>7 + j:=(w[i]^m)-m // j=abs(w[i]) + j=(j-1)/2 + s[0].Copy(g[j]); s[1].Copy(g[j]); s[1].conj() + p.usqr() + p.Mul(s[m&1]); + } + p.Mul(c) // apply correction + p.reduce() + return p; +} +*/ + diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP2.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP2.go new file mode 100644 index 00000000000..09823620ada --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP2.go @@ -0,0 +1,333 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* Finite Field arithmetic Fp^2 functions */ + +/* FP2 elements are of the form a+ib, where i is sqrt(-1) */ + +package FP256BN + + + +type FP2 struct { + a *FP + b *FP +} + +/* Constructors */ +func NewFP2int(a int) *FP2 { + F:=new(FP2) + F.a=NewFPint(a) + F.b=NewFPint(0) + return F +} + +func NewFP2copy(x *FP2) *FP2 { + F:=new(FP2) + F.a=NewFPcopy(x.a) + F.b=NewFPcopy(x.b) + return F +} + +func NewFP2fps(c *FP,d *FP) *FP2 { + F:=new(FP2) + F.a=NewFPcopy(c) + F.b=NewFPcopy(d) + return F +} + +func NewFP2bigs(c *BIG,d *BIG) *FP2 { + F:=new(FP2) + F.a=NewFPbig(c) + F.b=NewFPbig(d) + return F +} + +func NewFP2fp(c *FP) *FP2 { + F:=new(FP2) + F.a=NewFPcopy(c) + F.b=NewFPint(0) + return F +} + +func NewFP2big(c *BIG) *FP2 { + F:=new(FP2) + F.a=NewFPbig(c) + F.b=NewFPint(0) + return F +} + +/* reduce components mod Modulus */ +func (F *FP2) reduce() { + F.a.reduce() + F.b.reduce() +} + +/* normalise components of w */ +func (F *FP2) norm() { + F.a.norm() + F.b.norm() +} + +/* test this=0 ? */ +func (F *FP2) iszilch() bool { + //F.reduce() + return (F.a.iszilch() && F.b.iszilch()) +} + +func (F *FP2) cmove(g *FP2,d int) { + F.a.cmove(g.a,d) + F.b.cmove(g.b,d) +} + +/* test this=1 ? */ +func (F *FP2) isunity() bool { + one:=NewFPint(1) + return (F.a.Equals(one) && F.b.iszilch()) +} + +/* test this=x */ +func (F *FP2) Equals(x *FP2) bool { + return (F.a.Equals(x.a) && F.b.Equals(x.b)) +} + +/* extract a */ +func (F *FP2) GetA() *BIG { + return F.a.redc() +} + +/* extract b */ +func (F *FP2) GetB() *BIG { + return F.b.redc() +} + +/* copy this=x */ +func (F *FP2) copy(x *FP2) { + F.a.copy(x.a) + F.b.copy(x.b) +} + +/* set this=0 */ +func (F *FP2) zero() { + F.a.zero() + F.b.zero() +} + +/* set this=1 */ +func (F *FP2) one() { + F.a.one() + F.b.zero() +} + +/* negate this mod Modulus */ +func (F *FP2) neg() { +// F.norm() + m:=NewFPcopy(F.a) + t:= NewFPint(0) + + m.add(F.b) + m.neg() +// m.norm() + t.copy(m); t.add(F.b) + F.b.copy(m) + F.b.add(F.a) + F.a.copy(t) +} + +/* set to a-ib */ +func (F *FP2) conj() { + F.b.neg(); F.b.norm() +} + +/* this+=a */ +func (F *FP2) add(x *FP2) { + F.a.add(x.a) + F.b.add(x.b) +} + +/* this-=a */ +func (F *FP2) sub(x *FP2) { + m:=NewFP2copy(x) + m.neg() + F.add(m) +} + +/* this-=a */ +func (F *FP2) rsub(x *FP2) { + F.neg() + F.add(x) +} + +/* this*=s, where s is an FP */ +func (F *FP2) pmul(s *FP) { + F.a.mul(s) + F.b.mul(s) +} + +/* this*=i, where i is an int */ +func (F *FP2) imul(c int) { + F.a.imul(c) + F.b.imul(c) +} + +/* this*=this */ +func (F *FP2) sqr() { + w1:=NewFPcopy(F.a) + w3:=NewFPcopy(F.a) + mb:=NewFPcopy(F.b) + +// w3.mul(F.b) + w1.add(F.b) + +w3.add(F.a); +w3.norm(); +F.b.mul(w3); + + mb.neg() + F.a.add(mb) + + w1.norm() + F.a.norm() + + F.a.mul(w1) +// F.b.copy(w3); F.b.add(w3) + +// F.b.norm() +} + +/* this*=y */ +/* Now using Lazy reduction */ +func (F *FP2) mul(y *FP2) { + + if int64(F.a.XES+F.b.XES)*int64(y.a.XES+y.b.XES)>int64(FEXCESS) { + if F.a.XES>1 {F.a.reduce()} + if F.b.XES>1 {F.b.reduce()} + } + + pR:=NewDBIG() + C:=NewBIGcopy(F.a.x) + D:=NewBIGcopy(y.a.x) + p:=NewBIGints(Modulus) + + pR.ucopy(p) + + A:=mul(F.a.x,y.a.x) + B:=mul(F.b.x,y.b.x) + + C.add(F.b.x); C.norm() + D.add(y.b.x); D.norm() + + E:=mul(C,D) + FF:=NewDBIGcopy(A); FF.add(B) + B.rsub(pR) + + A.add(B); A.norm() + E.sub(FF); E.norm() + + F.a.x.copy(mod(A)); F.a.XES=3 + F.b.x.copy(mod(E)); F.b.XES=2 + +} + +/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */ +/* returns true if this is QR */ +func (F *FP2) sqrt() bool { + if F.iszilch() {return true} + w1:=NewFPcopy(F.b) + w2:=NewFPcopy(F.a) + w1.sqr(); w2.sqr(); w1.add(w2) + if w1.jacobi()!=1 { F.zero(); return false } + w1=w1.sqrt() + w2.copy(F.a); w2.add(w1); w2.norm(); w2.div2() + if w2.jacobi()!=1 { + w2.copy(F.a); w2.sub(w1); w2.norm(); w2.div2() + if w2.jacobi()!=1 { F.zero(); return false } + } + w2=w2.sqrt() + F.a.copy(w2) + w2.add(w2) + w2.inverse() + F.b.mul(w2) + return true +} + +/* output to hex string */ +func (F *FP2) toString() string { + return ("["+F.a.toString()+","+F.b.toString()+"]") +} + +/* this=1/this */ +func (F *FP2) inverse() { + F.norm() + w1:=NewFPcopy(F.a) + w2:=NewFPcopy(F.b) + + w1.sqr() + w2.sqr() + w1.add(w2) + w1.inverse() + F.a.mul(w1) + w1.neg(); w1.norm(); + F.b.mul(w1) +} + +/* this/=2 */ +func (F *FP2) div2() { + F.a.div2() + F.b.div2() +} + +/* this*=sqrt(-1) */ +func (F *FP2) times_i() { + // a.norm(); + z:=NewFPcopy(F.a) + F.a.copy(F.b); F.a.neg() + F.b.copy(z) +} + +/* w*=(1+sqrt(-1)) */ +/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */ +func (F *FP2) mul_ip() { +// F.norm() + t:=NewFP2copy(F) + z:=NewFPcopy(F.a) + F.a.copy(F.b) + F.a.neg() + F.b.copy(z) + F.add(t) +// F.norm() +} + +func (F *FP2) div_ip2() { + t:=NewFP2int(0) + F.norm() + t.a.copy(F.a); t.a.add(F.b) + t.b.copy(F.b); t.b.sub(F.a); + F.copy(t); F.norm() +} + +/* w/=(1+sqrt(-1)) */ +func (F *FP2) div_ip() { + t:=NewFP2int(0) + F.norm() + t.a.copy(F.a); t.a.add(F.b) + t.b.copy(F.b); t.b.sub(F.a); + F.copy(t); F.norm() + F.div2() +} diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP4.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP4.go new file mode 100644 index 00000000000..144490783ef --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/FP4.go @@ -0,0 +1,587 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* Finite Field arithmetic Fp^4 functions */ + +/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1)) */ + +package FP256BN + + + +type FP4 struct { + a *FP2 + b *FP2 +} + +/* Constructors */ +func NewFP4int(a int) *FP4 { + F:=new(FP4) + F.a=NewFP2int(a) + F.b=NewFP2int(0) + return F +} + +func NewFP4copy(x *FP4) *FP4 { + F:=new(FP4) + F.a=NewFP2copy(x.a) + F.b=NewFP2copy(x.b) + return F +} + +func NewFP4fp2s(c *FP2,d *FP2) *FP4 { + F:=new(FP4) + F.a=NewFP2copy(c) + F.b=NewFP2copy(d) + return F +} + +func NewFP4fp2(c *FP2) *FP4 { + F:=new(FP4) + F.a=NewFP2copy(c) + F.b=NewFP2int(0) + return F +} + +/* reduce all components of this mod Modulus */ +func (F *FP4) reduce() { + F.a.reduce() + F.b.reduce() +} + +/* normalise all components of this mod Modulus */ +func (F *FP4) norm() { + F.a.norm() + F.b.norm() +} + +/* test this==0 ? */ +func (F *FP4) iszilch() bool { + //F.reduce() + return F.a.iszilch() && F.b.iszilch() +} + +/* Conditional move */ +func (F *FP4) cmove(g *FP4,d int) { + F.a.cmove(g.a,d) + F.b.cmove(g.b,d) +} + +/* test this==1 ? */ +func (F *FP4) isunity() bool { + one:=NewFP2int(1) + return F.a.Equals(one) && F.b.iszilch() +} + +/* test is w real? That is in a+ib test b is zero */ +func (F *FP4) isreal() bool { + return F.b.iszilch() +} +/* extract real part a */ +func (F *FP4) real() *FP2 { + return F.a +} + +func (F *FP4) geta() *FP2 { + return F.a +} +/* extract imaginary part b */ +func (F *FP4) getb() *FP2 { + return F.b +} +/* test this=x? */ +func (F *FP4) Equals(x *FP4) bool { + return (F.a.Equals(x.a) && F.b.Equals(x.b)) +} + +/* copy this=x */ +func (F *FP4) copy(x *FP4) { + F.a.copy(x.a) + F.b.copy(x.b) +} +/* set this=0 */ +func (F *FP4) zero() { + F.a.zero() + F.b.zero() + } +/* set this=1 */ +func (F *FP4) one() { + F.a.one() + F.b.zero() +} + +/* set this=-this */ +func (F *FP4) neg() { + F.norm() + m:=NewFP2copy(F.a); + t:=NewFP2int(0) + m.add(F.b) + m.neg() + //m.norm() + t.copy(m); t.add(F.b) + F.b.copy(m) + F.b.add(F.a) + F.a.copy(t) + F.norm() +} + +/* this=conjugate(this) */ +func (F *FP4) conj() { + F.b.neg(); F.norm() +} + +/* this=-conjugate(this) */ +func (F *FP4) nconj() { + F.a.neg(); F.norm() +} + +/* this+=x */ +func (F *FP4) add(x *FP4) { + F.a.add(x.a) + F.b.add(x.b) +} +/* this-=x */ +func (F *FP4) sub(x *FP4) { + m:=NewFP4copy(x) + m.neg() + F.add(m) +} + +/* this-=x */ +func (F *FP4) rsub(x *FP4) { + F.neg() + F.add(x) +} + +/* this*=s where s is FP2 */ +func (F *FP4) pmul(s *FP2) { + F.a.mul(s) + F.b.mul(s) +} + +/* this*=s where s is FP2 */ +func (F *FP4) qmul(s *FP) { + F.a.pmul(s) + F.b.pmul(s) +} + +/* this*=c where c is int */ +func (F *FP4) imul(c int) { + F.a.imul(c) + F.b.imul(c) +} + +/* this*=this */ +func (F *FP4) sqr() { +// F.norm() + + t1:=NewFP2copy(F.a) + t2:=NewFP2copy(F.b) + t3:=NewFP2copy(F.a) + + t3.mul(F.b) + t1.add(F.b) + t2.mul_ip() + + t2.add(F.a) + + t1.norm(); t2.norm() + + F.a.copy(t1) + + F.a.mul(t2) + + t2.copy(t3) + t2.mul_ip() + t2.add(t3); t2.norm() + t2.neg() + F.a.add(t2) + + F.b.copy(t3) + F.b.add(t3) + + F.norm() +} + +/* this*=y */ +func (F *FP4) mul(y *FP4) { +// F.norm() + + t1:=NewFP2copy(F.a) + t2:=NewFP2copy(F.b) + t3:=NewFP2int(0) + t4:=NewFP2copy(F.b) + + t1.mul(y.a) + t2.mul(y.b) + t3.copy(y.b) + t3.add(y.a) + t4.add(F.a) + + t3.norm(); t4.norm(); + + t4.mul(t3) + + t3.copy(t1) + t3.neg() + t4.add(t3) + t4.norm() + + t3.copy(t2); + t3.neg() + F.b.copy(t4) + F.b.add(t3) + + t2.mul_ip() + F.a.copy(t2) + F.a.add(t1) + + F.norm() +} + +/* convert this to hex string */ +func (F *FP4) toString() string { + return ("["+F.a.toString()+","+F.b.toString()+"]") +} + +/* this=1/this */ +func (F *FP4) inverse() { +// F.norm() + + t1:=NewFP2copy(F.a) + t2:=NewFP2copy(F.b) + + t1.sqr() + t2.sqr() + t2.mul_ip(); t2.norm() + t1.sub(t2) + t1.inverse() + F.a.mul(t1) + t1.neg(); t1.norm() + F.b.mul(t1) +} + +/* this*=i where i = sqrt(-1+sqrt(-1)) */ +func (F *FP4) times_i() { +// F.norm() + s:=NewFP2copy(F.b) + t:=NewFP2copy(F.b) + s.times_i() + t.add(s) +// t.norm(); + F.b.copy(F.a) + F.a.copy(t) + F.norm() +} + +/* this=this^p using Frobenius */ +func (F *FP4) frob(f *FP2) { + F.a.conj() + F.b.conj() + F.b.mul(f) +} + +/* this=this^e */ +func (F *FP4) pow(e *BIG) *FP4 { + F.norm() + e.norm() + w:=NewFP4copy(F) + z:=NewBIGcopy(e) + r:=NewFP4int(1) + for true { + bt:=z.parity() + z.fshr(1) + if bt==1 {r.mul(w)} + if z.iszilch() {break} + w.sqr() + } + r.reduce() + return r +} + +/* XTR xtr_a function */ +func (F *FP4) xtr_A(w *FP4,y *FP4,z *FP4) { + r:=NewFP4copy(w) + t:=NewFP4copy(w) + //y.norm() + r.sub(y); r.norm() + r.pmul(F.a) + t.add(y); t.norm() + t.pmul(F.b) + t.times_i() + + F.copy(r) + F.add(t) + F.add(z) + + F.norm() +} + +/* XTR xtr_d function */ +func (F *FP4) xtr_D() { + w:=NewFP4copy(F) + F.sqr(); w.conj() + w.add(w); w.norm() + F.sub(w) + F.reduce() +} + +/* r=x^n using XTR method on traces of FP12s */ +func (F *FP4) xtr_pow(n *BIG) *FP4 { + a:=NewFP4int(3) + b:=NewFP4copy(F) + c:=NewFP4copy(b) + c.xtr_D() + t:=NewFP4int(0) + r:=NewFP4int(0) + + n.norm() + par:=n.parity() + v:=NewBIGcopy(n); v.fshr(1) + if (par==0) {v.dec(1); v.norm()} + + nb:=v.nbits(); + for i:=nb-1;i>=0;i-- { + if v.bit(i)!=1 { + t.copy(b) + F.conj() + c.conj() + b.xtr_A(a,F,c) + F.conj() + c.copy(t) + c.xtr_D() + a.xtr_D() + } else { + t.copy(a); t.conj() + a.copy(b) + a.xtr_D() + b.xtr_A(c,F,t) + c.xtr_D() + } + } + if par==0 { + r.copy(c) + } else {r.copy(b)} + r.reduce() + return r +} + +/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */ +func (F *FP4) xtr_pow2(ck *FP4,ckml *FP4,ckm2l *FP4,a *BIG,b *BIG) *FP4 { + a.norm(); b.norm() + e:=NewBIGcopy(a) + d:=NewBIGcopy(b) + w:=NewBIGint(0) + + cu:=NewFP4copy(ck) // can probably be passed in w/o copying + cv:=NewFP4copy(F); + cumv:=NewFP4copy(ckml) + cum2v:=NewFP4copy(ckm2l) + r:=NewFP4int(0) + t:=NewFP4int(0) + + f2:=0 + for (d.parity()==0 && e.parity()==0) { + d.fshr(1) + e.fshr(1) + f2++ + } + + for comp(d,e)!=0 { + if comp(d,e)>0 { + w.copy(e); w.imul(4); w.norm() + if comp(d,w)<=0 { + w.copy(d); d.copy(e) + e.rsub(w); e.norm() + + t.copy(cv); + t.xtr_A(cu,cumv,cum2v) + cum2v.copy(cumv); + cum2v.conj() + cumv.copy(cv) + cv.copy(cu) + cu.copy(t) + } else { + if (d.parity()==0) { + d.fshr(1) + r.copy(cum2v); r.conj() + t.copy(cumv) + t.xtr_A(cu,cv,r) + cum2v.copy(cumv) + cum2v.xtr_D() + cumv.copy(t) + cu.xtr_D() + } else { + if (e.parity()==1) { + d.sub(e); d.norm() + d.fshr(1) + t.copy(cv) + t.xtr_A(cu,cumv,cum2v) + cu.xtr_D() + cum2v.copy(cv) + cum2v.xtr_D() + cum2v.conj() + cv.copy(t) + } else { + w.copy(d) + d.copy(e); d.fshr(1) + e.copy(w) + t.copy(cumv) + t.xtr_D() + cumv.copy(cum2v); cumv.conj() + cum2v.copy(t); cum2v.conj() + t.copy(cv) + t.xtr_D() + cv.copy(cu) + cu.copy(t) + } + } + } + } + if comp(d,e)<0 { + w.copy(d); w.imul(4); w.norm() + if comp(e,w)<=0 { + e.sub(d); e.norm() + t.copy(cv) + t.xtr_A(cu,cumv,cum2v) + cum2v.copy(cumv) + cumv.copy(cu) + cu.copy(t) + } else { + if (e.parity()==0) { + w.copy(d) + d.copy(e); d.fshr(1) + e.copy(w) + t.copy(cumv) + t.xtr_D() + cumv.copy(cum2v); cumv.conj() + cum2v.copy(t); cum2v.conj() + t.copy(cv) + t.xtr_D() + cv.copy(cu) + cu.copy(t) + } else { + if (d.parity()==1) { + w.copy(e) + e.copy(d) + w.sub(d); w.norm() + d.copy(w); d.fshr(1) + t.copy(cv) + t.xtr_A(cu,cumv,cum2v) + cumv.conj() + cum2v.copy(cu) + cum2v.xtr_D() + cum2v.conj() + cu.copy(cv) + cu.xtr_D() + cv.copy(t) + } else { + d.fshr(1) + r.copy(cum2v); r.conj() + t.copy(cumv) + t.xtr_A(cu,cv,r) + cum2v.copy(cumv) + cum2v.xtr_D() + cumv.copy(t) + cu.xtr_D() + } + } + } + } + } + r.copy(cv) + r.xtr_A(cu,cumv,cum2v) + for i:=0;i=RM { + for i:=0;i>1)&1) + W:=emap(u,su) + P:=emap(v,sv) + P.Add(W) + u=P.GetX() + v=P.GetY() + D[0]=0x04 + u.ToBytes(T[:]) + for i:=0;i0 { + // s.mod2m(2*AES_S) + //} + s.ToBytes(S) + return 0 +} + + +func MPIN_EXTRACT_PIN(sha int,CID []byte,pin int,TOKEN []byte) int { + return MPIN_EXTRACT_FACTOR(sha,CID,int32(pin)%MAXPIN,PBLEN,TOKEN) +} + +/* Extract factor from TOKEN for identity CID */ +func MPIN_EXTRACT_FACTOR(sha int,CID []byte,factor int32,facbits int32,TOKEN []byte) int { + P:=ECP_fromBytes(TOKEN) + if P.Is_infinity() {return INVALID_POINT} + h:=mhashit(sha,0,CID) + R:=ECP_mapit(h) + + R=R.pinmul(factor,facbits) + P.Sub(R) + + P.ToBytes(TOKEN,false) + + return 0 +} + +/* Restore factor to TOKEN for identity CID */ +func MPIN_RESTORE_FACTOR(sha int,CID []byte,factor int32,facbits int32,TOKEN []byte) int { + P:=ECP_fromBytes(TOKEN) + if P.Is_infinity() {return INVALID_POINT} + h:=mhashit(sha,0,CID) + R:=ECP_mapit(h) + + R=R.pinmul(factor,facbits) + P.Add(R) + + P.ToBytes(TOKEN,false) + + return 0 +} + + +/* Extract PIN from TOKEN for identity CID +func MPIN_EXTRACT_PIN(sha int,CID []byte,pin int,TOKEN []byte) int { + P:=ECP_fromBytes(TOKEN) + if P.Is_infinity() {return INVALID_POINT} + h:=mhashit(sha,0,CID) + R:=ECP_mapit(h) + + R=R.pinmul(int32(pin)%MAXPIN,PBLEN) + P.Sub(R) + + P.ToBytes(TOKEN,false) + + return 0 +}*/ + +/* Implement step 2 on client side of MPin protocol */ +func MPIN_CLIENT_2(X []byte,Y []byte,SEC []byte) int { + r:=NewBIGints(CURVE_Order) + P:=ECP_fromBytes(SEC) + if P.Is_infinity() {return INVALID_POINT} + + px:=FromBytes(X) + py:=FromBytes(Y) + px.add(py) + px.Mod(r) + //px.rsub(r) + + P=G1mul(P,px) + P.neg() + P.ToBytes(SEC,false) + //G1mul(P,px).ToBytes(SEC,false) + return 0 +} + +/* Implement step 1 on client side of MPin protocol */ +func MPIN_CLIENT_1(sha int,date int,CLIENT_ID []byte,rng *amcl.RAND,X []byte,pin int,TOKEN []byte,SEC []byte,xID []byte,xCID []byte,PERMIT []byte) int { + r:=NewBIGints(CURVE_Order) + + var x *BIG + if (rng!=nil) { + x=Randomnum(r,rng) + //if AES_S>0 { + // x.mod2m(2*AES_S) + //} + x.ToBytes(X) + } else { + x=FromBytes(X) + } + + h:=mhashit(sha,0,CLIENT_ID) + P:=ECP_mapit(h) + + T:=ECP_fromBytes(TOKEN) + if T.Is_infinity() {return INVALID_POINT} + + W:=P.pinmul(int32(pin)%MAXPIN,PBLEN) + T.Add(W) + if date!=0 { + W=ECP_fromBytes(PERMIT) + if W.Is_infinity() {return INVALID_POINT} + T.Add(W) + h=mhashit(sha,int32(date),h) + W=ECP_mapit(h) + if xID!=nil { + P=G1mul(P,x) + P.ToBytes(xID,false) + W=G1mul(W,x) + P.Add(W) + } else { + P.Add(W) + P=G1mul(P,x) + } + if xCID!=nil {P.ToBytes(xCID,false)} + } else { + if xID!=nil { + P=G1mul(P,x) + P.ToBytes(xID,false) + } + } + + + T.ToBytes(SEC,false) + return 0 +} + +/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */ +func MPIN_GET_SERVER_SECRET(S []byte,SST []byte) int { + Q:=ECP2_generator(); + + s:=FromBytes(S) + Q=G2mul(Q,s) + Q.ToBytes(SST) + return 0 +} + +/* + W=x*H(G); + if RNG == NULL then X is passed in + if RNG != NULL the X is passed out + if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve +*/ +func MPIN_GET_G1_MULTIPLE(rng *amcl.RAND,typ int,X []byte,G []byte,W []byte) int { + var x *BIG + r:=NewBIGints(CURVE_Order) + if rng!=nil { + x=Randomnum(r,rng) + //if AES_S>0 { + // x.mod2m(2*AES_S) + //} + x.ToBytes(X) + } else { + x=FromBytes(X) + } + var P *ECP + if typ==0 { + P=ECP_fromBytes(G) + if P.Is_infinity() {return INVALID_POINT} + } else {P=ECP_mapit(G)} + + G1mul(P,x).ToBytes(W,false) + return 0 +} + +/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */ +/* CID is hashed externally */ +func MPIN_GET_CLIENT_SECRET(S []byte,CID []byte,CST []byte) int { + return MPIN_GET_G1_MULTIPLE(nil,1,S,CID,CST) +} + +/* Time Permit CTT=S*(date|H(CID)) where S is master secret */ +func MPIN_GET_CLIENT_PERMIT(sha,date int,S []byte,CID []byte,CTT []byte) int { + h:=mhashit(sha,int32(date),CID) + P:=ECP_mapit(h) + + s:=FromBytes(S) + G1mul(P,s).ToBytes(CTT,false) + return 0 +} + +/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */ +func MPIN_SERVER_1(sha int,date int,CID []byte,HID []byte,HTID []byte) { + h:=mhashit(sha,0,CID) + P:=ECP_mapit(h) + + P.ToBytes(HID,false); + if date!=0 { + // if HID!=nil {P.ToBytes(HID,false)} + h=mhashit(sha,int32(date),h) + R:=ECP_mapit(h) + P.Add(R) + P.ToBytes(HTID,false) + } //else {P.ToBytes(HID,false)} +} + +/* Implement step 2 of MPin protocol on server side */ +func MPIN_SERVER_2(date int,HID []byte,HTID []byte,Y []byte,SST []byte,xID []byte,xCID []byte,mSEC []byte,E []byte,F []byte) int { +// q:=NewBIGints(Modulus) + Q:=ECP2_generator(); + + sQ:=ECP2_fromBytes(SST) + if sQ.Is_infinity() {return INVALID_POINT} + + var R *ECP + if date!=0 { + R=ECP_fromBytes(xCID) + } else { + if xID==nil {return BAD_PARAMS} + R=ECP_fromBytes(xID) + } + if R.Is_infinity() {return INVALID_POINT} + + y:=FromBytes(Y) + var P *ECP + if date!=0 { + P=ECP_fromBytes(HTID) + } else { + if HID==nil {return BAD_PARAMS} + P=ECP_fromBytes(HID) + } + + if P.Is_infinity() {return INVALID_POINT} + + P=G1mul(P,y) + P.Add(R) + //P.Affine() + R=ECP_fromBytes(mSEC) + if R.Is_infinity() {return INVALID_POINT} + + var g *FP12 +// FP12 g1=new FP12(0); + + g=Ate2(Q,R,sQ,P) + g=Fexp(g) + + if !g.Isunity() { + if (HID!=nil && xID!=nil && E!=nil && F!=nil) { + g.ToBytes(E) + if date!=0 { + P=ECP_fromBytes(HID) + if P.Is_infinity() {return INVALID_POINT} + R=ECP_fromBytes(xID) + if R.Is_infinity() {return INVALID_POINT} + + P=G1mul(P,y) + P.Add(R) + //P.Affine() + } + g=Ate(Q,P) + g=Fexp(g) + g.ToBytes(F) + } + return BAD_PIN + } + + return 0 +} + +/* Pollards kangaroos used to return PIN error */ +func MPIN_KANGAROO(E []byte,F []byte) int { + ge:=FP12_fromBytes(E) + gf:=FP12_fromBytes(F) + var distance [TS]int + t:=NewFP12copy(gf) + + var table []*FP12 + var i int + s:=1 + for m:=0;m4*TRAP {break} + i=ge.geta().geta().GetA().lastbits(20)%TS; + ge.Mul(table[i]) + dm+=distance[i] + if ge.Equals(t) { + res=dm-dn + break; + } + if ge.Equals(gf) { + res=dn-dm + break + } + + } + if (steps>4*TRAP || dm-dn>=int(MAXPIN)) {res=0 } // Trap Failed - probable invalid token + return int(res) +} + +/* Functions to support M-Pin Full */ + +func MPIN_PRECOMPUTE(TOKEN []byte,CID []byte,G1 []byte,G2 []byte) int { + var P,T *ECP + var g *FP12 + + T=ECP_fromBytes(TOKEN) + if T.Is_infinity() {return INVALID_POINT} + + P=ECP_mapit(CID) + + Q:=ECP2_generator(); + + g=Ate(Q,T) + g=Fexp(g) + g.ToBytes(G1) + + g=Ate(Q,P) + g=Fexp(g) + g.ToBytes(G2) + + return 0 +} + +/* Hash the M-Pin transcript - new */ + +func MPIN_HASH_ALL(sha int,HID []byte,xID []byte,xCID []byte,SEC []byte,Y []byte,R []byte,W []byte) []byte { + tlen:=0 + var T [10*int(MODBYTES)+4]byte + + for i:=0;i0 { + // y.mod2m(2*AES_S) + //} + y.ToBytes(Y) +} + +/* One pass MPIN Client */ +func MPIN_CLIENT(sha int,date int,CLIENT_ID []byte,RNG *amcl.RAND,X []byte,pin int,TOKEN []byte,SEC []byte,xID []byte,xCID []byte,PERMIT []byte,TimeValue int,Y []byte) int { + rtn:=0 + + var pID []byte + if date == 0 { + pID = xID + } else {pID = xCID} + + rtn = MPIN_CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT) + if rtn != 0 {return rtn} + + MPIN_GET_Y(sha,TimeValue,pID,Y) + + rtn = MPIN_CLIENT_2(X,Y,SEC) + if rtn != 0 {return rtn} + + return 0 +} + +/* One pass MPIN Server */ +func MPIN_SERVER(sha int,date int,HID []byte,HTID []byte,Y []byte,SST []byte,xID []byte,xCID []byte,SEC []byte,E []byte,F []byte,CID []byte,TimeValue int) int { + rtn:=0 + + var pID []byte + if date == 0 { + pID = xID + } else {pID = xCID} + + MPIN_SERVER_1(sha,date,CID,HID,HTID) + MPIN_GET_Y(sha,TimeValue,pID,Y); + + rtn = MPIN_SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F) + if rtn != 0 {return rtn} + + return 0 +} + diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/PAIR.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/PAIR.go new file mode 100644 index 00000000000..3c05187a520 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/FP256BN/PAIR.go @@ -0,0 +1,777 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* MiotCL BN Curve Pairing functions */ + +package FP256BN + + + +/* Line function */ +func line(A *ECP2,B *ECP2,Qx *FP,Qy *FP) *FP12 { + var a *FP4 + var b *FP4 + var c *FP4 + + if (A==B) { /* Doubling */ + XX:=NewFP2copy(A.getx()) //X + YY:=NewFP2copy(A.gety()) //Y + ZZ:=NewFP2copy(A.getz()) //Z + YZ:=NewFP2copy(YY) //Y + YZ.mul(ZZ) //YZ + XX.sqr() //X^2 + YY.sqr() //Y^2 + ZZ.sqr() //Z^2 + + YZ.imul(4) + YZ.neg(); YZ.norm() //-4YZ + YZ.pmul(Qy); //-4YZ.Ys + + XX.imul(6) //6X^2 + XX.pmul(Qx); //6X^2.Xs + + sb:=3*CURVE_B_I + ZZ.imul(sb); // 3bZ^2 + if SEXTIC_TWIST == D_TYPE { + ZZ.div_ip2(); + } + if SEXTIC_TWIST == M_TYPE { + ZZ.mul_ip(); + ZZ.add(ZZ); + YZ.mul_ip(); + YZ.norm(); + } + ZZ.norm() // 3b.Z^2 + + YY.add(YY) + ZZ.sub(YY); ZZ.norm() // 3b.Z^2-2Y^2 + + a=NewFP4fp2s(YZ,ZZ); // -4YZ.Ys | 3b.Z^2-2Y^2 | 6X^2.Xs + if SEXTIC_TWIST == D_TYPE { + + b=NewFP4fp2(XX) // L(0,1) | L(0,0) | L(1,0) + c=NewFP4int(0) + } + if SEXTIC_TWIST == M_TYPE { + b=NewFP4int(0) + c=NewFP4fp2(XX); c.times_i() + } + A.dbl(); + + } else { /* Addition */ + + X1:=NewFP2copy(A.getx()) // X1 + Y1:=NewFP2copy(A.gety()) // Y1 + T1:=NewFP2copy(A.getz()) // Z1 + T2:=NewFP2copy(A.getz()) // Z1 + + T1.mul(B.gety()) // T1=Z1.Y2 + T2.mul(B.getx()) // T2=Z1.X2 + + X1.sub(T2); X1.norm() // X1=X1-Z1.X2 + Y1.sub(T1); Y1.norm() // Y1=Y1-Z1.Y2 + + T1.copy(X1) // T1=X1-Z1.X2 + X1.pmul(Qy) // X1=(X1-Z1.X2).Ys + + if SEXTIC_TWIST == M_TYPE { + X1.mul_ip() + X1.norm() + } + + T1.mul(B.gety()) // T1=(X1-Z1.X2).Y2 + + T2.copy(Y1) // T2=Y1-Z1.Y2 + T2.mul(B.getx()) // T2=(Y1-Z1.Y2).X2 + T2.sub(T1); T2.norm() // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2 + Y1.pmul(Qx); Y1.neg(); Y1.norm() // Y1=-(Y1-Z1.Y2).Xs + + a=NewFP4fp2s(X1,T2) // (X1-Z1.X2).Ys | (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2 | - (Y1-Z1.Y2).Xs + if SEXTIC_TWIST == D_TYPE { + b=NewFP4fp2(Y1) + c=NewFP4int(0) + } + if SEXTIC_TWIST == M_TYPE { + b=NewFP4int(0) + c=NewFP4fp2(Y1); c.times_i() + } + A.Add(B); + } + + + return NewFP12fp4s(a,b,c) +} + +/* Optimal R-ate pairing */ +func Ate(P1 *ECP2,Q1 *ECP) *FP12 { + f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) + x:=NewBIGints(CURVE_Bnx) + n:=NewBIGcopy(x) + K:=NewECP2() + var lv *FP12 + + if CURVE_PAIRING_TYPE == BN { + if SEXTIC_TWIST==M_TYPE { + f.inverse(); + f.norm(); + } + n.pmul(6) + if SIGN_OF_X==POSITIVEX { + n.inc(2) + } else { + n.dec(2) + } + } else {n.copy(x)} + + n.norm() + + n3:=NewBIGcopy(n); + n3.pmul(3); + n3.norm(); + + P:=NewECP2(); P.Copy(P1); P.Affine() + Q:=NewECP(); Q.Copy(Q1); Q.Affine() + + + Qx:=NewFPcopy(Q.getx()) + Qy:=NewFPcopy(Q.gety()) + + A:=NewECP2() + r:=NewFP12int(1) + + A.Copy(P) + + NP:=NewECP2() + NP.Copy(P) + NP.neg() + + nb:=n3.nbits() + + for i:=nb-2;i>=1;i-- { + r.sqr() + lv=line(A,A,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + bt:=n3.bit(i)-n.bit(i); + if bt==1 { + lv=line(A,P,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + } + if bt==-1 { + //P.neg() + lv=line(A,NP,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + //P.neg() + } + } + + if SIGN_OF_X==NEGATIVEX { + r.conj() + } + + +/* R-ate fixup required for BN curves */ + + if CURVE_PAIRING_TYPE == BN { + if SIGN_OF_X==NEGATIVEX { + //r.conj() + A.neg() + } + + K.Copy(P) + K.frob(f) + lv=line(A,K,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + K.frob(f) + K.neg() + lv=line(A,K,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + } + + return r +} + +/* Optimal R-ate double pairing e(P,Q).e(R,S) */ +func Ate2(P1 *ECP2,Q1 *ECP,R1 *ECP2,S1 *ECP) *FP12 { + f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) + x:=NewBIGints(CURVE_Bnx) + n:=NewBIGcopy(x) + K:=NewECP2() + var lv *FP12 + + if CURVE_PAIRING_TYPE == BN { + if SEXTIC_TWIST==M_TYPE { + f.inverse(); + f.norm(); + } + n.pmul(6); + if SIGN_OF_X==POSITIVEX { + n.inc(2) + } else { + n.dec(2) + } + } else {n.copy(x)} + + n.norm() + + n3:=NewBIGcopy(n); + n3.pmul(3); + n3.norm(); + + P:=NewECP2(); P.Copy(P1); P.Affine() + Q:=NewECP(); Q.Copy(Q1); Q.Affine() + R:=NewECP2(); R.Copy(R1); R.Affine() + S:=NewECP(); S.Copy(S1); S.Affine() + + + Qx:=NewFPcopy(Q.getx()) + Qy:=NewFPcopy(Q.gety()) + Sx:=NewFPcopy(S.getx()) + Sy:=NewFPcopy(S.gety()) + + A:=NewECP2() + B:=NewECP2() + r:=NewFP12int(1) + + A.Copy(P) + B.Copy(R) + NP:=NewECP2() + NP.Copy(P) + NP.neg() + NR:=NewECP2() + NR.Copy(R) + NR.neg() + + + nb:=n3.nbits() + + for i:=nb-2;i>=1;i-- { + r.sqr() + lv=line(A,A,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + lv=line(B,B,Sx,Sy) + r.smul(lv,SEXTIC_TWIST) + bt:=n3.bit(i)-n.bit(i); + if bt==1 { + lv=line(A,P,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + lv=line(B,R,Sx,Sy) + r.smul(lv,SEXTIC_TWIST) + } + if bt==-1 { + //P.neg(); + lv=line(A,NP,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + //P.neg(); + //R.neg() + lv=line(B,NR,Sx,Sy) + r.smul(lv,SEXTIC_TWIST) + //R.neg() + } + } + + if SIGN_OF_X==NEGATIVEX { + r.conj() + } + +/* R-ate fixup */ + if CURVE_PAIRING_TYPE == BN { + if SIGN_OF_X==NEGATIVEX { + // r.conj() + A.neg() + B.neg() + } + K.Copy(P) + K.frob(f) + + lv=line(A,K,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + K.frob(f) + K.neg() + lv=line(A,K,Qx,Qy) + r.smul(lv,SEXTIC_TWIST) + + K.Copy(R) + K.frob(f) + + lv=line(B,K,Sx,Sy) + r.smul(lv,SEXTIC_TWIST) + K.frob(f) + K.neg() + lv=line(B,K,Sx,Sy) + r.smul(lv,SEXTIC_TWIST) + } + + return r +} + +/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */ +func Fexp(m *FP12) *FP12 { + f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) + x:=NewBIGints(CURVE_Bnx) + r:=NewFP12copy(m) + +/* Easy part of final exp */ + lv:=NewFP12copy(r) + lv.Inverse() + r.conj() + + r.Mul(lv) + lv.Copy(r) + r.frob(f) + r.frob(f) + r.Mul(lv) +/* Hard part of final exp */ + if CURVE_PAIRING_TYPE == BN { + lv.Copy(r) + lv.frob(f) + x0:=NewFP12copy(lv) + x0.frob(f) + lv.Mul(r) + x0.Mul(lv) + x0.frob(f) + x1:=NewFP12copy(r) + x1.conj() + x4:=r.Pow(x) + if SIGN_OF_X==POSITIVEX { + x4.conj(); + } + + x3:=NewFP12copy(x4) + x3.frob(f) + + x2:=x4.Pow(x) + if SIGN_OF_X==POSITIVEX { + x2.conj(); + } + + x5:=NewFP12copy(x2); x5.conj() + lv=x2.Pow(x) + if SIGN_OF_X==POSITIVEX { + lv.conj(); + } + + x2.frob(f) + r.Copy(x2); r.conj() + + x4.Mul(r) + x2.frob(f) + + r.Copy(lv) + r.frob(f) + lv.Mul(r) + + lv.usqr() + lv.Mul(x4) + lv.Mul(x5) + r.Copy(x3) + r.Mul(x5) + r.Mul(lv) + lv.Mul(x2) + r.usqr() + r.Mul(lv) + r.usqr() + lv.Copy(r) + lv.Mul(x1) + r.Mul(x0) + lv.usqr() + r.Mul(lv) + r.reduce() + } else { + +// Ghamman & Fouotsa Method + y0:=NewFP12copy(r); y0.usqr() + y1:=y0.Pow(x) + if SIGN_OF_X==NEGATIVEX { + y1.conj(); + } + + x.fshr(1); y2:=y1.Pow(x); + if SIGN_OF_X==NEGATIVEX { + y2.conj(); + } + + x.fshl(1) + y3:=NewFP12copy(r); y3.conj() + y1.Mul(y3) + + y1.conj() + y1.Mul(y2) + + y2=y1.Pow(x) + if SIGN_OF_X==NEGATIVEX { + y2.conj(); + } + + + y3=y2.Pow(x) + if SIGN_OF_X==NEGATIVEX { + y3.conj(); + } + + y1.conj() + y3.Mul(y1) + + y1.conj(); + y1.frob(f); y1.frob(f); y1.frob(f) + y2.frob(f); y2.frob(f) + y1.Mul(y2) + + y2=y3.Pow(x) + if SIGN_OF_X==NEGATIVEX { + y2.conj(); + } + + y2.Mul(y0) + y2.Mul(r) + + y1.Mul(y2) + y2.Copy(y3); y2.frob(f) + y1.Mul(y2) + r.Copy(y1) + r.reduce() + + +/* + x0:=NewFP12copy(r) + x1:=NewFP12copy(r) + lv.Copy(r); lv.frob(f) + x3:=NewFP12copy(lv); x3.conj(); x1.Mul(x3) + lv.frob(f); lv.frob(f) + x1.Mul(lv) + + r.Copy(r.Pow(x)) //r=r.Pow(x); + x3.Copy(r); x3.conj(); x1.Mul(x3) + lv.Copy(r); lv.frob(f) + x0.Mul(lv) + lv.frob(f) + x1.Mul(lv) + lv.frob(f) + x3.Copy(lv); x3.conj(); x0.Mul(x3) + + r.Copy(r.Pow(x)) + x0.Mul(r) + lv.Copy(r); lv.frob(f); lv.frob(f) + x3.Copy(lv); x3.conj(); x0.Mul(x3) + lv.frob(f) + x1.Mul(lv) + + r.Copy(r.Pow(x)) + lv.Copy(r); lv.frob(f) + x3.Copy(lv); x3.conj(); x0.Mul(x3) + lv.frob(f) + x1.Mul(lv) + + r.Copy(r.Pow(x)) + x3.Copy(r); x3.conj(); x0.Mul(x3) + lv.Copy(r); lv.frob(f) + x1.Mul(lv) + + r.Copy(r.Pow(x)) + x1.Mul(r) + + x0.usqr() + x0.Mul(x1) + r.Copy(x0) + r.reduce() */ + } + return r +} + +/* GLV method */ +func glv(e *BIG) []*BIG { + var u []*BIG + if CURVE_PAIRING_TYPE == BN { + t:=NewBIGint(0) + q:=NewBIGints(CURVE_Order) + var v []*BIG + + for i:=0;i<2;i++ { + t.copy(NewBIGints(CURVE_W[i])) // why not just t=new BIG(ROM.CURVE_W[i]); + d:=mul(t,e) + v=append(v,NewBIGcopy(d.div(q))) + u=append(u,NewBIGint(0)) + } + u[0].copy(e) + for i:=0;i<2;i++ { + for j:=0;j<2;j++ { + t.copy(NewBIGints(CURVE_SB[j][i])) + t.copy(Modmul(v[j],t,q)) + u[i].add(q) + u[i].sub(t) + u[i].Mod(q) + } + } + } else { + q:=NewBIGints(CURVE_Order) + x:=NewBIGints(CURVE_Bnx) + x2:=smul(x,x) + u=append(u,NewBIGcopy(e)) + u[0].Mod(x2) + u=append(u,NewBIGcopy(e)) + u[1].div(x2) + u[1].rsub(q) + } + return u +} + +/* Galbraith & Scott Method */ +func gs(e *BIG) []*BIG { + var u []*BIG + if CURVE_PAIRING_TYPE == BN { + t:=NewBIGint(0) + q:=NewBIGints(CURVE_Order) + + var v []*BIG + for i:=0;i<4;i++ { + t.copy(NewBIGints(CURVE_WB[i])) + d:=mul(t,e) + v=append(v,NewBIGcopy(d.div(q))) + u=append(u,NewBIGint(0)) + } + u[0].copy(e) + for i:=0;i<4;i++ { + for j:=0;j<4;j++ { + t.copy(NewBIGints(CURVE_BB[j][i])) + t.copy(Modmul(v[j],t,q)) + u[i].add(q) + u[i].sub(t) + u[i].Mod(q) + } + } + } else { + q:=NewBIGints(CURVE_Order) + x:=NewBIGints(CURVE_Bnx) + w:=NewBIGcopy(e) + for i:=0;i<3;i++ { + u=append(u,NewBIGcopy(w)) + u[i].Mod(x) + w.div(x) + } + u=append(u,NewBIGcopy(w)) + if SIGN_OF_X==NEGATIVEX { + u[1].copy(Modneg(u[1],q)); + u[3].copy(Modneg(u[3],q)); + } + } + return u +} + +/* Multiply P by e in group G1 */ +func G1mul(P *ECP,e *BIG) *ECP { + var R *ECP + if (USE_GLV) { + //P.Affine() + R=NewECP() + R.Copy(P) + Q:=NewECP() + Q.Copy(P); Q.Affine() + q:=NewBIGints(CURVE_Order) + cru:=NewFPbig(NewBIGints(CURVE_Cru)) + t:=NewBIGint(0) + u:=glv(e) + Q.getx().mul(cru) + + np:=u[0].nbits() + t.copy(Modneg(u[0],q)) + nn:=t.nbits() + if nn>24)&0xff),byte((a>>16)&0xff),byte((a>>8)&0xff),byte(a&0xff)} + return b; +} + +func (G *GCM) precompute(H []byte) { + var b [4]byte + j:=0 + for i:=0;i>1; c=G.table[i-1][j]<<31;} + if c != 0 {G.table[i][0]^=0xE1000000} /* irreducible polynomial */ + } +} + +func (G *GCM) gf2mul() { /* gf2m mul - Z=H*X mod 2^128 */ + var P [4]uint32 + + for i:=0;i<4;i++ {P[i]=0} + j:=uint(8); m:=0 + for i:=0;i<128;i++ { + j-- + c:=uint32((G.stateX[m]>>j)&1); c=^c+1 + for k:=0;k>29 + F[1]=G.lenA[1]<<3 + F[2]=(G.lenC[0]<<3)|(G.lenC[1]&0xE0000000)>>29 + F[3]=G.lenC[1]<<3 + j:=0 + for i:=0;i>n) | ((x)<<(32-n))) +} + +func hash256_R(n uint32,x uint32) uint32 { + return ((x)>>n) +} + +func hash256_Ch(x,y,z uint32) uint32 { + return ((x&y)^(^(x)&z)) +} + +func hash256_Maj(x,y,z uint32) uint32 { + return ((x&y)^(x&z)^(y&z)) +} + +func hash256_Sig0(x uint32) uint32 { + return (hash256_S(2,x)^hash256_S(13,x)^hash256_S(22,x)) +} + +func hash256_Sig1(x uint32) uint32 { + return (hash256_S(6,x)^hash256_S(11,x)^hash256_S(25,x)) +} + +func hash256_theta0(x uint32) uint32 { + return (hash256_S(7,x)^hash256_S(18,x)^hash256_R(3,x)); +} + +func hash256_theta1(x uint32) uint32 { + return (hash256_S(17,x)^hash256_S(19,x)^hash256_R(10,x)) +} + +func (H *HASH256) transform() { /* basic transformation step */ + for j:=16;j<64;j++ { + H.w[j]=hash256_theta1(H.w[j-2])+H.w[j-7]+hash256_theta0(H.w[j-15])+H.w[j-16] + } + a:=H.h[0]; b:=H.h[1]; c:=H.h[2]; d:=H.h[3] + e:=H.h[4]; f:=H.h[5]; g:=H.h[6]; hh:=H.h[7] + for j:=0;j<64;j++ { /* 64 times - mush it up */ + t1:=hh+hash256_Sig1(e)+hash256_Ch(e,f,g)+hash256_K[j]+H.w[j] + t2:=hash256_Sig0(a)+hash256_Maj(a,b,c) + hh=g; g=f; f=e + e=d+t1 + d=c + c=b + b=a + a=t1+t2 + } + H.h[0]+=a; H.h[1]+=b; H.h[2]+=c; H.h[3]+=d + H.h[4]+=e; H.h[5]+=f; H.h[6]+=g; H.h[7]+=hh +} + +/* Initialise Hash function */ +func (H *HASH256) Init() { /* initialise */ + for i:=0;i<64;i++ {H.w[i]=0} + H.length[0]=0; H.length[1]=0 + H.h[0]=hash256_H0 + H.h[1]=hash256_H1 + H.h[2]=hash256_H2 + H.h[3]=hash256_H3 + H.h[4]=hash256_H4 + H.h[5]=hash256_H5 + H.h[6]=hash256_H6 + H.h[7]=hash256_H7 +} + +func NewHASH256() *HASH256 { + H:= new(HASH256) + H.Init() + return H +} + +/* process a single byte */ +func (H *HASH256) Process(byt byte) { /* process the next message byte */ + cnt:=(H.length[0]/32)%16; + + H.w[cnt]<<=8; + H.w[cnt]|=uint32(byt&0xFF); + H.length[0]+=8; + if H.length[0]==0 {H.length[1]++; H.length[0]=0} + if (H.length[0]%512)==0 {H.transform()} +} + +/* process an array of bytes */ +func (H *HASH256) Process_array(b []byte) { + for i:=0;i>24)&0xff)); + H.Process(byte((n>>16)&0xff)); + H.Process(byte((n>>8)&0xff)); + H.Process(byte(n&0xff)); +} + +/* Generate 32-byte Hash */ +func (H *HASH256) Hash() []byte { /* pad message and finish - supply digest */ + var digest [32]byte + len0:=H.length[0] + len1:=H.length[1] + H.Process(0x80); + for (H.length[0]%512)!=448 {H.Process(0)} + H.w[14]=len1; + H.w[15]=len0; + H.transform(); + for i:=0;i<32;i++ { /* convert to bytes */ + digest[i]=byte((H.h[i/4]>>uint(8*(3-i%4))) & 0xff); + } + H.Init() + return digest[0:32] +} + +/* test program: should produce digest */ + +//248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1 +/* +func main() { + + test := []byte("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") + sh:=NewHASH256() + + for i:=0;i>n) | ((x)<<(64-n))) +} + +func hash384_R(n uint64,x uint64) uint64 { + return ((x)>>n) +} + +func hash384_Ch(x,y,z uint64) uint64 { + return ((x&y)^(^(x)&z)) +} + +func hash384_Maj(x,y,z uint64) uint64 { + return ((x&y)^(x&z)^(y&z)) +} + +func hash384_Sig0(x uint64) uint64 { + return (hash384_S(28,x)^hash384_S(34,x)^hash384_S(39,x)) +} + +func hash384_Sig1(x uint64) uint64 { + return (hash384_S(14,x)^hash384_S(18,x)^hash384_S(41,x)) +} + +func hash384_theta0(x uint64) uint64 { + return (hash384_S(1,x)^hash384_S(8,x)^hash384_R(7,x)); +} + +func hash384_theta1(x uint64) uint64 { + return (hash384_S(19,x)^hash384_S(61,x)^hash384_R(6,x)) +} + +func (H *HASH384) transform() { /* basic transformation step */ + for j:=16;j<80;j++ { + H.w[j]=hash384_theta1(H.w[j-2])+H.w[j-7]+hash384_theta0(H.w[j-15])+H.w[j-16] + } + a:=H.h[0]; b:=H.h[1]; c:=H.h[2]; d:=H.h[3] + e:=H.h[4]; f:=H.h[5]; g:=H.h[6]; hh:=H.h[7] + for j:=0;j<80;j++ { /* 80 times - mush it up */ + t1:=hh+hash384_Sig1(e)+hash384_Ch(e,f,g)+hash384_K[j]+H.w[j] + t2:=hash384_Sig0(a)+hash384_Maj(a,b,c) + hh=g; g=f; f=e + e=d+t1 + d=c + c=b + b=a + a=t1+t2 + } + H.h[0]+=a; H.h[1]+=b; H.h[2]+=c; H.h[3]+=d + H.h[4]+=e; H.h[5]+=f; H.h[6]+=g; H.h[7]+=hh +} + +/* Initialise Hash function */ +func (H *HASH384) Init() { /* initialise */ + for i:=0;i<80;i++ {H.w[i]=0} + H.length[0]=0; H.length[1]=0 + H.h[0]=hash384_H0 + H.h[1]=hash384_H1 + H.h[2]=hash384_H2 + H.h[3]=hash384_H3 + H.h[4]=hash384_H4 + H.h[5]=hash384_H5 + H.h[6]=hash384_H6 + H.h[7]=hash384_H7 +} + +func NewHASH384() *HASH384 { + H:= new(HASH384) + H.Init() + return H +} + +/* process a single byte */ +func (H *HASH384) Process(byt byte) { /* process the next message byte */ + cnt:=(H.length[0]/64)%16; + + H.w[cnt]<<=8; + H.w[cnt]|=uint64(byt&0xFF); + H.length[0]+=8; + if H.length[0]==0 {H.length[1]++; H.length[0]=0} + if (H.length[0]%1024)==0 {H.transform()} +} + +/* process an array of bytes */ +func (H *HASH384) Process_array(b []byte) { + for i:=0;i>24)&0xff)); + H.Process(byte((n>>16)&0xff)); + H.Process(byte((n>>8)&0xff)); + H.Process(byte(n&0xff)); +} + +/* Generate 32-byte Hash */ +func (H *HASH384) Hash() []byte { /* pad message and finish - supply digest */ + var digest [48]byte + len0:=H.length[0] + len1:=H.length[1] + H.Process(0x80); + for (H.length[0]%1024)!=896 {H.Process(0)} + H.w[14]=len1; + H.w[15]=len0; + H.transform(); + for i:=0;i<48;i++ { /* convert to bytes */ + digest[i]=byte((H.h[i/8]>>uint(8*(7-i%8))) & 0xff); + } + H.Init() + return digest[0:48] +} + +/* test program: should produce digest */ + +//09330c33f71147e8 3d192fc782cd1b47 53111b173b3b05d2 2fa08086e3b0f712 fcc7c71a557e2db9 66c3e9fa91746039 +/* +func main() { + + test := []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") + sh:=NewHASH384() + + for i:=0;i>n) | ((x)<<(64-n))) +} + +func hash512_R(n uint64,x uint64) uint64 { + return ((x)>>n) +} + +func hash512_Ch(x,y,z uint64) uint64 { + return ((x&y)^(^(x)&z)) +} + +func hash512_Maj(x,y,z uint64) uint64 { + return ((x&y)^(x&z)^(y&z)) +} + +func hash512_Sig0(x uint64) uint64 { + return (hash512_S(28,x)^hash512_S(34,x)^hash512_S(39,x)) +} + +func hash512_Sig1(x uint64) uint64 { + return (hash512_S(14,x)^hash512_S(18,x)^hash512_S(41,x)) +} + +func hash512_theta0(x uint64) uint64 { + return (hash512_S(1,x)^hash512_S(8,x)^hash512_R(7,x)); +} + +func hash512_theta1(x uint64) uint64 { + return (hash512_S(19,x)^hash512_S(61,x)^hash512_R(6,x)) +} + +func (H *HASH512) transform() { /* basic transformation step */ + for j:=16;j<80;j++ { + H.w[j]=hash512_theta1(H.w[j-2])+H.w[j-7]+hash512_theta0(H.w[j-15])+H.w[j-16] + } + a:=H.h[0]; b:=H.h[1]; c:=H.h[2]; d:=H.h[3] + e:=H.h[4]; f:=H.h[5]; g:=H.h[6]; hh:=H.h[7] + for j:=0;j<80;j++ { /* 80 times - mush it up */ + t1:=hh+hash512_Sig1(e)+hash512_Ch(e,f,g)+hash512_K[j]+H.w[j] + t2:=hash512_Sig0(a)+hash512_Maj(a,b,c) + hh=g; g=f; f=e + e=d+t1 + d=c + c=b + b=a + a=t1+t2 + } + H.h[0]+=a; H.h[1]+=b; H.h[2]+=c; H.h[3]+=d + H.h[4]+=e; H.h[5]+=f; H.h[6]+=g; H.h[7]+=hh +} + +/* Initialise Hash function */ +func (H *HASH512) Init() { /* initialise */ + for i:=0;i<80;i++ {H.w[i]=0} + H.length[0]=0; H.length[1]=0 + H.h[0]=hash512_H0 + H.h[1]=hash512_H1 + H.h[2]=hash512_H2 + H.h[3]=hash512_H3 + H.h[4]=hash512_H4 + H.h[5]=hash512_H5 + H.h[6]=hash512_H6 + H.h[7]=hash512_H7 +} + +func NewHASH512() *HASH512 { + H:= new(HASH512) + H.Init() + return H +} + +/* process a single byte */ +func (H *HASH512) Process(byt byte) { /* process the next message byte */ + cnt:=(H.length[0]/64)%16; + + H.w[cnt]<<=8; + H.w[cnt]|=uint64(byt&0xFF); + H.length[0]+=8; + if H.length[0]==0 {H.length[1]++; H.length[0]=0} + if (H.length[0]%1024)==0 {H.transform()} +} + +/* process an array of bytes */ +func (H *HASH512) Process_array(b []byte) { + for i:=0;i>24)&0xff)); + H.Process(byte((n>>16)&0xff)); + H.Process(byte((n>>8)&0xff)); + H.Process(byte(n&0xff)); +} + +/* Generate 64-byte Hash */ +func (H *HASH512) Hash() []byte { /* pad message and finish - supply digest */ + var digest [64]byte + len0:=H.length[0] + len1:=H.length[1] + H.Process(0x80); + for (H.length[0]%1024)!=896 {H.Process(0)} + H.w[14]=len1; + H.w[15]=len0; + H.transform(); + for i:=0;i<64;i++ { /* convert to bytes */ + digest[i]=byte((H.h[i/8]>>uint(8*(7-i%8))) & 0xff); + } + H.Init() + return digest[0:64] +} + +/* test program: should produce digest */ + +//8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018 501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909 +/* +func main() { + + test := []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") + sh:=NewHASH512() + + for i:=0;i>31) + return (x+mask)^mask +} + +/* Montgomery stuff */ + +func redc(T uint64) int32 { + m:=(uint32(T)*NHS_ND) + return int32((uint64(m)*uint64(NHS_PRIME)+T)>>NHS_WL) +} + +func nres(x int32) int32 { + return redc(uint64(x)*NHS_R2MODP) +} + +func modmul(a int32,b int32) int32 { + return redc(uint64(a)*uint64(b)) +} + +/* NTT code */ +/* Cooley-Tukey NTT */ + +func ntt(x []int32) { + t:=NHS_DEGREE/2 + q:=NHS_PRIME + +/* Convert to Montgomery form */ + for j:=0;j1 { + k:=0; + for i:=0;i>(NHS_WL-1))&q + } +} + +/* See https://eprint.iacr.org/2016/1157.pdf */ + +func encode(key []byte,poly []int32) { + + q2:=NHS_PRIME/2 + j:=0 + for i:=0;i<256; { + kj:=key[j] + j++ + for k:=0;k<8;k++ { + b:=int32(kj&1) + poly[i]=b*q2 + poly[i+256]=b*q2 + poly[i+512]=b*q2 + poly[i+768]=b*q2 + kj>>=1 + i++ + } + } +} + +func decode(poly []int32,key []byte) { + q2:=NHS_PRIME/2 + for i:=0;i<32;i++ { + key[i]=0 + } + + j:=0 + for i:=0;i<256; { + for k:=0;k<8;k++ { + t:=nabs(poly[i]-q2)+nabs(poly[i+256]-q2)+nabs(poly[i+512]-q2)+nabs(poly[i+768]-q2) + b:=t-NHS_PRIME + b=(b>>31)&1 + key[j]=(key[j]>>1)+byte(b<<7) + i++ + } + j++ + } +} + +/* convert 32-byte seed to random polynomial */ + +func parse(seed []byte,poly []int32) { + var hash [4*NHS_DEGREE] byte + sh:=NewSHA3(SHA3_SHAKE128) + + for i:=0;i<32;i++ { + sh.Process(seed[i]) + } + sh.Shake(hash[:],4*NHS_DEGREE) + + j:=0 + for i:=0;i>8)|(b<<6))&0xff) + array[j+2]=byte((b>>2)&0xff) + array[j+3]=byte(((b>>10)|(c<<4))&0xff) + array[j+4]=byte((c>>4)&0xff) + array[j+5]=byte(((c>>12)|(d<<2))&0xff) + array[j+6]=byte(d>>6) + j+=7 + } +} + +func nhs_unpack(array []byte,poly []int32) { + j:=0 + for i:=0;i>6)|(c<<2)|((d&0xf)<<10) + poly[i+2]=(d>>4)|(e<<4)|((f&3)<<12) + poly[i+3]=(f>>2)|(g<<6) + i+=4 + } +} + +/* See https://eprint.iacr.org/2016/1157.pdf */ + +func compress(poly []int32,array []byte) { + + var col int32=0 + j:=0 + for i:=0;i>8)&0xff) + array[j+2]=byte((col>>16)&0xff) + j+=3; col=0 + } +} + +func decompress(array []byte,poly []int32) { + var col int32=0 + j:=0 + for i:=0;i>21; col<<=3 + poly[i]=round((b*NHS_PRIME),8) + i+=1 + } + } +} + +/* generate centered binomial distribution */ + +func error(rng *RAND,poly []int32) { + var r int32 + for i:=0;i>=1; n2>>=1 + } + poly[i]=(r+NHS_PRIME) + } +} + +func redc_it(p []int32) { + for i:=0;i>(NHS_WL-1))&NHS_PRIME) + } +} + +/* fully reduces modulo q */ +func poly_hard_reduce(poly []int32) { + for i:=0;i>(NHS_WL-1))&NHS_PRIME) + } +} + +/* API files */ + +func NHS_SERVER_1(rng *RAND,SB []byte,S []byte) { + var seed [32] byte + var array [1792] byte + var s [NHS_DEGREE] int32 + var e [NHS_DEGREE] int32 + var b [NHS_DEGREE] int32 + + for i:=0;i<32;i++ { + seed[i]=rng.GetByte() + } + + parse(seed[:],b[:]) + + error(rng,e[:]) + error(rng,s[:]) + + ntt(s[:]) + ntt(e[:]) + poly_mul(b[:],b[:],s[:]) + poly_add(b[:],b[:],e[:]) + poly_hard_reduce(b[:]) + + redc_it(b[:]) + nhs_pack(b[:],array[:]) + + for i:=0;i<32;i++ { + SB[i]=seed[i] + } + + for i:=0;i<1792;i++ { + SB[i+32]=array[i] + } + + poly_hard_reduce(s[:]) + nhs_pack(s[:],array[:]) + + for i:=0;i<1792;i++ { + S[i]=array[i] + } + +} + +func NHS_CLIENT(rng *RAND,SB []byte,UC []byte,KEY []byte) { + sh:=NewSHA3(SHA3_HASH256) + var seed [32] byte + var array [1792] byte + var key [32] byte + var cc [384] byte + + var sd [NHS_DEGREE] int32 + var ed [NHS_DEGREE] int32 + var u [NHS_DEGREE] int32 + var k [NHS_DEGREE] int32 + var c [NHS_DEGREE] int32 + + error(rng,sd[:]) + error(rng,ed[:]) + + ntt(sd[:]) + ntt(ed[:]) + + for i:=0;i<32;i++ { + seed[i]=SB[i] + } + + for i:=0;i<1792;i++ { + array[i]=SB[i+32] + } + + parse(seed[:],u[:]) + + poly_mul(u[:],u[:],sd[:]) + poly_add(u[:],u[:],ed[:]) + poly_hard_reduce(u[:]) + + for i:=0;i<32;i++ { + key[i]=rng.GetByte() + } + + for i:=0;i<32;i++ { + sh.Process(key[i]) + } + sh.Hash(key[:]) + + encode(key[:],k[:]) + + nhs_unpack(array[:],c[:]) + nres_it(c[:]) + + poly_mul(c[:],c[:],sd[:]) + intt(c[:]) + error(rng,ed[:]) + poly_add(c[:],c[:],ed[:]) + poly_add(c[:],c[:],k[:]) + + compress(c[:],cc[:]) + + sh.Init(SHA3_HASH256) + for i:=0;i<32;i++ { + sh.Process(key[i]) + } + sh.Hash(key[:]) + + for i:=0;i<32;i++ { + KEY[i]=key[i] + } + + redc_it(u[:]) + nhs_pack(u[:],array[:]) + + for i:=0;i<1792;i++ { + UC[i]=array[i] + } + + for i:=0;i<384;i++ { + UC[i+1792]=cc[i] + } +} + +func NHS_SERVER_2(S []byte,UC []byte,KEY []byte) { + sh:=NewSHA3(SHA3_HASH256) + + var c [NHS_DEGREE] int32 + var s [NHS_DEGREE] int32 + var k [NHS_DEGREE] int32 + + var array [1792] byte + var key [32] byte + var cc [384] byte + + for i:=0;i<1792;i++ { + array[i]=UC[i] + } + + nhs_unpack(array[:],k[:]) + nres_it(k[:]) + + for i:=0;i<384;i++ { + cc[i]=UC[i+1792] + } + + decompress(cc[:],c[:]) + + for i:=0;i<1792;i++ { + array[i]=S[i] + } + + nhs_unpack(array[:],s[:]) + + poly_mul(k[:],k[:],s[:]) + intt(k[:]) + poly_sub(k[:],c[:],k[:]) + poly_soft_reduce(k[:]) + + decode(k[:],key[:]) + + for i:=0;i<32;i++ { + sh.Process(key[i]) + } + sh.Hash(key[:]) + + for i:=0;i<32;i++ { + KEY[i]=key[i] + } +} + +/* +func main() { + + srng:=NewRAND() + var sraw [100]byte + for i:=0;i<100;i++ {sraw[i]=byte(i+1)} + srng.Seed(100,sraw[:]) + + crng:=NewRAND() + var craw [100]byte + for i:=0;i<100;i++ {craw[i]=byte(i+2)} + crng.Seed(100,craw[:]) + + var S [1792] byte + + var SB [1824] byte + NHS_SERVER_1(srng,SB[:],S[:]) + var UC [2176] byte + var KEYB [32] byte + NHS_CLIENT(crng,SB[:],UC[:],KEYB[:]) + + fmt.Printf("Bob's Key= ") + for i:=0;i<32;i++ { + fmt.Printf("%02x", KEYB[i]) + } + fmt.Printf("\n") + var KEYA [32] byte + NHS_SERVER_2(S[:],UC[:],KEYA[:]) + + fmt.Printf("Alice Key= ") + for i:=0;i<32;i++ { + fmt.Printf("%02x", KEYA[i]) + } + +} +*/ diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/RAND.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/RAND.go new file mode 100644 index 00000000000..a26cc6d3769 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/RAND.go @@ -0,0 +1,153 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* + * Cryptographic strong random number generator + * + * Unguessable seed -> SHA -> PRNG internal state -> SHA -> random numbers + * Slow - but secure + * + * See ftp://ftp.rsasecurity.com/pub/pdfs/bull-1.pdf for a justification + */ + +/* Marsaglia & Zaman Random number generator constants */ + + +package amcl + + + +const rand_NK int=21 +const rand_NJ int=6 +const rand_NV int=8 + +type RAND struct { + ira [rand_NK]uint32 /* random number... */ + rndptr int + borrow uint32 + pool_ptr int + pool [32]byte +} + +/* Terminate and clean up */ +func (R *RAND) Clean() { /* kill internal state */ + R.pool_ptr=0; R.rndptr=0; + for i:=0;i<32;i++ {R.pool[i]=0} + for i:=0;it {R.borrow=1} + R.ira[i]=pdiff + k++ + } + + return R.ira[0]; +} + +func (R *RAND) sirand(seed uint32) { + var m uint32=1; + R.borrow=0 + R.rndptr=0 + R.ira[0]^=seed; + for i:=1;i0 { + for i:=0;i=32 {R.fill_pool()} + return byte(r&0xff) +} + +/* test main program */ +/* +func main() { + var raw [100]byte + rng:=NewRAND() + + rng.Clean() + for i:=0;i<100;i++ {raw[i]=byte(i)} + + rng.Seed(100,raw[:]) + + for i:=0;i<1000;i++ { + fmt.Printf("%03d ",rng.GetByte()) + } +} +*/ diff --git a/vendor/github.com/hyperledger/fabric-amcl/amcl/SHA3.go b/vendor/github.com/hyperledger/fabric-amcl/amcl/SHA3.go new file mode 100644 index 00000000000..efcc80c8a52 --- /dev/null +++ b/vendor/github.com/hyperledger/fabric-amcl/amcl/SHA3.go @@ -0,0 +1,258 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +/* + * Implementation of the Secure Hashing Algorithm (SHA-384) + * + * Generates a 384 bit message digest. It should be impossible to come + * come up with two messages that hash to the same value ("collision free"). + * + * For use with byte-oriented messages only. + */ + +//package main + +package amcl + + + +const SHA3_HASH224 int=28 +const SHA3_HASH256 int=32 +const SHA3_HASH384 int=48 +const SHA3_HASH512 int=64 +const SHA3_SHAKE128 int=16 +const SHA3_SHAKE256 int=32 + + +const sha3_ROUNDS int=24 + +var sha3_RC = [24]uint64 { + 0x0000000000000001,0x0000000000008082,0x800000000000808A,0x8000000080008000, + 0x000000000000808B,0x0000000080000001,0x8000000080008081,0x8000000000008009, + 0x000000000000008A,0x0000000000000088,0x0000000080008009,0x000000008000000A, + 0x000000008000808B,0x800000000000008B,0x8000000000008089,0x8000000000008003, + 0x8000000000008002,0x8000000000000080,0x000000000000800A,0x800000008000000A, + 0x8000000080008081,0x8000000000008080,0x0000000080000001,0x8000000080008008} + + +type SHA3 struct { + length uint64 + rate int + len int + s [5][5] uint64 +} + +/* functions */ + +func sha3_ROTL(x uint64,n uint64) uint64 { + return (((x)<>(64-n))) +} + +func (H *SHA3) transform() { /* basic transformation step */ + + var c [5]uint64 + var d [5]uint64 + var b [5][5]uint64 + + for k:=0;k=olen || (m%H.rate)==0 { + done=true + break + } + el>>=8; + } + if done {break} + } + if done {break} + } + if m>=olen {break} + done=false + H.transform() + + } +} + +/* Generate Hash */ +func (H *SHA3) Hash(hash []byte) { /* generate a SHA3 hash of appropriate size */ + q:=H.rate-int(H.length%uint64(H.rate)) + if q==1 { + H.Process(0x86) + } else { + H.Process(0x06) + for int(H.length%uint64(H.rate)) != (H.rate-1) {H.Process(0x00)} + H.Process(0x80) + } + H.Squeeze(hash,H.len); +} + +func (H *SHA3) Shake(hash []byte,olen int) { /* generate a SHA3 hash of appropriate size */ + q:=H.rate-int(H.length%uint64(H.rate)) + if q==1 { + H.Process(0x9f) + } else { + H.Process(0x1f) + for int(H.length%uint64(H.rate))!=H.rate-1 {H.Process(0x00)} + H.Process(0x80) + } + H.Squeeze(hash,olen); +} + + + +/* test program: should produce digest */ +//916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18 +//afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185 +//98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf4535423709b02843948684e029010badcc0acd8303fc85fdad3eabf4f78cae165635f57afd28810fc2 + +/* +func main() { + + test := []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") + var digest [172]byte + + sh:=NewSHA3(SHA3_HASH256) + for i:=0;i. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* AES Encryption */ - -package core - -//import "fmt" - -const AES_ECB int = 0 -const AES_CBC int = 1 -const AES_CFB1 int = 2 -const AES_CFB2 int = 3 -const AES_CFB4 int = 5 -const AES_OFB1 int = 14 -const AES_OFB2 int = 15 -const AES_OFB4 int = 17 -const AES_OFB8 int = 21 -const AES_OFB16 int = 29 -const AES_CTR1 int = 30 -const AES_CTR2 int = 31 -const AES_CTR4 int = 33 -const AES_CTR8 int = 37 -const AES_CTR16 int = 45 - -var aes_InCo = [...]byte{0xB, 0xD, 0x9, 0xE} /* Inverse Coefficients */ - -var aes_ptab = [...]byte{ - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1} - -var aes_ltab = [...]byte{ - 0, 255, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3, - 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193, - 125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120, - 101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142, - 150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, - 102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, - 126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186, - 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87, - 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232, - 44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160, - 127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183, - 204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157, - 151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209, - 83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171, - 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165, - 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7} - -var aes_fbsub = [...]byte{ - 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, - 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, - 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, - 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, - 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, - 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, - 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, - 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, - 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, - 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, - 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, - 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, - 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, - 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, - 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, - 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22} - -var aes_rbsub = [...]byte{ - 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, - 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, - 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78, - 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37, - 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, - 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, - 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, - 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107, - 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, - 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, - 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, - 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, - 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, - 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, - 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, - 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125} - -var aes_rco = [...]byte{1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47} - -var aes_ftable = [...]uint32{ - 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0xdf2f2ff, 0xbd6b6bd6, - 0xb16f6fde, 0x54c5c591, 0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, - 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, - 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb, - 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, - 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, - 0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, - 0x34e5e5d1, 0x8f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, - 0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, - 0xf05050a, 0xb59a9a2f, 0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, - 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, - 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, - 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, - 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, - 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, - 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, - 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, - 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, - 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, - 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1, - 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, - 0xef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, - 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, - 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, - 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, - 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, - 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, - 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8, - 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, - 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, - 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, - 0x7f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, - 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, - 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, - 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, - 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c, - 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, - 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, - 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, - 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, - 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, - 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, - 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c} - -var aes_rtable = [...]uint32{ - 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, - 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, - 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25, - 0x980eea45, 0xe1c0fe5d, 0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, - 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, - 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, - 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5, - 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, - 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, - 0x578f1fe3, 0x2aab5566, 0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, - 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, - 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, - 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, - 0x69f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, - 0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, - 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, - 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, 0x83868009, 0x48ed2b32, - 0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, - 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0xfe75793, - 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, - 0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0xb0d090e, 0xadc78bf2, - 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, - 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, - 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, - 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, - 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, - 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9, - 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, - 0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, - 0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, - 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x97826cd, 0xf418596e, - 0x1b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef, - 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, - 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, - 0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, - 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, - 0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, - 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, - 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, - 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, - 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0xc25e2bc, - 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, - 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0} - -type AES struct { - Nk int - Nr int - mode int - fkey [60]uint32 - rkey [60]uint32 - f [16]byte -} - -/* Rotates 32-bit word left by 1, 2 or 3 byte */ - -func aes_ROTL8(x uint32) uint32 { - return (((x) << 8) | ((x) >> 24)) -} - -func aes_ROTL16(x uint32) uint32 { - return (((x) << 16) | ((x) >> 16)) -} - -func aes_ROTL24(x uint32) uint32 { - return (((x) << 24) | ((x) >> 8)) -} - -func aes_pack(b [4]byte) uint32 { /* pack bytes into a 32-bit Word */ - return ((uint32(b[3]) & 0xff) << 24) | ((uint32(b[2]) & 0xff) << 16) | ((uint32(b[1]) & 0xff) << 8) | (uint32(b[0]) & 0xff) -} - -func aes_unpack(a uint32) [4]byte { /* unpack bytes from a word */ - var b = [4]byte{byte(a & 0xff), byte((a >> 8) & 0xff), byte((a >> 16) & 0xff), byte((a >> 24) & 0xff)} - return b -} - -func aes_bmul(x byte, y byte) byte { /* x.y= AntiLog(Log(x) + Log(y)) */ - - ix := int(x) & 0xff - iy := int(y) & 0xff - lx := int(aes_ltab[ix]) & 0xff - ly := int(aes_ltab[iy]) & 0xff - - if x != 0 && y != 0 { - return aes_ptab[(lx+ly)%255] - } else { - return byte(0) - } -} - -func aes_SubByte(a uint32) uint32 { - b := aes_unpack(a) - b[0] = aes_fbsub[int(b[0])] - b[1] = aes_fbsub[int(b[1])] - b[2] = aes_fbsub[int(b[2])] - b[3] = aes_fbsub[int(b[3])] - return aes_pack(b) -} - -func aes_product(x uint32, y uint32) byte { /* dot product of two 4-byte arrays */ - xb := aes_unpack(x) - yb := aes_unpack(y) - - return (aes_bmul(xb[0], yb[0]) ^ aes_bmul(xb[1], yb[1]) ^ aes_bmul(xb[2], yb[2]) ^ aes_bmul(xb[3], yb[3])) -} - -func aes_InvMixCol(x uint32) uint32 { /* matrix Multiplication */ - var b [4]byte - m := aes_pack(aes_InCo) - b[3] = aes_product(m, x) - m = aes_ROTL24(m) - b[2] = aes_product(m, x) - m = aes_ROTL24(m) - b[1] = aes_product(m, x) - m = aes_ROTL24(m) - b[0] = aes_product(m, x) - var y = aes_pack(b) - return y -} - -func aes_increment(f []byte) { - for i := 0; i < 16; i++ { - f[i]++ - if f[i] != 0 { - break - } - } -} - -/* reset cipher */ -func (A *AES) Reset(m int, iv []byte) { /* reset mode, or reset iv */ - A.mode = m - for i := 0; i < 16; i++ { - A.f[i] = 0 - } - if (A.mode != AES_ECB) && (iv != nil) { - for i := 0; i < 16; i++ { - A.f[i] = iv[i] - } - } -} - -func (A *AES) Init(m int, nk int, key []byte, iv []byte) bool { - /* Key Scheduler. Create expanded encryption key */ - var CipherKey [8]uint32 - var b [4]byte - nk /= 4 - if nk != 4 && nk != 6 && nk != 8 { - return false - } - nr := 6 + nk - A.Nk = nk - A.Nr = nr - A.Reset(m, iv) - N := 4 * (nr + 1) - - j := 0 - for i := 0; i < nk; i++ { - for k := 0; k < 4; k++ { - b[k] = key[j+k] - } - CipherKey[i] = aes_pack(b) - j += 4 - } - for i := 0; i < nk; i++ { - A.fkey[i] = CipherKey[i] - } - - j = nk - for k := 0; j < N; k++ { - A.fkey[j] = A.fkey[j-nk] ^ aes_SubByte(aes_ROTL24(A.fkey[j-1])) ^ uint32(aes_rco[k]) - if nk <= 6 { - for i := 1; i < nk && (i+j) < N; i++ { - A.fkey[i+j] = A.fkey[i+j-nk] ^ A.fkey[i+j-1] - } - } else { - i := 0 - for i = 1; i < 4 && (i+j) < N; i++ { - A.fkey[i+j] = A.fkey[i+j-nk] ^ A.fkey[i+j-1] - } - if (j + 4) < N { - A.fkey[j+4] = A.fkey[j+4-nk] ^ aes_SubByte(A.fkey[j+3]) - } - for i = 5; i < nk && (i+j) < N; i++ { - A.fkey[i+j] = A.fkey[i+j-nk] ^ A.fkey[i+j-1] - } - } - j += nk - - } - - /* now for the expanded decrypt key in reverse order */ - - for j := 0; j < 4; j++ { - A.rkey[j+N-4] = A.fkey[j] - } - for i := 4; i < N-4; i += 4 { - k := N - 4 - i - for j := 0; j < 4; j++ { - A.rkey[k+j] = aes_InvMixCol(A.fkey[i+j]) - } - } - for j := N - 4; j < N; j++ { - A.rkey[j-N+4] = A.fkey[j] - } - return true -} - -func NewAES() *AES { - var A = new(AES) - return A -} - -func (A *AES) Getreg() [16]byte { - var ir [16]byte - for i := 0; i < 16; i++ { - ir[i] = A.f[i] - } - return ir -} - -/* Encrypt a single block */ -func (A *AES) ecb_encrypt(buff []byte) { - var b [4]byte - var p [4]uint32 - var q [4]uint32 - - j := 0 - for i := 0; i < 4; i++ { - for k := 0; k < 4; k++ { - b[k] = buff[j+k] - } - p[i] = aes_pack(b) - p[i] ^= A.fkey[i] - j += 4 - } - - k := 4 - - /* State alternates between p and q */ - for i := 1; i < A.Nr; i++ { - q[0] = A.fkey[k] ^ aes_ftable[int(p[0]&0xff)] ^ aes_ROTL8(aes_ftable[int((p[1]>>8)&0xff)]) ^ aes_ROTL16(aes_ftable[int((p[2]>>16)&0xff)]) ^ aes_ROTL24(aes_ftable[int((p[3]>>24)&0xff)]) - - q[1] = A.fkey[k+1] ^ aes_ftable[int(p[1]&0xff)] ^ aes_ROTL8(aes_ftable[int((p[2]>>8)&0xff)]) ^ aes_ROTL16(aes_ftable[int((p[3]>>16)&0xff)]) ^ aes_ROTL24(aes_ftable[int((p[0]>>24)&0xff)]) - - q[2] = A.fkey[k+2] ^ aes_ftable[int(p[2]&0xff)] ^ aes_ROTL8(aes_ftable[int((p[3]>>8)&0xff)]) ^ aes_ROTL16(aes_ftable[int((p[0]>>16)&0xff)]) ^ aes_ROTL24(aes_ftable[int((p[1]>>24)&0xff)]) - - q[3] = A.fkey[k+3] ^ aes_ftable[int(p[3]&0xff)] ^ aes_ROTL8(aes_ftable[int((p[0]>>8)&0xff)]) ^ aes_ROTL16(aes_ftable[int((p[1]>>16)&0xff)]) ^ aes_ROTL24(aes_ftable[int((p[2]>>24)&0xff)]) - - k += 4 - for j = 0; j < 4; j++ { - t := p[j] - p[j] = q[j] - q[j] = t - } - } - - /* Last Round */ - - q[0] = A.fkey[k] ^ uint32(aes_fbsub[int(p[0]&0xff)]) ^ aes_ROTL8(uint32(aes_fbsub[int((p[1]>>8)&0xff)])) ^ aes_ROTL16(uint32(aes_fbsub[int((p[2]>>16)&0xff)])) ^ aes_ROTL24(uint32(aes_fbsub[int((p[3]>>24)&0xff)])) - - q[1] = A.fkey[k+1] ^ uint32(aes_fbsub[int(p[1]&0xff)]) ^ aes_ROTL8(uint32(aes_fbsub[int((p[2]>>8)&0xff)])) ^ aes_ROTL16(uint32(aes_fbsub[int((p[3]>>16)&0xff)])) ^ aes_ROTL24(uint32(aes_fbsub[int((p[0]>>24)&0xff)])) - - q[2] = A.fkey[k+2] ^ uint32(aes_fbsub[int(p[2]&0xff)]) ^ aes_ROTL8(uint32(aes_fbsub[int((p[3]>>8)&0xff)])) ^ aes_ROTL16(uint32(aes_fbsub[int((p[0]>>16)&0xff)])) ^ aes_ROTL24(uint32(aes_fbsub[int((p[1]>>24)&0xff)])) - - q[3] = A.fkey[k+3] ^ uint32(aes_fbsub[int(p[3]&0xff)]) ^ aes_ROTL8(uint32(aes_fbsub[int((p[0]>>8)&0xff)])) ^ aes_ROTL16(uint32(aes_fbsub[int((p[1]>>16)&0xff)])) ^ aes_ROTL24(uint32(aes_fbsub[int((p[2]>>24)&0xff)])) - - j = 0 - for i := 0; i < 4; i++ { - b = aes_unpack(q[i]) - for k = 0; k < 4; k++ { - buff[j+k] = b[k] - } - j += 4 - } -} - -/* Decrypt a single block */ -func (A *AES) ecb_decrypt(buff []byte) { - var b [4]byte - var p [4]uint32 - var q [4]uint32 - - j := 0 - for i := 0; i < 4; i++ { - for k := 0; k < 4; k++ { - b[k] = buff[j+k] - } - p[i] = aes_pack(b) - p[i] ^= A.rkey[i] - j += 4 - } - - k := 4 - - /* State alternates between p and q */ - for i := 1; i < A.Nr; i++ { - - q[0] = A.rkey[k] ^ aes_rtable[int(p[0]&0xff)] ^ aes_ROTL8(aes_rtable[int((p[3]>>8)&0xff)]) ^ aes_ROTL16(aes_rtable[int((p[2]>>16)&0xff)]) ^ aes_ROTL24(aes_rtable[int((p[1]>>24)&0xff)]) - - q[1] = A.rkey[k+1] ^ aes_rtable[int(p[1]&0xff)] ^ aes_ROTL8(aes_rtable[int((p[0]>>8)&0xff)]) ^ aes_ROTL16(aes_rtable[int((p[3]>>16)&0xff)]) ^ aes_ROTL24(aes_rtable[int((p[2]>>24)&0xff)]) - - q[2] = A.rkey[k+2] ^ aes_rtable[int(p[2]&0xff)] ^ aes_ROTL8(aes_rtable[int((p[1]>>8)&0xff)]) ^ aes_ROTL16(aes_rtable[int((p[0]>>16)&0xff)]) ^ aes_ROTL24(aes_rtable[int((p[3]>>24)&0xff)]) - - q[3] = A.rkey[k+3] ^ aes_rtable[int(p[3]&0xff)] ^ aes_ROTL8(aes_rtable[int((p[2]>>8)&0xff)]) ^ aes_ROTL16(aes_rtable[int((p[1]>>16)&0xff)]) ^ aes_ROTL24(aes_rtable[int((p[0]>>24)&0xff)]) - - k += 4 - for j := 0; j < 4; j++ { - t := p[j] - p[j] = q[j] - q[j] = t - } - } - - /* Last Round */ - - q[0] = A.rkey[k] ^ uint32(aes_rbsub[int(p[0]&0xff)]) ^ aes_ROTL8(uint32(aes_rbsub[int((p[3]>>8)&0xff)])) ^ aes_ROTL16(uint32(aes_rbsub[int((p[2]>>16)&0xff)])) ^ aes_ROTL24(uint32(aes_rbsub[int((p[1]>>24)&0xff)])) - - q[1] = A.rkey[k+1] ^ uint32(aes_rbsub[int(p[1]&0xff)]) ^ aes_ROTL8(uint32(aes_rbsub[int((p[0]>>8)&0xff)])) ^ aes_ROTL16(uint32(aes_rbsub[int((p[3]>>16)&0xff)])) ^ aes_ROTL24(uint32(aes_rbsub[int((p[2]>>24)&0xff)])) - - q[2] = A.rkey[k+2] ^ uint32(aes_rbsub[int(p[2]&0xff)]) ^ aes_ROTL8(uint32(aes_rbsub[int((p[1]>>8)&0xff)])) ^ aes_ROTL16(uint32(aes_rbsub[int((p[0]>>16)&0xff)])) ^ aes_ROTL24(uint32(aes_rbsub[int((p[3]>>24)&0xff)])) - - q[3] = A.rkey[k+3] ^ uint32(aes_rbsub[int((p[3])&0xff)]) ^ aes_ROTL8(uint32(aes_rbsub[int((p[2]>>8)&0xff)])) ^ aes_ROTL16(uint32(aes_rbsub[int((p[1]>>16)&0xff)])) ^ aes_ROTL24(uint32(aes_rbsub[int((p[0]>>24)&0xff)])) - - j = 0 - for i := 0; i < 4; i++ { - b = aes_unpack(q[i]) - for k := 0; k < 4; k++ { - buff[j+k] = b[k] - } - j += 4 - } -} - -/* Encrypt using selected mode of operation */ -func (A *AES) Encrypt(buff []byte) uint32 { - var st [16]byte - - // Supported Modes of Operation - - var fell_off uint32 = 0 - switch A.mode { - case AES_ECB: - A.ecb_encrypt(buff) - return 0 - case AES_CBC: - for j := 0; j < 16; j++ { - buff[j] ^= A.f[j] - } - A.ecb_encrypt(buff) - for j := 0; j < 16; j++ { - A.f[j] = buff[j] - } - return 0 - - case AES_CFB1: - fallthrough - case AES_CFB2: - fallthrough - case AES_CFB4: - bytes := A.mode - AES_CFB1 + 1 - for j := 0; j < bytes; j++ { - fell_off = (fell_off << 8) | uint32(A.f[j]) - } - for j := 0; j < 16; j++ { - st[j] = A.f[j] - } - for j := bytes; j < 16; j++ { - A.f[j-bytes] = A.f[j] - } - A.ecb_encrypt(st[:]) - for j := 0; j < bytes; j++ { - buff[j] ^= st[j] - A.f[16-bytes+j] = buff[j] - } - return fell_off - - case AES_OFB1: - fallthrough - case AES_OFB2: - fallthrough - case AES_OFB4: - fallthrough - case AES_OFB8: - fallthrough - case AES_OFB16: - - bytes := A.mode - AES_OFB1 + 1 - A.ecb_encrypt(A.f[:]) - for j := 0; j < bytes; j++ { - buff[j] ^= A.f[j] - } - return 0 - - case AES_CTR1: - fallthrough - case AES_CTR2: - fallthrough - case AES_CTR4: - fallthrough - case AES_CTR8: - fallthrough - case AES_CTR16: - bytes := A.mode - AES_CTR1 + 1 - for j := 0; j < 16; j++ { - st[j] = A.f[j] - } - A.ecb_encrypt(st[:]) - for j := 0; j < bytes; j++ { - buff[j] ^= st[j] - } - aes_increment(A.f[:]) - return 0 - - default: - return 0 - } -} - -/* Decrypt using selected mode of operation */ -func (A *AES) Decrypt(buff []byte) uint32 { - - var st [16]byte - - // Supported Modes of Operation - - var fell_off uint32 = 0 - switch A.mode { - case AES_ECB: - A.ecb_decrypt(buff) - return 0 - case AES_CBC: - for j := 0; j < 16; j++ { - st[j] = A.f[j] - A.f[j] = buff[j] - } - A.ecb_decrypt(buff) - for j := 0; j < 16; j++ { - buff[j] ^= st[j] - st[j] = 0 - } - return 0 - case AES_CFB1: - fallthrough - case AES_CFB2: - fallthrough - case AES_CFB4: - bytes := A.mode - AES_CFB1 + 1 - for j := 0; j < bytes; j++ { - fell_off = (fell_off << 8) | uint32(A.f[j]) - } - for j := 0; j < 16; j++ { - st[j] = A.f[j] - } - for j := bytes; j < 16; j++ { - A.f[j-bytes] = A.f[j] - } - A.ecb_encrypt(st[:]) - for j := 0; j < bytes; j++ { - A.f[16-bytes+j] = buff[j] - buff[j] ^= st[j] - } - return fell_off - case AES_OFB1: - fallthrough - case AES_OFB2: - fallthrough - case AES_OFB4: - fallthrough - case AES_OFB8: - fallthrough - case AES_OFB16: - bytes := A.mode - AES_OFB1 + 1 - A.ecb_encrypt(A.f[:]) - for j := 0; j < bytes; j++ { - buff[j] ^= A.f[j] - } - return 0 - - case AES_CTR1: - fallthrough - case AES_CTR2: - fallthrough - case AES_CTR4: - fallthrough - case AES_CTR8: - fallthrough - case AES_CTR16: - bytes := A.mode - AES_CTR1 + 1 - for j := 0; j < 16; j++ { - st[j] = A.f[j] - } - A.ecb_encrypt(st[:]) - for j := 0; j < bytes; j++ { - buff[j] ^= st[j] - } - aes_increment(A.f[:]) - return 0 - - default: - return 0 - } -} - -/* Clean up and delete left-overs */ -func (A *AES) End() { // clean up - for i := 0; i < 4*(A.Nr+1); i++ { - A.fkey[i] = 0 - A.rkey[i] = 0 - } - for i := 0; i < 16; i++ { - A.f[i] = 0 - } -} - -/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */ -func AES_CBC_IV0_ENCRYPT(K []byte, M []byte) []byte { /* AES CBC encryption, with Null IV and key K */ - /* Input is from an octet string M, output is to an octet string C */ - /* Input is padded as necessary to make up a full final block */ - a := NewAES() - fin := false - - var buff [16]byte - var C []byte - - a.Init(AES_CBC, len(K), K, nil) - - ipt := 0 //opt:=0 - var i int - for true { - for i = 0; i < 16; i++ { - if ipt < len(M) { - buff[i] = M[ipt] - ipt++ - } else { - fin = true - break - } - } - if fin { - break - } - a.Encrypt(buff[:]) - for i = 0; i < 16; i++ { - C = append(C, buff[i]) - } - } - - /* last block, filled up to i-th index */ - - padlen := 16 - i - for j := i; j < 16; j++ { - buff[j] = byte(padlen) - } - - a.Encrypt(buff[:]) - - for i = 0; i < 16; i++ { - C = append(C, buff[i]) - } - a.End() - return C -} - -/* returns plaintext if all consistent, else returns null string */ -func AES_CBC_IV0_DECRYPT(K []byte, C []byte) []byte { /* padding is removed */ - a := NewAES() - var buff [16]byte - var MM []byte - var M []byte - - var i int - ipt := 0 - opt := 0 - - a.Init(AES_CBC, len(K), K, nil) - - if len(C) == 0 { - return nil - } - ch := C[ipt] - ipt++ - - fin := false - - for true { - for i = 0; i < 16; i++ { - buff[i] = ch - if ipt >= len(C) { - fin = true - break - } else { - ch = C[ipt] - ipt++ - } - } - a.Decrypt(buff[:]) - if fin { - break - } - for i = 0; i < 16; i++ { - MM = append(MM, buff[i]) - opt++ - } - } - - a.End() - bad := false - padlen := int(buff[15]) - if i != 15 || padlen < 1 || padlen > 16 { - bad = true - } - if padlen >= 2 && padlen <= 16 { - for i = 16 - padlen; i < 16; i++ { - if buff[i] != byte(padlen) { - bad = true - } - } - } - - if !bad { - for i = 0; i < 16-padlen; i++ { - MM = append(MM, buff[i]) - opt++ - } - } - - if bad { - return nil - } - - for i = 0; i < opt; i++ { - M = append(M, MM[i]) - } - - return M -} - -/* -func main() { - var key [32]byte - var block [16]byte - var iv [16]byte - - for i:=0;i<32;i++ {key[i]=0} - key[0]=1 - for i:=0;i<16;i++ {iv[i]=byte(i)} - for i:=0;i<16;i++ {block[i]=byte(i)} - - a:=NewAES() - - a.Init(AES_CTR16,32,key[:],iv[:]) - fmt.Printf("Plain= \n") - for i:=0;i<16;i++ {fmt.Printf("%02X ", block[i]&0xff)} - fmt.Printf("\n") - - a.Encrypt(block[:]) - - fmt.Printf("Encrypt= \n") - for i:=0;i<16;i++ {fmt.Printf("%02X ", block[i]&0xff)} - fmt.Printf("\n") - - a.Reset(AES_CTR16,iv[:]) - a.Decrypt(block[:]) - - fmt.Printf("Decrypt= \n") - for i:=0;i<16;i++ {fmt.Printf("%02X ", block[i]&0xff)} - fmt.Printf("\n") - - a.End(); -} -*/ diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ARCH.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ARCH.go deleted file mode 100644 index 4c2b9a6a170..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ARCH.go +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* core BIG number class */ - -package FP256BN - -type Chunk int64 - -const CHUNK int = 64 /* Set word size */ diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/BIG.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/BIG.go deleted file mode 100644 index a330bb37332..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/BIG.go +++ /dev/null @@ -1,960 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* core BIG number class */ - -package FP256BN - -import "strconv" -import "github.com/hyperledger/fabric-amcl/core" - - - -//const MODBYTES uint = @NB@ -//const BASEBITS uint = @BASE@ - -//const NLEN int = int((1 + ((8*MODBYTES - 1) / BASEBITS))) -//const DNLEN int = 2 * NLEN -//const BMASK Chunk = ((Chunk(1) << BASEBITS) - 1) -//const HBITS uint = (BASEBITS / 2) -//const HMASK Chunk = ((Chunk(1) << HBITS) - 1) -//const NEXCESS int = (1 << (uint(CHUNK) - BASEBITS - 1)) - -//const BIGBITS int = int(MODBYTES * 8) - -type BIG struct { - w [NLEN]Chunk -} - -type DBIG struct { - w [2 * NLEN]Chunk -} - -/***************** 64-bit specific code ****************/ - -/* First the 32/64-bit dependent BIG code */ -/* Note that because of the lack of a 128-bit integer, 32 and 64-bit code needs to be done differently */ - -/* return a*b as DBIG */ -func mul(a *BIG, b *BIG) *DBIG { - c := NewDBIG() - carry := Chunk(0) - - for i := 0; i < NLEN; i++ { - carry = 0 - for j := 0; j < NLEN; j++ { - carry, c.w[i+j] = muladd(a.w[i], b.w[j], carry, c.w[i+j]) - } - c.w[NLEN+i] = carry - } - - return c -} - -/* return a^2 as DBIG */ -func sqr(a *BIG) *DBIG { - c := NewDBIG() - carry := Chunk(0) - - for i := 0; i < NLEN; i++ { - carry = 0 - for j := i + 1; j < NLEN; j++ { - carry, c.w[i+j] = muladd(2*a.w[i], a.w[j], carry, c.w[i+j]) - } - c.w[NLEN+i] = carry - } - - for i := 0; i < NLEN; i++ { - top, bot := muladd(a.w[i], a.w[i], 0, c.w[2*i]) - c.w[2*i] = bot - c.w[2*i+1] += top - } - c.norm() - return c -} - -func monty(md *BIG, mc Chunk, d *DBIG) *BIG { - carry := Chunk(0) - m := Chunk(0) - for i := 0; i < NLEN; i++ { - if mc == -1 { - m = (-d.w[i]) & BMASK - } else { - if mc == 1 { - m = d.w[i] - } else { - m = (mc * d.w[i]) & BMASK - } - } - - carry = 0 - for j := 0; j < NLEN; j++ { - carry, d.w[i+j] = muladd(m, md.w[j], carry, d.w[i+j]) - } - d.w[NLEN+i] += carry - } - - b := NewBIG() - for i := 0; i < NLEN; i++ { - b.w[i] = d.w[NLEN+i] - } - b.norm() - return b -} - -/* set this[i]+=x*y+c, and return high part */ -func muladd(a Chunk, b Chunk, c Chunk, r Chunk) (Chunk, Chunk) { - x0 := a & HMASK - x1 := (a >> HBITS) - y0 := b & HMASK - y1 := (b >> HBITS) - bot := x0 * y0 - top := x1 * y1 - mid := x0*y1 + x1*y0 - x0 = mid & HMASK - x1 = (mid >> HBITS) - bot += x0 << HBITS - bot += c - bot += r - top += x1 - carry := bot >> BASEBITS - bot &= BMASK - top += carry - return top, bot -} - -/************************************************************/ - -func (r *BIG) get(i int) Chunk { - return r.w[i] -} - -func (r *BIG) set(i int, x Chunk) { - r.w[i] = x -} - -func (r *BIG) xortop(x Chunk) { - r.w[NLEN-1] ^= x -} - -/* normalise BIG - force all digits < 2^BASEBITS */ -func (r *BIG) norm() Chunk { - carry := Chunk(0) - for i := 0; i < NLEN-1; i++ { - d := r.w[i] + carry - r.w[i] = d & BMASK - carry = d >> BASEBITS - } - r.w[NLEN-1] = (r.w[NLEN-1] + carry) - return (r.w[NLEN-1] >> ((8 * MODBYTES) % BASEBITS)) -} - -/* Shift right by less than a word */ -func (r *BIG) fshr(k uint) int { - w := r.w[0] & ((Chunk(1) << k) - 1) /* shifted out part */ - for i := 0; i < NLEN-1; i++ { - r.w[i] = (r.w[i] >> k) | ((r.w[i+1] << (BASEBITS - k)) & BMASK) - } - r.w[NLEN-1] = r.w[NLEN-1] >> k - return int(w) -} - -/* Shift right by less than a word */ -func (r *BIG) fshl(k uint) int { - r.w[NLEN-1] = (r.w[NLEN-1] << k) | (r.w[NLEN-2] >> (BASEBITS - k)) - for i := NLEN - 2; i > 0; i-- { - r.w[i] = ((r.w[i] << k) & BMASK) | (r.w[i-1] >> (BASEBITS - k)) - } - r.w[0] = (r.w[0] << k) & BMASK - return int(r.w[NLEN-1] >> ((8 * MODBYTES) % BASEBITS)) /* return excess - only used in ff.c */ -} - -func NewBIG() *BIG { - b := new(BIG) - for i := 0; i < NLEN; i++ { - b.w[i] = 0 - } - return b -} - -func NewBIGints(x [NLEN]Chunk) *BIG { - b := new(BIG) - for i := 0; i < NLEN; i++ { - b.w[i] = x[i] - } - return b -} - -func NewBIGint(x int) *BIG { - b := new(BIG) - b.w[0] = Chunk(x) - for i := 1; i < NLEN; i++ { - b.w[i] = 0 - } - return b -} - -func NewBIGcopy(x *BIG) *BIG { - b := new(BIG) - for i := 0; i < NLEN; i++ { - b.w[i] = x.w[i] - } - return b -} - -func NewBIGdcopy(x *DBIG) *BIG { - b := new(BIG) - for i := 0; i < NLEN; i++ { - b.w[i] = x.w[i] - } - return b -} - -/* test for zero */ -func (r *BIG) iszilch() bool { - d:=Chunk(0) - for i := 0; i < NLEN; i++ { - d|=r.w[i] - } - return (1 & ((d-1)>>BASEBITS)) != 0 -} - -/* set to zero */ -func (r *BIG) zero() { - for i := 0; i < NLEN; i++ { - r.w[i] = 0 - } -} - -/* Test for equal to one */ -func (r *BIG) isunity() bool { - d:=Chunk(0) - for i := 1; i < NLEN; i++ { - d|=r.w[i] - } - return (1 & ((d-1)>>BASEBITS) & (((r.w[0]^1)-1)>>BASEBITS)) != 0 -} - -/* set to one */ -func (r *BIG) one() { - r.w[0] = 1 - for i := 1; i < NLEN; i++ { - r.w[i] = 0 - } -} - -/* Copy from another BIG */ -func (r *BIG) copy(x *BIG) { - for i := 0; i < NLEN; i++ { - r.w[i] = x.w[i] - } -} - -/* Copy from another DBIG */ -func (r *BIG) dcopy(x *DBIG) { - for i := 0; i < NLEN; i++ { - r.w[i] = x.w[i] - } -} - -/* Conditional swap of two bigs depending on d using XOR - no branches */ -func (r *BIG) cswap(b *BIG, d int) { - c := Chunk(d) - c = ^(c - 1) - - for i := 0; i < NLEN; i++ { - t := c & (r.w[i] ^ b.w[i]) - r.w[i] ^= t - b.w[i] ^= t - } -} - -func (r *BIG) cmove(g *BIG, d int) { - b := Chunk(-d) - - for i := 0; i < NLEN; i++ { - r.w[i] ^= (r.w[i] ^ g.w[i]) & b - } -} - -/* general shift right */ -func (r *BIG) shr(k uint) { - n := (k % BASEBITS) - m := int(k / BASEBITS) - for i := 0; i < NLEN-m-1; i++ { - r.w[i] = (r.w[m+i] >> n) | ((r.w[m+i+1] << (BASEBITS - n)) & BMASK) - } - r.w[NLEN-m-1] = r.w[NLEN-1] >> n - for i := NLEN - m; i < NLEN; i++ { - r.w[i] = 0 - } -} - -/* general shift left */ -func (r *BIG) shl(k uint) { - n := k % BASEBITS - m := int(k / BASEBITS) - - r.w[NLEN-1] = (r.w[NLEN-1-m] << n) - if NLEN >= m+2 { - r.w[NLEN-1] |= (r.w[NLEN-m-2] >> (BASEBITS - n)) - } - for i := NLEN - 2; i > m; i-- { - r.w[i] = ((r.w[i-m] << n) & BMASK) | (r.w[i-m-1] >> (BASEBITS - n)) - } - r.w[m] = (r.w[0] << n) & BMASK - for i := 0; i < m; i++ { - r.w[i] = 0 - } -} - -/* return number of bits */ -func (r *BIG) nbits() int { - t := NewBIGcopy(r) - k := NLEN - 1 - t.norm() - for k >= 0 && t.w[k] == 0 { - k-- - } - if k < 0 { - return 0 - } - bts := int(BASEBITS) * k - c := t.w[k] - for c != 0 { - c /= 2 - bts++ - } - return bts -} - -/* Convert to Hex String */ -func (r *BIG) ToString() string { - s := "" - len := r.nbits() - - if len%4 == 0 { - len /= 4 - } else { - len /= 4 - len++ - - } - MB := int(MODBYTES * 2) - if len < MB { - len = MB - } - - for i := len - 1; i >= 0; i-- { - b := NewBIGcopy(r) - - b.shr(uint(i * 4)) - s += strconv.FormatInt(int64(b.w[0]&15), 16) - } - return s -} - -func (r *BIG) add(x *BIG) { - for i := 0; i < NLEN; i++ { - r.w[i] = r.w[i] + x.w[i] - } -} - -func (r *BIG) or(x *BIG) { - for i := 0; i < NLEN; i++ { - r.w[i] = r.w[i] | x.w[i] - } -} - -/* return this+x */ -func (r *BIG) Plus(x *BIG) *BIG { - s := new(BIG) - for i := 0; i < NLEN; i++ { - s.w[i] = r.w[i] + x.w[i] - } - return s -} - -/* this+=x, where x is int */ -func (r *BIG) inc(x int) { - r.norm() - r.w[0] += Chunk(x) -} - -/* this*=c and catch overflow in DBIG */ -func (r *BIG) pxmul(c int) *DBIG { - m := NewDBIG() - carry := Chunk(0) - for j := 0; j < NLEN; j++ { - carry, m.w[j] = muladd(r.w[j], Chunk(c), carry, m.w[j]) - } - m.w[NLEN] = carry - return m -} - -/* return this-x */ -func (r *BIG) Minus(x *BIG) *BIG { - d := new(BIG) - for i := 0; i < NLEN; i++ { - d.w[i] = r.w[i] - x.w[i] - } - return d -} - -/* this-=x */ -func (r *BIG) sub(x *BIG) { - for i := 0; i < NLEN; i++ { - r.w[i] = r.w[i] - x.w[i] - } -} - -/* reverse subtract this=x-this */ -func (r *BIG) rsub(x *BIG) { - for i := 0; i < NLEN; i++ { - r.w[i] = x.w[i] - r.w[i] - } -} - -/* this-=x, where x is int */ -func (r *BIG) dec(x int) { - r.norm() - r.w[0] -= Chunk(x) -} - -/* this*=x, where x is small intNEXCESS */ -func (r *BIG) pmul(c int) Chunk { - carry := Chunk(0) - // r.norm(); - for i := 0; i < NLEN; i++ { - ak := r.w[i] - r.w[i] = 0 - carry, r.w[i] = muladd(ak, Chunk(c), carry, r.w[i]) - } - return carry -} - -/* convert this BIG to byte array */ -func (r *BIG) tobytearray(b []byte, n int) { - //r.norm(); - c := NewBIGcopy(r) - c.norm() - - for i := int(MODBYTES) - 1; i >= 0; i-- { - b[i+n] = byte(c.w[0]) - c.fshr(8) - } -} - -/* convert from byte array to BIG */ -func frombytearray(b []byte, n int) *BIG { - m := NewBIG() - for i := 0; i < int(MODBYTES); i++ { - m.fshl(8) - m.w[0] += Chunk(int(b[i+n] & 0xff)) - } - return m -} - -func (r *BIG) ToBytes(b []byte) { - r.tobytearray(b, 0) -} - -func FromBytes(b []byte) *BIG { - return frombytearray(b, 0) -} - -/* divide by 3 */ -func (r *BIG) div3() int { - carry := Chunk(0) - r.norm() - base := (Chunk(1) << BASEBITS) - for i := NLEN - 1; i >= 0; i-- { - ak := (carry*base + r.w[i]) - r.w[i] = ak / 3 - carry = ak % 3 - } - return int(carry) -} - -/* return a*b where result fits in a BIG */ -func smul(a *BIG, b *BIG) *BIG { - carry := Chunk(0) - c := NewBIG() - for i := 0; i < NLEN; i++ { - carry = 0 - for j := 0; j < NLEN; j++ { - if i+j < NLEN { - carry, c.w[i+j] = muladd(a.w[i], b.w[j], carry, c.w[i+j]) - } - } - } - return c -} - -/* Compare a and b, return 0 if a==b, -1 if ab. Inputs must be normalised */ -func Comp(a *BIG, b *BIG) int { - gt:=Chunk(0) - eq:=Chunk(1) - for i := NLEN - 1; i >= 0; i-- { - gt |= ((b.w[i]-a.w[i]) >> BASEBITS) & eq - eq &= ((b.w[i]^a.w[i])-1) >> BASEBITS - } - return int(gt+gt+eq-1) -} - -/* return parity */ -func (r *BIG) parity() int { - return int(r.w[0] % 2) -} - -/* return n-th bit */ -func (r *BIG) bit(n int) int { - if (r.w[n/int(BASEBITS)] & (Chunk(1) << (uint(n) % BASEBITS))) > 0 { - return 1 - } - return 0 -} - -/* return n last bits */ -func (r *BIG) lastbits(n int) int { - msk := (1 << uint(n)) - 1 - r.norm() - return (int(r.w[0])) & msk -} - -/* set x = x mod 2^m */ -func (r *BIG) mod2m(m uint) { - wd := int(m / BASEBITS) - bt := m % BASEBITS - msk := (Chunk(1) << bt) - 1 - r.w[wd] &= msk - for i := wd + 1; i < NLEN; i++ { - r.w[i] = 0 - } -} - -/* a=1/a mod 2^256. This is very fast! */ -func (r *BIG) invmod2m() { - U := NewBIG() - b := NewBIG() - c := NewBIG() - - U.inc(invmod256(r.lastbits(8))) - - for i := 8; i < BIGBITS; i <<= 1 { - U.norm() - ui := uint(i) - b.copy(r) - b.mod2m(ui) - t1 := smul(U, b) - t1.shr(ui) - c.copy(r) - c.shr(ui) - c.mod2m(ui) - - t2 := smul(U, c) - t2.mod2m(ui) - t1.add(t2) - t1.norm() - b = smul(t1, U) - t1.copy(b) - t1.mod2m(ui) - - t2.one() - t2.shl(ui) - t1.rsub(t2) - t1.norm() - t1.shl(ui) - U.add(t1) - } - U.mod2m(8 * MODBYTES) - r.copy(U) - r.norm() -} - -/* reduce this mod m */ -func (r *BIG) Mod(m1 *BIG) { - m := NewBIGcopy(m1) - sr := NewBIG() - r.norm() - if Comp(r, m) < 0 { - return - } - - m.fshl(1) - k := 1 - - for Comp(r, m) >= 0 { - m.fshl(1) - k++ - } - - for k > 0 { - m.fshr(1) - sr.copy(r) - sr.sub(m) - sr.norm() - r.cmove(sr, int(1-((sr.w[NLEN-1]>>uint(CHUNK-1))&1))) - - k-- - } -} - -/* divide this by m */ -func (r *BIG) div(m1 *BIG) { - m := NewBIGcopy(m1) - var d int - k := 0 - r.norm() - sr := NewBIG() - e := NewBIGint(1) - b := NewBIGcopy(r) - r.zero() - - for Comp(b, m) >= 0 { - e.fshl(1) - m.fshl(1) - k++ - } - - for k > 0 { - m.fshr(1) - e.fshr(1) - - sr.copy(b) - sr.sub(m) - sr.norm() - d = int(1 - ((sr.w[NLEN-1] >> uint(CHUNK-1)) & 1)) - b.cmove(sr, d) - sr.copy(r) - sr.add(e) - sr.norm() - r.cmove(sr, d) - - k-- - } -} - -/* get 8*MODBYTES size random number */ -func random(rng *core.RAND) *BIG { - m := NewBIG() - var j int = 0 - var r byte = 0 - /* generate random BIG */ - for i := 0; i < 8*int(MODBYTES); i++ { - if j == 0 { - r = rng.GetByte() - } else { - r >>= 1 - } - - b := Chunk(int(r & 1)) - m.shl(1) - m.w[0] += b - j++ - j &= 7 - } - return m -} - -/* Create random BIG in portable way, one bit at a time */ -func Randomnum(q *BIG, rng *core.RAND) *BIG { - d := NewDBIG() - var j int = 0 - var r byte = 0 - for i := 0; i < 2*q.nbits(); i++ { - if j == 0 { - r = rng.GetByte() - } else { - r >>= 1 - } - - b := Chunk(int(r & 1)) - d.shl(1) - d.w[0] += b - j++ - j &= 7 - } - m := d.mod(q) - return m -} - -func Randtrunc(q *BIG, trunc int, rng *core.RAND) *BIG { - m := Randomnum(q, rng) - if q.nbits() > trunc { - m.mod2m(uint(trunc)) - } - return m -} - -/* return a*b mod m */ -func Modmul(a1, b1, m *BIG) *BIG { - a := NewBIGcopy(a1) - b := NewBIGcopy(b1) - a.Mod(m) - b.Mod(m) - d := mul(a, b) - return d.mod(m) -} - -/* return a^2 mod m */ -func Modsqr(a1, m *BIG) *BIG { - a := NewBIGcopy(a1) - a.Mod(m) - d := sqr(a) - return d.mod(m) -} - -/* return -a mod m */ -func Modneg(a1, m *BIG) *BIG { - a := NewBIGcopy(a1) - a.Mod(m) - a.rsub(m) - a.Mod(m) - return a -} - -/* return a+b mod m */ -func Modadd(a1, b1, m *BIG) *BIG { - a := NewBIGcopy(a1) - b := NewBIGcopy(b1) - a.Mod(m) - b.Mod(m) - a.add(b); a.norm() - a.Mod(m) - return a -} - -/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */ -func (r *BIG) Jacobi(p *BIG) int { - m := 0 - t := NewBIGint(0) - x := NewBIGint(0) - n := NewBIGint(0) - zilch := NewBIGint(0) - one := NewBIGint(1) - if p.parity() == 0 || Comp(r, zilch) == 0 || Comp(p, one) <= 0 { - return 0 - } - r.norm() - x.copy(r) - n.copy(p) - x.Mod(p) - - for Comp(n, one) > 0 { - if Comp(x, zilch) == 0 { - return 0 - } - n8 := n.lastbits(3) - k := 0 - for x.parity() == 0 { - k++ - x.shr(1) - } - if k%2 == 1 { - m += (n8*n8 - 1) / 8 - } - m += (n8 - 1) * (x.lastbits(2) - 1) / 4 - t.copy(n) - t.Mod(x) - n.copy(x) - x.copy(t) - m %= 2 - - } - if m == 0 { - return 1 - } - return -1 -} - -/* this=1/this mod p. Binary method */ -func (r *BIG) Invmodp(p *BIG) { - r.Mod(p) - if r.iszilch() { - return - } - - u := NewBIGcopy(r) - - v := NewBIGcopy(p) - x1 := NewBIGint(1) - x2 := NewBIGint(0) - t := NewBIGint(0) - one := NewBIGint(1) - for Comp(u, one) != 0 && Comp(v, one) != 0 { - for u.parity() == 0 { - u.fshr(1) - if x1.parity() != 0 { - x1.add(p) - x1.norm() - } - x1.fshr(1) - } - for v.parity() == 0 { - v.fshr(1) - if x2.parity() != 0 { - x2.add(p) - x2.norm() - } - x2.fshr(1) - } - if Comp(u, v) >= 0 { - u.sub(v) - u.norm() - if Comp(x1, x2) >= 0 { - x1.sub(x2) - } else { - t.copy(p) - t.sub(x2) - x1.add(t) - } - x1.norm() - } else { - v.sub(u) - v.norm() - if Comp(x2, x1) >= 0 { - x2.sub(x1) - } else { - t.copy(p) - t.sub(x1) - x2.add(t) - } - x2.norm() - } - } - if Comp(u, one) == 0 { - r.copy(x1) - } else { - r.copy(x2) - } -} - -/* return this^e mod m */ -func (r *BIG) Powmod(e1 *BIG, m *BIG) *BIG { - e := NewBIGcopy(e1) - r.norm() - e.norm() - a := NewBIGint(1) - z := NewBIGcopy(e) - s := NewBIGcopy(r) - for true { - bt := z.parity() - z.fshr(1) - if bt == 1 { - a = Modmul(a, s, m) - } - if z.iszilch() { - break - } - s = Modsqr(s, m) - } - return a -} - -/* Arazi and Qi inversion mod 256 */ -func invmod256(a int) int { - var t1 int = 0 - c := (a >> 1) & 1 - t1 += c - t1 &= 1 - t1 = 2 - t1 - t1 <<= 1 - U := t1 + 1 - - // i=2 - b := a & 3 - t1 = U * b - t1 >>= 2 - c = (a >> 2) & 3 - t2 := (U * c) & 3 - t1 += t2 - t1 *= U - t1 &= 3 - t1 = 4 - t1 - t1 <<= 2 - U += t1 - - // i=4 - b = a & 15 - t1 = U * b - t1 >>= 4 - c = (a >> 4) & 15 - t2 = (U * c) & 15 - t1 += t2 - t1 *= U - t1 &= 15 - t1 = 16 - t1 - t1 <<= 4 - U += t1 - - return U -} - -func logb2(w uint32) uint { - v := w - v |= (v >> 1) - v |= (v >> 2) - v |= (v >> 4) - v |= (v >> 8) - v |= (v >> 16) - - v = v - ((v >> 1) & 0x55555555) - v = (v & 0x33333333) + ((v >> 2) & 0x33333333) - r := uint((((v + (v >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24) - return (r) -} - -// Optimized combined shift, subtract and norm -func ssn(r *BIG, a *BIG, m *BIG) int { - n := NLEN - 1 - m.w[0] = (m.w[0] >> 1) | ((m.w[1] << (BASEBITS - 1)) & BMASK) - r.w[0] = a.w[0] - m.w[0] - carry := r.w[0] >> BASEBITS - r.w[0] &= BMASK - for i := 1; i < n; i++ { - m.w[i] = (m.w[i] >> 1) | ((m.w[i+1] << (BASEBITS - 1)) & BMASK) - r.w[i] = a.w[i] - m.w[i] + carry - carry = r.w[i] >> BASEBITS - r.w[i] &= BMASK - } - m.w[n] >>= 1 - r.w[n] = a.w[n] - m.w[n] + carry - return int((r.w[n] >> uint(CHUNK-1)) & 1) -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/BLS.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/BLS.go deleted file mode 100644 index b4b29133bf0..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/BLS.go +++ /dev/null @@ -1,157 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* Boneh-Lynn-Shacham API Functions */ - -/* Loosely (for now) following https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-00 */ - -// Minimal-signature-size variant - -package FP256BN - -import "github.com/hyperledger/fabric-amcl/core" - - - -const BFS int = int(MODBYTES) -const BGS int = int(MODBYTES) -const BLS_OK int = 0 -const BLS_FAIL int = -1 - -var G2_TAB []*FP4 - -func ceil(a int,b int) int { - return (((a)-1)/(b)+1) -} - -/* output u \in F_p */ -func hash_to_base(hash int,hlen int ,DST []byte,M []byte,ctr int) *BIG { - q := NewBIGints(Modulus) - L := ceil(q.nbits()+AESKEY*8,8) - INFO := []byte("H2C") - INFO = append(INFO,byte(ctr)) - - PRK:=core.HKDF_Extract(hash,hlen,DST,M) - OKM:=core.HKDF_Expand(hash,hlen,L,PRK,INFO) - - dx:= DBIG_fromBytes(OKM[:]) - u:= dx.mod(q) - return u -} - - -/* hash a message to an ECP point, using SHA2, random oracle method */ -func bls_hash_to_point(M []byte) *ECP { - DST := []byte("BLS_SIG_ZZZG1-SHA256-SSWU-RO-_NUL_") - u := hash_to_base(core.MC_SHA2,HASH_TYPE,DST,M,0) - u1 := hash_to_base(core.MC_SHA2,HASH_TYPE,DST,M,1) - - P:=ECP_hashit(u) - P1 := ECP_hashit(u1); - P.Add(P1) - P.Cfp() - P.Affine() - return P -} - -func Init() int { - G := ECP2_generator() - if G.Is_infinity() { - return BLS_FAIL - } - G2_TAB = precomp(G) - return BLS_OK -} - -/* generate key pair, private key S, public key W */ -func KeyPairGenerate(IKM []byte, S []byte, W []byte) int { - r := NewBIGints(CURVE_Order) - L := ceil(3*ceil(r.nbits(),8),2) - G := ECP2_generator() - if G.Is_infinity() { - return BLS_FAIL - } - SALT := []byte("BLS-SIG-KEYGEN-SALT-") - INFO := []byte("") - PRK := core.HKDF_Extract(core.MC_SHA2,HASH_TYPE,SALT,IKM) - OKM := core.HKDF_Expand(core.MC_SHA2,HASH_TYPE,L,PRK,INFO) - - dx:= DBIG_fromBytes(OKM[:]) - s:= dx.mod(r) - - s.ToBytes(S) - G = G2mul(G, s) - G.ToBytes(W,true) - return BLS_OK -} - -/* Sign message M using private key S to produce signature SIG */ - -func Core_Sign(SIG []byte, M []byte, S []byte) int { - D := bls_hash_to_point(M) - s := FromBytes(S) - D = G1mul(D, s) - D.ToBytes(SIG, true) - return BLS_OK -} - -/* Verify signature given message m, the signature SIG, and the public key W */ - -func Core_Verify(SIG []byte, M []byte, W []byte) int { - HM := bls_hash_to_point(M) - - D := ECP_fromBytes(SIG) - if !G1member(D) {return BLS_FAIL} - D.Neg() - - PK := ECP2_fromBytes(W) - - // Use new multi-pairing mechanism - - r := Initmp() - Another_pc(r, G2_TAB, D) - Another(r, PK, HM) - v := Miller(r) - - //.. or alternatively - // G := ECP2_generator() - // if G.Is_infinity() {return BLS_FAIL} - // v := Ate2(G, D, PK, HM) - - v = Fexp(v) - - if v.Isunity() { - return BLS_OK - } else { - return BLS_FAIL - } -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_BIG.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_BIG.go deleted file mode 100644 index aecb7cd9448..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_BIG.go +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -package FP256BN - -// BIG length in bytes and number base -const MODBYTES uint = 32 -const BASEBITS uint = 56 - -// BIG lengths and Masks -const NLEN int = int((1 + ((8*MODBYTES - 1) / BASEBITS))) -const DNLEN int = 2 * NLEN -const BMASK Chunk = ((Chunk(1) << BASEBITS) - 1) -const HBITS uint = (BASEBITS / 2) -const HMASK Chunk = ((Chunk(1) << HBITS) - 1) -const NEXCESS int = (1 << (uint(CHUNK) - BASEBITS - 1)) - -const BIGBITS int = int(MODBYTES * 8) - diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_CURVE.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_CURVE.go deleted file mode 100644 index 28abeda3d6e..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_CURVE.go +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -package FP256BN - -// Curve types -const WEIERSTRASS int = 0 -const EDWARDS int = 1 -const MONTGOMERY int = 2 - -// Pairing Friendly? -const NOT int = 0 -const BN int = 1 -const BLS int = 2 - -// Pairing Twist type -const D_TYPE int = 0 -const M_TYPE int = 1 - -// Sparsity -const FP_ZERO int = 0 -const FP_ONE int = 1 -const FP_SPARSEST int = 2 -const FP_SPARSER int = 3 -const FP_SPARSE int = 4 -const FP_DENSE int = 5 - -// Pairing x parameter sign -const POSITIVEX int = 0 -const NEGATIVEX int = 1 - -// Curve type - -const CURVETYPE int = WEIERSTRASS -const CURVE_PAIRING_TYPE int = BN - -// Pairings only - -const SEXTIC_TWIST int = M_TYPE -const SIGN_OF_X int = NEGATIVEX -const ATE_BITS int = 66 -const G2_TABLE int = 83 - -// associated hash function and AES key size - -const HASH_TYPE int = 32 -const AESKEY int = 16 - -// These are manually decided policy decisions. To block any potential patent issues set to false. - -const USE_GLV bool = true -const USE_GS_G2 bool = true -const USE_GS_GT bool = true - diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_FIELD.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_FIELD.go deleted file mode 100644 index 1337ac054b4..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/CONFIG_FIELD.go +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - - -package FP256BN - -// Modulus types -const NOT_SPECIAL int = 0 -const PSEUDO_MERSENNE int = 1 -const MONTGOMERY_FRIENDLY int = 2 -const GENERALISED_MERSENNE int = 3 - -const NEGATOWER int = 0 -const POSITOWER int = 1 - -// Modulus details -const MODBITS uint = 256 /* Number of bits in Modulus */ -const PM1D2 uint = 1 /* Modulus mod 8 */ -const MODTYPE int = NOT_SPECIAL //NOT_SPECIAL -const QNRI int = 0 // Fp2 QNR -const TOWER int = NEGATOWER // Tower type -const FEXCESS int32=((int32(1)<<24)-1) - -// Modulus Masks -const OMASK Chunk = ((Chunk(-1)) << (MODBITS % BASEBITS)) -const TBITS uint = MODBITS % BASEBITS // Number of active bits in top word -const TMASK Chunk = (Chunk(1) << TBITS) - 1 - diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/DBIG.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/DBIG.go deleted file mode 100644 index ddcfc424b6e..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/DBIG.go +++ /dev/null @@ -1,297 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* MiotCL double length DBIG number class */ - -package FP256BN - -import "strconv" - - - -func NewDBIG() *DBIG { - b := new(DBIG) - for i := 0; i < DNLEN; i++ { - b.w[i] = 0 - } - return b -} - -func NewDBIGcopy(x *DBIG) *DBIG { - b := new(DBIG) - for i := 0; i < DNLEN; i++ { - b.w[i] = x.w[i] - } - return b -} - -func NewDBIGscopy(x *BIG) *DBIG { - b := new(DBIG) - for i := 0; i < NLEN-1; i++ { - b.w[i] = x.w[i] - } - b.w[NLEN-1] = x.get(NLEN-1) & BMASK /* top word normalized */ - b.w[NLEN] = x.get(NLEN-1) >> BASEBITS - - for i := NLEN + 1; i < DNLEN; i++ { - b.w[i] = 0 - } - return b -} - -/* normalise this */ -func (r *DBIG) norm() { - carry := Chunk(0) - for i := 0; i < DNLEN-1; i++ { - d := r.w[i] + carry - r.w[i] = d & BMASK - carry = d >> BASEBITS - } - r.w[DNLEN-1] = (r.w[DNLEN-1] + carry) -} - -/* split DBIG at position n, return higher half, keep lower half */ -func (r *DBIG) split(n uint) *BIG { - t := NewBIG() - m := n % BASEBITS - carry := r.w[DNLEN-1] << (BASEBITS - m) - - for i := DNLEN - 2; i >= NLEN-1; i-- { - nw := (r.w[i] >> m) | carry - carry = (r.w[i] << (BASEBITS - m)) & BMASK - t.set(i-NLEN+1, nw) - } - r.w[NLEN-1] &= ((Chunk(1) << m) - 1) - return t -} - -func (r *DBIG) cmove(g *DBIG, d int) { - var b = Chunk(-d) - - for i := 0; i < DNLEN; i++ { - r.w[i] ^= (r.w[i] ^ g.w[i]) & b - } -} - -/* Compare a and b, return 0 if a==b, -1 if ab. Inputs must be normalised */ -func dcomp(a *DBIG, b *DBIG) int { - gt:=Chunk(0) - eq:=Chunk(1) - for i := DNLEN - 1; i >= 0; i-- { - gt |= ((b.w[i]-a.w[i]) >> BASEBITS) & eq - eq &= ((b.w[i]^a.w[i])-1) >> BASEBITS - } - return int(gt+gt+eq-1) -} - -/* Copy from another DBIG */ -func (r *DBIG) copy(x *DBIG) { - for i := 0; i < DNLEN; i++ { - r.w[i] = x.w[i] - } -} - -/* Copy from another BIG to upper half */ -func (r *DBIG) ucopy(x *BIG) { - for i := 0; i < NLEN; i++ { - r.w[i] = 0 - } - for i := NLEN; i < DNLEN; i++ { - r.w[i] = x.w[i-NLEN] - } -} - -func (r *DBIG) add(x *DBIG) { - for i := 0; i < DNLEN; i++ { - r.w[i] = r.w[i] + x.w[i] - } -} - -/* this-=x */ -func (r *DBIG) sub(x *DBIG) { - for i := 0; i < DNLEN; i++ { - r.w[i] = r.w[i] - x.w[i] - } -} - -/* this-=x */ -func (r *DBIG) rsub(x *DBIG) { - for i := 0; i < DNLEN; i++ { - r.w[i] = x.w[i] - r.w[i] - } -} - -/* general shift left */ -func (r *DBIG) shl(k uint) { - n := k % BASEBITS - m := int(k / BASEBITS) - - r.w[DNLEN-1] = (r.w[DNLEN-1-m] << n) | (r.w[DNLEN-m-2] >> (BASEBITS - n)) - for i := DNLEN - 2; i > m; i-- { - r.w[i] = ((r.w[i-m] << n) & BMASK) | (r.w[i-m-1] >> (BASEBITS - n)) - } - r.w[m] = (r.w[0] << n) & BMASK - for i := 0; i < m; i++ { - r.w[i] = 0 - } -} - -/* general shift right */ -func (r *DBIG) shr(k uint) { - n := (k % BASEBITS) - m := int(k / BASEBITS) - for i := 0; i < DNLEN-m-1; i++ { - r.w[i] = (r.w[m+i] >> n) | ((r.w[m+i+1] << (BASEBITS - n)) & BMASK) - } - r.w[DNLEN-m-1] = r.w[DNLEN-1] >> n - for i := DNLEN - m; i < DNLEN; i++ { - r.w[i] = 0 - } -} - -/* reduces this DBIG mod a BIG, and returns the BIG */ -func (r *DBIG) mod(c *BIG) *BIG { - r.norm() - m := NewDBIGscopy(c) - dr := NewDBIG() - - if dcomp(r, m) < 0 { - return NewBIGdcopy(r) - } - - m.shl(1) - k := 1 - - for dcomp(r, m) >= 0 { - m.shl(1) - k++ - } - - for k > 0 { - m.shr(1) - - dr.copy(r) - dr.sub(m) - dr.norm() - r.cmove(dr, int(1-((dr.w[DNLEN-1]>>uint(CHUNK-1))&1))) - k-- - } - return NewBIGdcopy(r) -} - -/* return this/c */ -func (r *DBIG) div(c *BIG) *BIG { - var d int - k := 0 - m := NewDBIGscopy(c) - a := NewBIGint(0) - e := NewBIGint(1) - sr := NewBIG() - dr := NewDBIG() - r.norm() - - for dcomp(r, m) >= 0 { - e.fshl(1) - m.shl(1) - k++ - } - - for k > 0 { - m.shr(1) - e.shr(1) - - dr.copy(r) - dr.sub(m) - dr.norm() - d = int(1 - ((dr.w[DNLEN-1] >> uint(CHUNK-1)) & 1)) - r.cmove(dr, d) - sr.copy(a) - sr.add(e) - sr.norm() - a.cmove(sr, d) - - k-- - } - return a -} - -/* Convert to Hex String */ -func (r *DBIG) toString() string { - s := "" - len := r.nbits() - - if len%4 == 0 { - len /= 4 - } else { - len /= 4 - len++ - - } - - for i := len - 1; i >= 0; i-- { - b := NewDBIGcopy(r) - - b.shr(uint(i * 4)) - s += strconv.FormatInt(int64(b.w[0]&15), 16) - } - return s -} - -/* return number of bits */ -func (r *DBIG) nbits() int { - k := DNLEN - 1 - t := NewDBIGcopy(r) - t.norm() - for k >= 0 && t.w[k] == 0 { - k-- - } - if k < 0 { - return 0 - } - bts := int(BASEBITS) * k - c := t.w[k] - for c != 0 { - c /= 2 - bts++ - } - return bts -} - -/* convert from byte array to BIG */ -func DBIG_fromBytes(b []byte) *DBIG { - m := NewDBIG() - for i := 0; i < len(b); i++ { - m.shl(8) - m.w[0] += Chunk(int(b[i] & 0xff)) - } - return m -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECDH.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECDH.go deleted file mode 100644 index 150d6fb1351..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECDH.go +++ /dev/null @@ -1,350 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* Elliptic Curve API high-level functions */ - -package FP256BN - - -import "github.com/hyperledger/fabric-amcl/core" - -const INVALID_PUBLIC_KEY int = -2 -const ERROR int = -3 -//const INVALID int = -4 -const EFS int = int(MODBYTES) -const EGS int = int(MODBYTES) - - - -/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p), - * where S is the secret key and W is the public key - * and G is fixed generator. - * If RNG is NULL then the private key is provided externally in S - * otherwise it is generated randomly internally */ -func ECDH_KEY_PAIR_GENERATE(RNG *core.RAND, S []byte, W []byte) int { - res := 0 - var s *BIG - var G *ECP - - G = ECP_generator() - - r := NewBIGints(CURVE_Order) - - if RNG == nil { - s = FromBytes(S) - s.Mod(r) - } else { - s = Randtrunc(r, 16*AESKEY, RNG) - } - - s.ToBytes(S) - - WP := G.mul(s) - - WP.ToBytes(W, false) // To use point compression on public keys, change to true - - return res -} - -/* validate public key */ -func ECDH_PUBLIC_KEY_VALIDATE(W []byte) int { - WP := ECP_fromBytes(W) - res := 0 - - r := NewBIGints(CURVE_Order) - - if WP.Is_infinity() { - res = INVALID_PUBLIC_KEY - } - if res == 0 { - - q := NewBIGints(Modulus) - nb := q.nbits() - k := NewBIGint(1) - k.shl(uint((nb + 4) / 2)) - k.add(q) - k.div(r) - - for k.parity() == 0 { - k.shr(1) - WP.dbl() - } - - if !k.isunity() { - WP = WP.mul(k) - } - if WP.Is_infinity() { - res = INVALID_PUBLIC_KEY - } - - } - return res -} - -/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */ -func ECDH_ECPSVDP_DH(S []byte, WD []byte, Z []byte) int { - res := 0 - var T [EFS]byte - - s := FromBytes(S) - - W := ECP_fromBytes(WD) - if W.Is_infinity() { - res = ERROR - } - - if res == 0 { - r := NewBIGints(CURVE_Order) - s.Mod(r) - W = W.mul(s) - if W.Is_infinity() { - res = ERROR - } else { - W.GetX().ToBytes(T[:]) - for i := 0; i < EFS; i++ { - Z[i] = T[i] - } - } - } - return res -} - -/* IEEE ECDSA Signature, C and D are signature on F using private key S */ -func ECDH_ECPSP_DSA(sha int, RNG *core.RAND, S []byte, F []byte, C []byte, D []byte) int { - var T [EFS]byte - - B := core.GPhashit(core.MC_SHA2, sha, int(MODBYTES), F, -1, nil ) - G := ECP_generator() - - r := NewBIGints(CURVE_Order) - - s := FromBytes(S) - f := FromBytes(B[:]) - - c := NewBIGint(0) - d := NewBIGint(0) - V := NewECP() - - for d.iszilch() { - u := Randomnum(r, RNG) - w := Randomnum(r, RNG) /* side channel masking */ - V.Copy(G) - V = V.mul(u) - vx := V.GetX() - c.copy(vx) - c.Mod(r) - if c.iszilch() { - continue - } - u.copy(Modmul(u, w, r)) - u.Invmodp(r) - d.copy(Modmul(s, c, r)) - d.add(f) - d.copy(Modmul(d, w, r)) - d.copy(Modmul(u, d, r)) - } - - c.ToBytes(T[:]) - for i := 0; i < EFS; i++ { - C[i] = T[i] - } - d.ToBytes(T[:]) - for i := 0; i < EFS; i++ { - D[i] = T[i] - } - return 0 -} - -/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */ -func ECDH_ECPVP_DSA(sha int, W []byte, F []byte, C []byte, D []byte) int { - res := 0 - - B := core.GPhashit(core.MC_SHA2, sha, int(MODBYTES), F, -1, nil ) - - G := ECP_generator() - r := NewBIGints(CURVE_Order) - - c := FromBytes(C) - d := FromBytes(D) - f := FromBytes(B[:]) - - if c.iszilch() || Comp(c, r) >= 0 || d.iszilch() || Comp(d, r) >= 0 { - res = ERROR - } - - if res == 0 { - d.Invmodp(r) - f.copy(Modmul(f, d, r)) - h2 := Modmul(c, d, r) - - WP := ECP_fromBytes(W) - if WP.Is_infinity() { - res = ERROR - } else { - P := NewECP() - P.Copy(WP) - - P = P.Mul2(h2, G, f) - - if P.Is_infinity() { - res = ERROR - } else { - d = P.GetX() - d.Mod(r) - - if Comp(d, c) != 0 { - res = ERROR - } - } - } - } - - return res -} - -/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */ -func ECDH_ECIES_ENCRYPT(sha int, P1 []byte, P2 []byte, RNG *core.RAND, W []byte, M []byte, V []byte, T []byte) []byte { - var Z [EFS]byte - var VZ [3*EFS + 1]byte - var K1 [AESKEY]byte - var K2 [AESKEY]byte - var U [EGS]byte - - if ECDH_KEY_PAIR_GENERATE(RNG, U[:], V) != 0 { - return nil - } - if ECDH_ECPSVDP_DH(U[:], W, Z[:]) != 0 { - return nil - } - - for i := 0; i < 2*EFS+1; i++ { - VZ[i] = V[i] - } - for i := 0; i < EFS; i++ { - VZ[2*EFS+1+i] = Z[i] - } - - K := core.KDF2(core.MC_SHA2, sha, VZ[:], P1, 2*AESKEY) - - for i := 0; i < AESKEY; i++ { - K1[i] = K[i] - K2[i] = K[AESKEY+i] - } - - C := core.AES_CBC_IV0_ENCRYPT(K1[:], M) - - L2 := core.InttoBytes(len(P2), 8) - - var AC []byte - - for i := 0; i < len(C); i++ { - AC = append(AC, C[i]) - } - for i := 0; i < len(P2); i++ { - AC = append(AC, P2[i]) - } - for i := 0; i < 8; i++ { - AC = append(AC, L2[i]) - } - - core.HMAC(core.MC_SHA2, sha, T, len(T), K2[:], AC) - - return C -} - -/* constant time n-byte compare */ -func ncomp(T1 []byte, T2 []byte, n int) bool { - res := 0 - for i := 0; i < n; i++ { - res |= int(T1[i] ^ T2[i]) - } - if res == 0 { - return true - } - return false -} - -/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */ -func ECDH_ECIES_DECRYPT(sha int, P1 []byte, P2 []byte, V []byte, C []byte, T []byte, U []byte) []byte { - var Z [EFS]byte - var VZ [3*EFS + 1]byte - var K1 [AESKEY]byte - var K2 [AESKEY]byte - - var TAG []byte = T[:] - - if ECDH_ECPSVDP_DH(U, V, Z[:]) != 0 { - return nil - } - - for i := 0; i < 2*EFS+1; i++ { - VZ[i] = V[i] - } - for i := 0; i < EFS; i++ { - VZ[2*EFS+1+i] = Z[i] - } - - K := core.KDF2(core.MC_SHA2, sha, VZ[:], P1, 2*AESKEY) - - for i := 0; i < AESKEY; i++ { - K1[i] = K[i] - K2[i] = K[AESKEY+i] - } - - M := core.AES_CBC_IV0_DECRYPT(K1[:], C) - - if M == nil { - return nil - } - - L2 := core.InttoBytes(len(P2), 8) - - var AC []byte - - for i := 0; i < len(C); i++ { - AC = append(AC, C[i]) - } - for i := 0; i < len(P2); i++ { - AC = append(AC, P2[i]) - } - for i := 0; i < 8; i++ { - AC = append(AC, L2[i]) - } - - core.HMAC(core.MC_SHA2, sha, TAG, len(TAG), K2[:],AC) - - if !ncomp(T, TAG, len(T)) { - return nil - } - - return M -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECP.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECP.go deleted file mode 100644 index 340c572b5fd..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECP.go +++ /dev/null @@ -1,1384 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -package FP256BN - -/* Elliptic Curve Point Structure */ - -type ECP struct { - x *FP - y *FP - z *FP -} - -/* Constructors */ -func NewECP() *ECP { - E := new(ECP) - E.x = NewFP() - E.y = NewFPint(1) - if CURVETYPE == EDWARDS { - E.z = NewFPint(1) - } else { - E.z = NewFP() - } - return E -} - -/* set (x,y) from two BIGs */ -func NewECPbigs(ix *BIG, iy *BIG) *ECP { - E := new(ECP) - E.x = NewFPbig(ix) - E.y = NewFPbig(iy) - E.z = NewFPint(1) - E.x.norm() - rhs := RHS(E.x) - - if CURVETYPE == MONTGOMERY { - if rhs.qr(nil) != 1 { - E.inf() - } - } else { - y2 := NewFPcopy(E.y) - y2.sqr() - if !y2.Equals(rhs) { - E.inf() - } - } - return E -} - -/* set (x,y) from BIG and a bit */ -func NewECPbigint(ix *BIG, s int) *ECP { - E := new(ECP) - E.x = NewFPbig(ix) - E.y = NewFP() - E.x.norm() - rhs := RHS(E.x) - E.z = NewFPint(1) - hint := NewFP() - if rhs.qr(hint) == 1 { - ny := rhs.sqrt(hint) - if ny.redc().parity() != s { - ny.neg() - } - E.y.copy(ny) - } else { - E.inf() - } - return E -} - -/* set from x - calculate y from curve equation */ -func NewECPbig(ix *BIG) *ECP { - E := new(ECP) - E.x = NewFPbig(ix) - E.y = NewFP() - E.x.norm() - rhs := RHS(E.x) - E.z = NewFPint(1) - hint := NewFP() - if rhs.qr(hint) == 1 { - if CURVETYPE != MONTGOMERY { - E.y.copy(rhs.sqrt(hint)) - } - } else { - E.inf() - } - return E -} - -/* test for O point-at-infinity */ -func (E *ECP) Is_infinity() bool { - // if E.INF {return true} - - if CURVETYPE == EDWARDS { - return (E.x.iszilch() && E.y.Equals(E.z)) - } - if CURVETYPE == WEIERSTRASS { - return (E.x.iszilch() && E.z.iszilch()) - } - if CURVETYPE == MONTGOMERY { - return E.z.iszilch() - } - return true -} - -/* Conditional swap of P and Q dependant on d */ -func (E *ECP) cswap(Q *ECP, d int) { - E.x.cswap(Q.x, d) - if CURVETYPE != MONTGOMERY { - E.y.cswap(Q.y, d) - } - E.z.cswap(Q.z, d) -} - -/* Conditional move of Q to P dependant on d */ -func (E *ECP) cmove(Q *ECP, d int) { - E.x.cmove(Q.x, d) - if CURVETYPE != MONTGOMERY { - E.y.cmove(Q.y, d) - } - E.z.cmove(Q.z, d) -} - -/* return 1 if b==c, no branching */ -func teq(b int32, c int32) int { - x := b ^ c - x -= 1 // if x=0, x now -1 - return int((x >> 31) & 1) -} - -/* this=P */ -func (E *ECP) Copy(P *ECP) { - E.x.copy(P.x) - if CURVETYPE != MONTGOMERY { - E.y.copy(P.y) - } - E.z.copy(P.z) -} - -/* this=-this */ -func (E *ECP) Neg() { - if CURVETYPE == WEIERSTRASS { - E.y.neg() - E.y.norm() - } - if CURVETYPE == EDWARDS { - E.x.neg() - E.x.norm() - } - return -} - -/* Constant time select from pre-computed table */ -func (E *ECP) selector(W []*ECP, b int32) { - MP := NewECP() - m := b >> 31 - babs := (b ^ m) - m - - babs = (babs - 1) / 2 - - E.cmove(W[0], teq(babs, 0)) // conditional move - E.cmove(W[1], teq(babs, 1)) - E.cmove(W[2], teq(babs, 2)) - E.cmove(W[3], teq(babs, 3)) - E.cmove(W[4], teq(babs, 4)) - E.cmove(W[5], teq(babs, 5)) - E.cmove(W[6], teq(babs, 6)) - E.cmove(W[7], teq(babs, 7)) - - MP.Copy(E) - MP.Neg() - E.cmove(MP, int(m&1)) -} - -/* set this=O */ -func (E *ECP) inf() { - E.x.zero() - if CURVETYPE != MONTGOMERY { - E.y.one() - } - if CURVETYPE != EDWARDS { - E.z.zero() - } else { - E.z.one() - } -} - -/* Test P == Q */ -func (E *ECP) Equals(Q *ECP) bool { - a := NewFP() - b := NewFP() - a.copy(E.x) - a.mul(Q.z) - a.reduce() - b.copy(Q.x) - b.mul(E.z) - b.reduce() - if !a.Equals(b) { - return false - } - if CURVETYPE != MONTGOMERY { - a.copy(E.y) - a.mul(Q.z) - a.reduce() - b.copy(Q.y) - b.mul(E.z) - b.reduce() - if !a.Equals(b) { - return false - } - } - - return true -} - -/* Calculate RHS of curve equation */ -func RHS(x *FP) *FP { - r := NewFPcopy(x) - r.sqr() - - if CURVETYPE == WEIERSTRASS { // x^3+Ax+B - b := NewFPbig(NewBIGints(CURVE_B)) - r.mul(x) - if CURVE_A == -3 { - cx := NewFPcopy(x) - cx.imul(3) - cx.neg() - cx.norm() - r.add(cx) - } - r.add(b) - } - if CURVETYPE == EDWARDS { // (Ax^2-1)/(Bx^2-1) - b := NewFPbig(NewBIGints(CURVE_B)) - - one := NewFPint(1) - b.mul(r) - b.sub(one) - b.norm() - if CURVE_A == -1 { - r.neg() - } - r.sub(one) - r.norm() - b.inverse() - r.mul(b) - } - if CURVETYPE == MONTGOMERY { // x^3+Ax^2+x - x3 := NewFP() - x3.copy(r) - x3.mul(x) - r.imul(CURVE_A) - r.add(x3) - r.add(x) - } - r.reduce() - return r -} - -/* set to affine - from (x,y,z) to (x,y) */ -func (E *ECP) Affine() { - if E.Is_infinity() { - return - } - one := NewFPint(1) - if E.z.Equals(one) { - return - } - E.z.inverse() - E.x.mul(E.z) - E.x.reduce() - - if CURVETYPE != MONTGOMERY { - E.y.mul(E.z) - E.y.reduce() - } - E.z.copy(one) -} - -/* extract x as a BIG */ -func (E *ECP) GetX() *BIG { - W := NewECP() - W.Copy(E) - W.Affine() - return W.x.redc() -} - -/* extract y as a BIG */ -func (E *ECP) GetY() *BIG { - W := NewECP() - W.Copy(E) - W.Affine() - return W.y.redc() -} - -/* get sign of Y */ -func (E *ECP) GetS() int { - y := E.GetY() - return y.parity() -} - -/* extract x as an FP */ -func (E *ECP) getx() *FP { - return E.x -} - -/* extract y as an FP */ -func (E *ECP) gety() *FP { - return E.y -} - -/* extract z as an FP */ -func (E *ECP) getz() *FP { - return E.z -} - -/* convert to byte array */ -func (E *ECP) ToBytes(b []byte, compress bool) { - var t [int(MODBYTES)]byte - MB := int(MODBYTES) - W := NewECP() - W.Copy(E) - W.Affine() - W.x.redc().ToBytes(t[:]) - - - if CURVETYPE == MONTGOMERY { - for i := 0; i < MB; i++ { - b[i] = t[i] - } - //b[0] = 0x06 - return - } - - for i := 0; i < MB; i++ { - b[i+1] = t[i] - } - - if compress { - b[0] = 0x02 - if W.y.redc().parity() == 1 { - b[0] = 0x03 - } - return - } - - b[0] = 0x04 - - W.y.redc().ToBytes(t[:]) - for i := 0; i < MB; i++ { - b[i+MB+1] = t[i] - } -} - -/* convert from byte array to point */ -func ECP_fromBytes(b []byte) *ECP { - var t [int(MODBYTES)]byte - MB := int(MODBYTES) - p := NewBIGints(Modulus) - - if CURVETYPE == MONTGOMERY { - for i := 0; i < MB; i++ { - t[i] = b[i] - } - px := FromBytes(t[:]) - if Comp(px, p) >= 0 { - return NewECP() - } - return NewECPbig(px) - } - - for i := 0; i < MB; i++ { - t[i] = b[i+1] - } - px := FromBytes(t[:]) - if Comp(px, p) >= 0 { - return NewECP() - } - - if b[0] == 0x04 { - for i := 0; i < MB; i++ { - t[i] = b[i+MB+1] - } - py := FromBytes(t[:]) - if Comp(py, p) >= 0 { - return NewECP() - } - return NewECPbigs(px, py) - } - - if b[0] == 0x02 || b[0] == 0x03 { - return NewECPbigint(px, int(b[0]&1)) - } - - return NewECP() -} - -/* convert to hex string */ -func (E *ECP) ToString() string { - W := NewECP() - W.Copy(E) - W.Affine() - if W.Is_infinity() { - return "infinity" - } - if CURVETYPE == MONTGOMERY { - return "(" + W.x.redc().ToString() + ")" - } else { - return "(" + W.x.redc().ToString() + "," + W.y.redc().ToString() + ")" - } -} - -/* this*=2 */ -func (E *ECP) dbl() { - - if CURVETYPE == WEIERSTRASS { - if CURVE_A == 0 { - t0 := NewFPcopy(E.y) - t0.sqr() - t1 := NewFPcopy(E.y) - t1.mul(E.z) - t2 := NewFPcopy(E.z) - t2.sqr() - - E.z.copy(t0) - E.z.add(t0) - E.z.norm() - E.z.add(E.z) - E.z.add(E.z) - E.z.norm() - t2.imul(3 * CURVE_B_I) - - x3 := NewFPcopy(t2) - x3.mul(E.z) - - y3 := NewFPcopy(t0) - y3.add(t2) - y3.norm() - E.z.mul(t1) - t1.copy(t2) - t1.add(t2) - t2.add(t1) - t0.sub(t2) - t0.norm() - y3.mul(t0) - y3.add(x3) - t1.copy(E.x) - t1.mul(E.y) - E.x.copy(t0) - E.x.norm() - E.x.mul(t1) - E.x.add(E.x) - E.x.norm() - E.y.copy(y3) - E.y.norm() - } else { - t0 := NewFPcopy(E.x) - t1 := NewFPcopy(E.y) - t2 := NewFPcopy(E.z) - t3 := NewFPcopy(E.x) - z3 := NewFPcopy(E.z) - y3 := NewFP() - x3 := NewFP() - b := NewFP() - - if CURVE_B_I == 0 { - b.copy(NewFPbig(NewBIGints(CURVE_B))) - } - - t0.sqr() //1 x^2 - t1.sqr() //2 y^2 - t2.sqr() //3 - - t3.mul(E.y) //4 - t3.add(t3) - t3.norm() //5 - z3.mul(E.x) //6 - z3.add(z3) - z3.norm() //7 - y3.copy(t2) - - if CURVE_B_I == 0 { - y3.mul(b) - } else { - y3.imul(CURVE_B_I) - } - - y3.sub(z3) //9 *** - x3.copy(y3) - x3.add(y3) - x3.norm() //10 - - y3.add(x3) //11 - x3.copy(t1) - x3.sub(y3) - x3.norm() //12 - y3.add(t1) - y3.norm() //13 - y3.mul(x3) //14 - x3.mul(t3) //15 - t3.copy(t2) - t3.add(t2) //16 - t2.add(t3) //17 - - if CURVE_B_I == 0 { - z3.mul(b) - } else { - z3.imul(CURVE_B_I) - } - - z3.sub(t2) //19 - z3.sub(t0) - z3.norm() //20 *** - t3.copy(z3) - t3.add(z3) //21 - - z3.add(t3) - z3.norm() //22 - t3.copy(t0) - t3.add(t0) //23 - t0.add(t3) //24 - t0.sub(t2) - t0.norm() //25 - - t0.mul(z3) //26 - y3.add(t0) //27 - t0.copy(E.y) - t0.mul(E.z) //28 - t0.add(t0) - t0.norm() //29 - z3.mul(t0) //30 - x3.sub(z3) //x3.norm();//31 - t0.add(t0) - t0.norm() //32 - t1.add(t1) - t1.norm() //33 - z3.copy(t0) - z3.mul(t1) //34 - - E.x.copy(x3) - E.x.norm() - E.y.copy(y3) - E.y.norm() - E.z.copy(z3) - E.z.norm() - } - } - - if CURVETYPE == EDWARDS { - C := NewFPcopy(E.x) - D := NewFPcopy(E.y) - H := NewFPcopy(E.z) - J := NewFP() - - E.x.mul(E.y) - E.x.add(E.x) - E.x.norm() - C.sqr() - D.sqr() - if CURVE_A == -1 { - C.neg() - } - E.y.copy(C) - E.y.add(D) - E.y.norm() - - H.sqr() - H.add(H) - E.z.copy(E.y) - J.copy(E.y) - J.sub(H) - J.norm() - E.x.mul(J) - C.sub(D) - C.norm() - E.y.mul(C) - E.z.mul(J) - - } - if CURVETYPE == MONTGOMERY { - A := NewFPcopy(E.x) - B := NewFPcopy(E.x) - AA := NewFP() - BB := NewFP() - C := NewFP() - - A.add(E.z) - A.norm() - AA.copy(A) - AA.sqr() - B.sub(E.z) - B.norm() - BB.copy(B) - BB.sqr() - C.copy(AA) - C.sub(BB) - C.norm() - - E.x.copy(AA) - E.x.mul(BB) - - A.copy(C) - A.imul((CURVE_A + 2) / 4) - - BB.add(A) - BB.norm() - E.z.copy(BB) - E.z.mul(C) - } - return -} - -/* this+=Q */ -func (E *ECP) Add(Q *ECP) { - - if CURVETYPE == WEIERSTRASS { - if CURVE_A == 0 { - b := 3 * CURVE_B_I - t0 := NewFPcopy(E.x) - t0.mul(Q.x) - t1 := NewFPcopy(E.y) - t1.mul(Q.y) - t2 := NewFPcopy(E.z) - t2.mul(Q.z) - t3 := NewFPcopy(E.x) - t3.add(E.y) - t3.norm() - t4 := NewFPcopy(Q.x) - t4.add(Q.y) - t4.norm() - t3.mul(t4) - t4.copy(t0) - t4.add(t1) - - t3.sub(t4) - t3.norm() - t4.copy(E.y) - t4.add(E.z) - t4.norm() - x3 := NewFPcopy(Q.y) - x3.add(Q.z) - x3.norm() - - t4.mul(x3) - x3.copy(t1) - x3.add(t2) - - t4.sub(x3) - t4.norm() - x3.copy(E.x) - x3.add(E.z) - x3.norm() - y3 := NewFPcopy(Q.x) - y3.add(Q.z) - y3.norm() - x3.mul(y3) - y3.copy(t0) - y3.add(t2) - y3.rsub(x3) - y3.norm() - x3.copy(t0) - x3.add(t0) - t0.add(x3) - t0.norm() - t2.imul(b) - - z3 := NewFPcopy(t1) - z3.add(t2) - z3.norm() - t1.sub(t2) - t1.norm() - y3.imul(b) - - x3.copy(y3) - x3.mul(t4) - t2.copy(t3) - t2.mul(t1) - x3.rsub(t2) - y3.mul(t0) - t1.mul(z3) - y3.add(t1) - t0.mul(t3) - z3.mul(t4) - z3.add(t0) - - E.x.copy(x3) - E.x.norm() - E.y.copy(y3) - E.y.norm() - E.z.copy(z3) - E.z.norm() - } else { - - t0 := NewFPcopy(E.x) - t1 := NewFPcopy(E.y) - t2 := NewFPcopy(E.z) - t3 := NewFPcopy(E.x) - t4 := NewFPcopy(Q.x) - z3 := NewFP() - y3 := NewFPcopy(Q.x) - x3 := NewFPcopy(Q.y) - b := NewFP() - - if CURVE_B_I == 0 { - b.copy(NewFPbig(NewBIGints(CURVE_B))) - } - - t0.mul(Q.x) //1 - t1.mul(Q.y) //2 - t2.mul(Q.z) //3 - - t3.add(E.y) - t3.norm() //4 - t4.add(Q.y) - t4.norm() //5 - t3.mul(t4) //6 - t4.copy(t0) - t4.add(t1) //7 - t3.sub(t4) - t3.norm() //8 - t4.copy(E.y) - t4.add(E.z) - t4.norm() //9 - x3.add(Q.z) - x3.norm() //10 - t4.mul(x3) //11 - x3.copy(t1) - x3.add(t2) //12 - - t4.sub(x3) - t4.norm() //13 - x3.copy(E.x) - x3.add(E.z) - x3.norm() //14 - y3.add(Q.z) - y3.norm() //15 - - x3.mul(y3) //16 - y3.copy(t0) - y3.add(t2) //17 - - y3.rsub(x3) - y3.norm() //18 - z3.copy(t2) - - if CURVE_B_I == 0 { - z3.mul(b) - } else { - z3.imul(CURVE_B_I) - } - - x3.copy(y3) - x3.sub(z3) - x3.norm() //20 - z3.copy(x3) - z3.add(x3) //21 - - x3.add(z3) //22 - z3.copy(t1) - z3.sub(x3) - z3.norm() //23 - x3.add(t1) - x3.norm() //24 - - if CURVE_B_I == 0 { - y3.mul(b) - } else { - y3.imul(CURVE_B_I) - } - - t1.copy(t2) - t1.add(t2) //26 - t2.add(t1) //27 - - y3.sub(t2) //28 - - y3.sub(t0) - y3.norm() //29 - t1.copy(y3) - t1.add(y3) //30 - y3.add(t1) - y3.norm() //31 - - t1.copy(t0) - t1.add(t0) //32 - t0.add(t1) //33 - t0.sub(t2) - t0.norm() //34 - t1.copy(t4) - t1.mul(y3) //35 - t2.copy(t0) - t2.mul(y3) //36 - y3.copy(x3) - y3.mul(z3) //37 - y3.add(t2) //38 - x3.mul(t3) //39 - x3.sub(t1) //40 - z3.mul(t4) //41 - t1.copy(t3) - t1.mul(t0) //42 - z3.add(t1) - E.x.copy(x3) - E.x.norm() - E.y.copy(y3) - E.y.norm() - E.z.copy(z3) - E.z.norm() - - } - } - if CURVETYPE == EDWARDS { - b := NewFPbig(NewBIGints(CURVE_B)) - A := NewFPcopy(E.z) - B := NewFP() - C := NewFPcopy(E.x) - D := NewFPcopy(E.y) - EE := NewFP() - F := NewFP() - G := NewFP() - - A.mul(Q.z) - B.copy(A) - B.sqr() - C.mul(Q.x) - D.mul(Q.y) - - EE.copy(C) - EE.mul(D) - EE.mul(b) - F.copy(B) - F.sub(EE) - G.copy(B) - G.add(EE) - - if CURVE_A == 1 { - EE.copy(D) - EE.sub(C) - } - C.add(D) - - B.copy(E.x) - B.add(E.y) - D.copy(Q.x) - D.add(Q.y) - B.norm() - D.norm() - B.mul(D) - B.sub(C) - B.norm() - F.norm() - B.mul(F) - E.x.copy(A) - E.x.mul(B) - G.norm() - if CURVE_A == 1 { - EE.norm() - C.copy(EE) - C.mul(G) - } - if CURVE_A == -1 { - C.norm() - C.mul(G) - } - E.y.copy(A) - E.y.mul(C) - E.z.copy(F) - E.z.mul(G) - } - return -} - -/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */ -func (E *ECP) dadd(Q *ECP, W *ECP) { - A := NewFPcopy(E.x) - B := NewFPcopy(E.x) - C := NewFPcopy(Q.x) - D := NewFPcopy(Q.x) - DA := NewFP() - CB := NewFP() - - A.add(E.z) - B.sub(E.z) - - C.add(Q.z) - D.sub(Q.z) - A.norm() - D.norm() - - DA.copy(D) - DA.mul(A) - C.norm() - B.norm() - - CB.copy(C) - CB.mul(B) - - A.copy(DA) - A.add(CB) - A.norm() - A.sqr() - B.copy(DA) - B.sub(CB) - B.norm() - B.sqr() - - E.x.copy(A) - E.z.copy(W.x) - E.z.mul(B) - -} - -/* this-=Q */ -func (E *ECP) Sub(Q *ECP) { - NQ := NewECP() - NQ.Copy(Q) - NQ.Neg() - E.Add(NQ) -} - -/* constant time multiply by small integer of length bts - use ladder */ -func (E *ECP) pinmul(e int32, bts int32) *ECP { - if CURVETYPE == MONTGOMERY { - return E.mul(NewBIGint(int(e))) - } else { - P := NewECP() - R0 := NewECP() - R1 := NewECP() - R1.Copy(E) - - for i := bts - 1; i >= 0; i-- { - b := int((e >> uint32(i)) & 1) - P.Copy(R1) - P.Add(R0) - R0.cswap(R1, b) - R1.Copy(P) - R0.dbl() - R0.cswap(R1, b) - } - P.Copy(R0) - P.Affine() - return P - } -} - -/* return e.this */ - -func (E *ECP) mul(e *BIG) *ECP { - if e.iszilch() || E.Is_infinity() { - return NewECP() - } - P := NewECP() - if CURVETYPE == MONTGOMERY { - /* use Ladder */ - D := NewECP() - R0 := NewECP() - R0.Copy(E) - R1 := NewECP() - R1.Copy(E) - R1.dbl() - D.Copy(E) - D.Affine() - nb := e.nbits() - for i := nb - 2; i >= 0; i-- { - b := int(e.bit(i)) - P.Copy(R1) - P.dadd(R0, D) - R0.cswap(R1, b) - R1.Copy(P) - R0.dbl() - R0.cswap(R1, b) - } - P.Copy(R0) - } else { - // fixed size windows - mt := NewBIG() - t := NewBIG() - Q := NewECP() - C := NewECP() - - var W []*ECP - var w [1 + (NLEN*int(BASEBITS)+3)/4]int8 - - Q.Copy(E) - Q.dbl() - - W = append(W, NewECP()) - W[0].Copy(E) - - for i := 1; i < 8; i++ { - W = append(W, NewECP()) - W[i].Copy(W[i-1]) - W[i].Add(Q) - } - - // make exponent odd - add 2P if even, P if odd - t.copy(e) - s := int(t.parity()) - t.inc(1) - t.norm() - ns := int(t.parity()) - mt.copy(t) - mt.inc(1) - mt.norm() - t.cmove(mt, s) - Q.cmove(E, ns) - C.Copy(Q) - - nb := 1 + (t.nbits()+3)/4 - - // convert exponent to signed 4-bit window - for i := 0; i < nb; i++ { - w[i] = int8(t.lastbits(5) - 16) - t.dec(int(w[i])) - t.norm() - t.fshr(4) - } - w[nb] = int8(t.lastbits(5)) - - P.Copy(W[(int(w[nb])-1)/2]) - for i := nb - 1; i >= 0; i-- { - Q.selector(W, int32(w[i])) - P.dbl() - P.dbl() - P.dbl() - P.dbl() - P.Add(Q) - } - P.Sub(C) /* apply correction */ - } - P.Affine() - return P -} - -/* Public version */ -func (E *ECP) Mul(e *BIG) *ECP { - return E.mul(e) -} - -/* Return e.this+f.Q */ - -func (E *ECP) Mul2(e *BIG, Q *ECP, f *BIG) *ECP { - te := NewBIG() - tf := NewBIG() - mt := NewBIG() - S := NewECP() - T := NewECP() - C := NewECP() - var W []*ECP - var w [1 + (NLEN*int(BASEBITS)+1)/2]int8 - - te.copy(e) - tf.copy(f) - - // precompute table - for i := 0; i < 8; i++ { - W = append(W, NewECP()) - } - W[1].Copy(E) - W[1].Sub(Q) - W[2].Copy(E) - W[2].Add(Q) - S.Copy(Q) - S.dbl() - W[0].Copy(W[1]) - W[0].Sub(S) - W[3].Copy(W[2]) - W[3].Add(S) - T.Copy(E) - T.dbl() - W[5].Copy(W[1]) - W[5].Add(T) - W[6].Copy(W[2]) - W[6].Add(T) - W[4].Copy(W[5]) - W[4].Sub(S) - W[7].Copy(W[6]) - W[7].Add(S) - - // if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction - - s := int(te.parity()) - te.inc(1) - te.norm() - ns := int(te.parity()) - mt.copy(te) - mt.inc(1) - mt.norm() - te.cmove(mt, s) - T.cmove(E, ns) - C.Copy(T) - - s = int(tf.parity()) - tf.inc(1) - tf.norm() - ns = int(tf.parity()) - mt.copy(tf) - mt.inc(1) - mt.norm() - tf.cmove(mt, s) - S.cmove(Q, ns) - C.Add(S) - - mt.copy(te) - mt.add(tf) - mt.norm() - nb := 1 + (mt.nbits()+1)/2 - - // convert exponent to signed 2-bit window - for i := 0; i < nb; i++ { - a := (te.lastbits(3) - 4) - te.dec(int(a)) - te.norm() - te.fshr(2) - b := (tf.lastbits(3) - 4) - tf.dec(int(b)) - tf.norm() - tf.fshr(2) - w[i] = int8(4*a + b) - } - w[nb] = int8(4*te.lastbits(3) + tf.lastbits(3)) - S.Copy(W[(w[nb]-1)/2]) - - for i := nb - 1; i >= 0; i-- { - T.selector(W, int32(w[i])) - S.dbl() - S.dbl() - S.Add(T) - } - S.Sub(C) /* apply correction */ - S.Affine() - return S -} - -func (E *ECP) Cfp() { - cf := CURVE_Cof_I - if cf == 1 { - return - } - if cf == 4 { - E.dbl() - E.dbl() - return - } - if cf == 8 { - E.dbl() - E.dbl() - E.dbl() - return - } - c := NewBIGints(CURVE_Cof) - E.Copy(E.mul(c)) -} - -func ECP_hashit(h *BIG) *ECP { - P := NewECP() - - if CURVETYPE == MONTGOMERY { -// Elligator 2 - one:=NewFPint(1) - A:=NewFPint(CURVE_A) - t:=NewFPbig(h) - - t.sqr(); - - if PM1D2 == 2 { - t.add(t) - } - if PM1D2 == 1 { - t.neg(); - } - if PM1D2 > 2 { - t.imul(QNRI); - } - - t.add(one) - t.norm() - t.inverse() - X1:=NewFPcopy(t); X1.mul(A) - X1.neg(); - X2:=NewFPcopy(X1) - X2.add(A); X2.norm() - X2.neg() - rhs:=RHS(X2) - X1.cmove(X2,rhs.qr(nil)) - - a:=X1.redc() - P.Copy(NewECPbig(a)) - } - if CURVETYPE == EDWARDS { -// Elligator 2 - map to Montgomery, place point, map back - t:=NewFPbig(h) - one:=NewFPint(1) - B:=NewFPbig(NewBIGints(CURVE_B)) - A:=NewFPcopy(B) - sgn:=t.sign() - if (CURVE_A==1) { - A.add(one) - B.sub(one) - } else { - A.sub(one) - B.add(one) - } - A.norm(); B.norm() - KB:=NewFPcopy(B); - - A.div2() - B.div2() - B.div2() - B.sqr() - - t.sqr() - - if PM1D2 == 2 { - t.add(t) - } - if PM1D2 == 1 { - t.neg(); - } - if PM1D2 > 2 { - t.imul(QNRI); - } - - t.add(one); t.norm() - t.inverse() - X1:=NewFPcopy(t); X1.mul(A) - X1.neg() - - X2:=NewFPcopy(X1); - X2.add(A); X2.norm() - X2.neg() - - X1.norm() - t.copy(X1); t.sqr(); w1:=NewFPcopy(t); w1.mul(X1) - t.mul(A); w1.add(t) - t.copy(X1); t.mul(B) - w1.add(t) - w1.norm() - - X2.norm() - t.copy(X2); t.sqr(); w2:=NewFPcopy(t); w2.mul(X2) - t.mul(A); w2.add(t) - t.copy(X2); t.mul(B) - w2.add(t) - w2.norm() - - qres:=w2.qr(nil) - X1.cmove(X2,qres) - w1.cmove(w2,qres) - - Y:=w1.sqrt(nil) - t.copy(X1); t.add(t); t.add(t); t.norm() - - w1.copy(t); w1.sub(KB); w1.norm() - w2.copy(t); w2.add(KB); w2.norm() - t.copy(w1); t.mul(Y) - t.inverse() - - X1.mul(t) - X1.mul(w1) - Y.mul(t) - Y.mul(w2) - - x:=X1.redc() - - ne:=Y.sign()^sgn - NY:=NewFPcopy(Y); NY.neg(); NY.norm() - Y.cmove(NY,ne) - - y:=Y.redc() - P.Copy(NewECPbigs(x,y)) - } - if CURVETYPE == WEIERSTRASS { - // swu method - one:=NewFPint(1); - B:=NewFPbig(NewBIGints(CURVE_B)) - t:=NewFPbig(h) - x:=NewBIG(); - Y:=NewFP(); - sgn:=t.sign(); - if CURVE_A!=0 { - A:=NewFPint(CURVE_A) - t.sqr(); - if (PM1D2 == 2) { - t.add(t) - } else { - t.neg() - } - t.norm() - w:=NewFPcopy(t); w.add(one); w.norm() - w.mul(t) - A.mul(w) - A.inverse() - w.add(one); w.norm() - w.mul(B) - w.neg(); w.norm() - X2:=NewFPcopy(w); X2.mul(A) - X3:=NewFPcopy(t); X3.mul(X2) - rhs:=RHS(X3) - X2.cmove(X3,rhs.qr(nil)) - rhs.copy(RHS(X2)) - Y.copy(rhs.sqrt(nil)) - x.copy(X2.redc()) - } else { - A:=NewFPint(-3) - w:=A.sqrt(nil) - j:=NewFPcopy(w); j.sub(one); j.norm(); j.div2() - w.mul(t) - B.add(one) - Y.copy(t); Y.sqr() - B.add(Y); B.norm(); B.inverse() - w.mul(B) - t.mul(w) - X1:=NewFPcopy(j); X1.sub(t); X1.norm() - X2:=NewFPcopy(X1); X2.neg(); X2.sub(one); X2.norm() - w.sqr(); w.inverse() - X3:=NewFPcopy(w); X3.add(one); X3.norm() - rhs:=RHS(X2) - X1.cmove(X2,rhs.qr(nil)) - rhs.copy(RHS(X3)) - X1.cmove(X3,rhs.qr(nil)) - rhs.copy(RHS(X1)) - Y.copy(rhs.sqrt(nil)) - x.copy(X1.redc()) - } - ne:=Y.sign()^sgn - NY:=NewFPcopy(Y); NY.neg(); NY.norm() - Y.cmove(NY,ne) - - y:=Y.redc() - P.Copy(NewECPbigs(x,y)) - } - return P -} - -func ECP_mapit(h []byte) *ECP { - q := NewBIGints(Modulus) - dx:= DBIG_fromBytes(h[:]) - x:= dx.mod(q) - P:= ECP_hashit(x) - P.Cfp() - return P -} - -func ECP_generator() *ECP { - var G *ECP - - gx := NewBIGints(CURVE_Gx) - if CURVETYPE != MONTGOMERY { - gy := NewBIGints(CURVE_Gy) - G = NewECPbigs(gx, gy) - } else { - G = NewECPbig(gx) - } - return G -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECP2.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECP2.go deleted file mode 100644 index 92db18bd8c5..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ECP2.go +++ /dev/null @@ -1,797 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* MiotCL Weierstrass elliptic curve functions over FP2 */ - -package FP256BN - - - -type ECP2 struct { - x *FP2 - y *FP2 - z *FP2 -} - -func NewECP2() *ECP2 { - E := new(ECP2) - E.x = NewFP2() - E.y = NewFP2int(1) - E.z = NewFP2() - return E -} - -/* Test this=O? */ -func (E *ECP2) Is_infinity() bool { - return E.x.iszilch() && E.z.iszilch() -} - -/* copy this=P */ -func (E *ECP2) Copy(P *ECP2) { - E.x.copy(P.x) - E.y.copy(P.y) - E.z.copy(P.z) -} - -/* set this=O */ -func (E *ECP2) inf() { - E.x.zero() - E.y.one() - E.z.zero() -} - -/* set this=-this */ -func (E *ECP2) neg() { - E.y.norm() - E.y.neg() - E.y.norm() -} - -/* Conditional move of Q to P dependant on d */ -func (E *ECP2) cmove(Q *ECP2, d int) { - E.x.cmove(Q.x, d) - E.y.cmove(Q.y, d) - E.z.cmove(Q.z, d) -} - -/* Constant time select from pre-computed table */ -func (E *ECP2) selector(W []*ECP2, b int32) { - MP := NewECP2() - m := b >> 31 - babs := (b ^ m) - m - - babs = (babs - 1) / 2 - - E.cmove(W[0], teq(babs, 0)) // conditional move - E.cmove(W[1], teq(babs, 1)) - E.cmove(W[2], teq(babs, 2)) - E.cmove(W[3], teq(babs, 3)) - E.cmove(W[4], teq(babs, 4)) - E.cmove(W[5], teq(babs, 5)) - E.cmove(W[6], teq(babs, 6)) - E.cmove(W[7], teq(babs, 7)) - - MP.Copy(E) - MP.neg() - E.cmove(MP, int(m&1)) -} - -/* Test if P == Q */ -func (E *ECP2) Equals(Q *ECP2) bool { - - a := NewFP2copy(E.x) - b := NewFP2copy(Q.x) - a.mul(Q.z) - b.mul(E.z) - - if !a.Equals(b) { - return false - } - a.copy(E.y) - b.copy(Q.y) - a.mul(Q.z) - b.mul(E.z) - if !a.Equals(b) { - return false - } - - return true -} - -/* set to Affine - (x,y,z) to (x,y) */ -func (E *ECP2) Affine() { - if E.Is_infinity() { - return - } - one := NewFP2int(1) - if E.z.Equals(one) { - E.x.reduce() - E.y.reduce() - return - } - E.z.inverse() - - E.x.mul(E.z) - E.x.reduce() - E.y.mul(E.z) - E.y.reduce() - E.z.copy(one) -} - -/* extract affine x as FP2 */ -func (E *ECP2) GetX() *FP2 { - W := NewECP2() - W.Copy(E) - W.Affine() - return W.x -} - -/* extract affine y as FP2 */ -func (E *ECP2) GetY() *FP2 { - W := NewECP2() - W.Copy(E) - W.Affine() - return W.y -} - -/* extract projective x */ -func (E *ECP2) getx() *FP2 { - return E.x -} - -/* extract projective y */ -func (E *ECP2) gety() *FP2 { - return E.y -} - -/* extract projective z */ -func (E *ECP2) getz() *FP2 { - return E.z -} - -/* convert to byte array */ -func (E *ECP2) ToBytes(b []byte,compress bool) { - var t [int(MODBYTES)]byte - MB := int(MODBYTES) - - W := NewECP2() - W.Copy(E) - W.Affine() - - W.x.GetA().ToBytes(t[:]) - for i := 0; i < MB; i++ { - b[i+1] = t[i] - } - W.x.GetB().ToBytes(t[:]) - for i := 0; i < MB; i++ { - b[i+MB+1] = t[i] - } - - if !compress { - b[0]=0x04 - W.y.GetA().ToBytes(t[:]) - for i := 0; i < MB; i++ { - b[i+2*MB+1] = t[i] - } - W.y.GetB().ToBytes(t[:]) - for i := 0; i < MB; i++ { - b[i+3*MB+1] = t[i] - } - } else { - b[0]=0x02 - if W.y.sign() == 1 { - b[0]=0x03 - } - } - -} - -/* convert from byte array to point */ -func ECP2_fromBytes(b []byte) *ECP2 { - var t [int(MODBYTES)]byte - MB := int(MODBYTES) - typ := int(b[0]) - - for i := 0; i < MB; i++ { - t[i] = b[i+1] - } - ra := FromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = b[i+MB+1] - } - rb := FromBytes(t[:]) - rx := NewFP2bigs(ra, rb) - - if typ == 0x04 { - for i := 0; i < MB; i++ { - t[i] = b[i+2*MB+1] - } - ra = FromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = b[i+3*MB+1] - } - rb = FromBytes(t[:]) - ry := NewFP2bigs(ra, rb) - - return NewECP2fp2s(rx, ry) - } else { - return NewECP2fp2(rx,typ&1) - } -} - -/* convert this to hex string */ -func (E *ECP2) ToString() string { - W := NewECP2() - W.Copy(E) - W.Affine() - if W.Is_infinity() { - return "infinity" - } - return "(" + W.x.toString() + "," + W.y.toString() + ")" -} - -/* Calculate RHS of twisted curve equation x^3+B/i */ -func RHS2(x *FP2) *FP2 { - r := NewFP2copy(x) - r.sqr() - b := NewFP2big(NewBIGints(CURVE_B)) - - if SEXTIC_TWIST == D_TYPE { - b.div_ip() - } - if SEXTIC_TWIST == M_TYPE { - b.norm() - b.mul_ip() - b.norm() - } - r.mul(x) - r.add(b) - - r.reduce() - return r -} - -/* construct this from (x,y) - but set to O if not on curve */ -func NewECP2fp2s(ix *FP2, iy *FP2) *ECP2 { - E := new(ECP2) - E.x = NewFP2copy(ix) - E.y = NewFP2copy(iy) - E.z = NewFP2int(1) - E.x.norm() - rhs := RHS2(E.x) - y2 := NewFP2copy(E.y) - y2.sqr() - if !y2.Equals(rhs) { - E.inf() - } - return E -} - -/* construct this from x - but set to O if not on curve */ -func NewECP2fp2(ix *FP2, s int) *ECP2 { - E := new(ECP2) - E.x = NewFP2copy(ix) - E.y = NewFP2int(1) - E.z = NewFP2int(1) - E.x.norm() - rhs := RHS2(E.x) - if rhs.qr() == 1 { - rhs.sqrt() - if rhs.sign() != s { - rhs.neg() - } - rhs.reduce() - E.y.copy(rhs) - - } else { - E.inf() - } - return E -} - -/* this+=this */ -func (E *ECP2) dbl() int { - iy := NewFP2copy(E.y) - if SEXTIC_TWIST == D_TYPE { - iy.mul_ip() - iy.norm() - } - - t0 := NewFP2copy(E.y) //***** Change - t0.sqr() - if SEXTIC_TWIST == D_TYPE { - t0.mul_ip() - } - t1 := NewFP2copy(iy) - t1.mul(E.z) - t2 := NewFP2copy(E.z) - t2.sqr() // z^2 - - E.z.copy(t0) // y^2 - E.z.add(t0) - E.z.norm() // 2y^2 - E.z.add(E.z) - E.z.add(E.z) // 8y^2 - E.z.norm() - - t2.imul(3 * CURVE_B_I) // 3bz^2 - if SEXTIC_TWIST == M_TYPE { - t2.mul_ip() - t2.norm() - } - x3 := NewFP2copy(t2) - x3.mul(E.z) - - y3 := NewFP2copy(t0) - - y3.add(t2) - y3.norm() - E.z.mul(t1) - t1.copy(t2) - t1.add(t2) - t2.add(t1) - t2.norm() - t0.sub(t2) - t0.norm() //y^2-9bz^2 - y3.mul(t0) - y3.add(x3) //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2 - t1.copy(E.x) - t1.mul(iy) // - E.x.copy(t0) - E.x.norm() - E.x.mul(t1) - E.x.add(E.x) //(y^2-9bz^2)xy2 - - E.x.norm() - E.y.copy(y3) - E.y.norm() - - return 1 -} - -/* this+=Q - return 0 for add, 1 for double, -1 for O */ -func (E *ECP2) Add(Q *ECP2) int { - b := 3 * CURVE_B_I - t0 := NewFP2copy(E.x) - t0.mul(Q.x) // x.Q.x - t1 := NewFP2copy(E.y) - t1.mul(Q.y) // y.Q.y - - t2 := NewFP2copy(E.z) - t2.mul(Q.z) - t3 := NewFP2copy(E.x) - t3.add(E.y) - t3.norm() //t3=X1+Y1 - t4 := NewFP2copy(Q.x) - t4.add(Q.y) - t4.norm() //t4=X2+Y2 - t3.mul(t4) //t3=(X1+Y1)(X2+Y2) - t4.copy(t0) - t4.add(t1) //t4=X1.X2+Y1.Y2 - - t3.sub(t4) - t3.norm() - if SEXTIC_TWIST == D_TYPE { - t3.mul_ip() - t3.norm() //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1 - } - t4.copy(E.y) - t4.add(E.z) - t4.norm() //t4=Y1+Z1 - x3 := NewFP2copy(Q.y) - x3.add(Q.z) - x3.norm() //x3=Y2+Z2 - - t4.mul(x3) //t4=(Y1+Z1)(Y2+Z2) - x3.copy(t1) // - x3.add(t2) //X3=Y1.Y2+Z1.Z2 - - t4.sub(x3) - t4.norm() - if SEXTIC_TWIST == D_TYPE { - t4.mul_ip() - t4.norm() //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1 - } - x3.copy(E.x) - x3.add(E.z) - x3.norm() // x3=X1+Z1 - y3 := NewFP2copy(Q.x) - y3.add(Q.z) - y3.norm() // y3=X2+Z2 - x3.mul(y3) // x3=(X1+Z1)(X2+Z2) - y3.copy(t0) - y3.add(t2) // y3=X1.X2+Z1+Z2 - y3.rsub(x3) - y3.norm() // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1 - - if SEXTIC_TWIST == D_TYPE { - t0.mul_ip() - t0.norm() // x.Q.x - t1.mul_ip() - t1.norm() // y.Q.y - } - x3.copy(t0) - x3.add(t0) - t0.add(x3) - t0.norm() - t2.imul(b) - if SEXTIC_TWIST == M_TYPE { - t2.mul_ip() - t2.norm() - } - z3 := NewFP2copy(t1) - z3.add(t2) - z3.norm() - t1.sub(t2) - t1.norm() - y3.imul(b) - if SEXTIC_TWIST == M_TYPE { - y3.mul_ip() - y3.norm() - } - x3.copy(y3) - x3.mul(t4) - t2.copy(t3) - t2.mul(t1) - x3.rsub(t2) - y3.mul(t0) - t1.mul(z3) - y3.add(t1) - t0.mul(t3) - z3.mul(t4) - z3.add(t0) - - E.x.copy(x3) - E.x.norm() - E.y.copy(y3) - E.y.norm() - E.z.copy(z3) - E.z.norm() - - return 0 -} - -/* set this-=Q */ -func (E *ECP2) Sub(Q *ECP2) int { - NQ := NewECP2() - NQ.Copy(Q) - NQ.neg() - D := E.Add(NQ) - return D -} - -/* set this*=q, where q is Modulus, using Frobenius */ -func (E *ECP2) frob(X *FP2) { - X2 := NewFP2copy(X) - X2.sqr() - E.x.conj() - E.y.conj() - E.z.conj() - E.z.reduce() - E.x.mul(X2) - E.y.mul(X2) - E.y.mul(X) -} - -/* P*=e */ -func (E *ECP2) mul(e *BIG) *ECP2 { - /* fixed size windows */ - mt := NewBIG() - t := NewBIG() - P := NewECP2() - Q := NewECP2() - C := NewECP2() - - if E.Is_infinity() { - return NewECP2() - } - - var W []*ECP2 - var w [1 + (NLEN*int(BASEBITS)+3)/4]int8 - - /* precompute table */ - Q.Copy(E) - Q.dbl() - - W = append(W, NewECP2()) - W[0].Copy(E) - - for i := 1; i < 8; i++ { - W = append(W, NewECP2()) - W[i].Copy(W[i-1]) - W[i].Add(Q) - } - - /* make exponent odd - add 2P if even, P if odd */ - t.copy(e) - s := int(t.parity()) - t.inc(1) - t.norm() - ns := int(t.parity()) - mt.copy(t) - mt.inc(1) - mt.norm() - t.cmove(mt, s) - Q.cmove(E, ns) - C.Copy(Q) - - nb := 1 + (t.nbits()+3)/4 - /* convert exponent to signed 4-bit window */ - for i := 0; i < nb; i++ { - w[i] = int8(t.lastbits(5) - 16) - t.dec(int(w[i])) - t.norm() - t.fshr(4) - } - w[nb] = int8(t.lastbits(5)) - - P.Copy(W[(w[nb]-1)/2]) - for i := nb - 1; i >= 0; i-- { - Q.selector(W, int32(w[i])) - P.dbl() - P.dbl() - P.dbl() - P.dbl() - P.Add(Q) - } - P.Sub(C) - P.Affine() - return P -} - -/* Public version */ -func (E *ECP2) Mul(e *BIG) *ECP2 { - return E.mul(e) -} - - -/* clear cofactor */ -func (E *ECP2) Cfp() { - var T, K, xQ, x2Q *ECP2 - /* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */ - Fra := NewBIGints(Fra) - Frb := NewBIGints(Frb) - X := NewFP2bigs(Fra, Frb) - if SEXTIC_TWIST == M_TYPE { - X.inverse() - X.norm() - } - - x := NewBIGints(CURVE_Bnx) - - if CURVE_PAIRING_TYPE == BN { - T = NewECP2() - T.Copy(E) - T = T.mul(x) - if SIGN_OF_X == NEGATIVEX { - T.neg() - } - - K = NewECP2() - K.Copy(T) - K.dbl() - K.Add(T) - - K.frob(X) - E.frob(X) - E.frob(X) - E.frob(X) - E.Add(T) - E.Add(K) - T.frob(X) - T.frob(X) - E.Add(T) - } - if CURVE_PAIRING_TYPE == BLS { - xQ = E.mul(x) - x2Q = xQ.mul(x) - - if SIGN_OF_X == NEGATIVEX { - xQ.neg() - } - - x2Q.Sub(xQ) - x2Q.Sub(E) - - xQ.Sub(E) - xQ.frob(X) - - E.dbl() - E.frob(X) - E.frob(X) - - E.Add(x2Q) - E.Add(xQ) - } - E.Affine() -} - - -/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */ -// Bos & Costello https://eprint.iacr.org/2013/458.pdf -// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf -// Side channel attack secure -func mul4(Q []*ECP2, u []*BIG) *ECP2 { - W := NewECP2() - P := NewECP2() - var T []*ECP2 - mt := NewBIG() - var t []*BIG - - var w [NLEN*int(BASEBITS) + 1]int8 - var s [NLEN*int(BASEBITS) + 1]int8 - - for i := 0; i < 4; i++ { - t = append(t, NewBIGcopy(u[i])) - } - - T = append(T, NewECP2()) - T[0].Copy(Q[0]) // Q[0] - T = append(T, NewECP2()) - T[1].Copy(T[0]) - T[1].Add(Q[1]) // Q[0]+Q[1] - T = append(T, NewECP2()) - T[2].Copy(T[0]) - T[2].Add(Q[2]) // Q[0]+Q[2] - T = append(T, NewECP2()) - T[3].Copy(T[1]) - T[3].Add(Q[2]) // Q[0]+Q[1]+Q[2] - T = append(T, NewECP2()) - T[4].Copy(T[0]) - T[4].Add(Q[3]) // Q[0]+Q[3] - T = append(T, NewECP2()) - T[5].Copy(T[1]) - T[5].Add(Q[3]) // Q[0]+Q[1]+Q[3] - T = append(T, NewECP2()) - T[6].Copy(T[2]) - T[6].Add(Q[3]) // Q[0]+Q[2]+Q[3] - T = append(T, NewECP2()) - T[7].Copy(T[3]) - T[7].Add(Q[3]) // Q[0]+Q[1]+Q[2]+Q[3] - - // Make it odd - pb := 1 - t[0].parity() - t[0].inc(pb) - - // Number of bits - mt.zero() - for i := 0; i < 4; i++ { - t[i].norm() - mt.or(t[i]) - } - - nb := 1 + mt.nbits() - - // Sign pivot - s[nb-1] = 1 - for i := 0; i < nb-1; i++ { - t[0].fshr(1) - s[i] = 2*int8(t[0].parity()) - 1 - } - - // Recoded exponent - for i := 0; i < nb; i++ { - w[i] = 0 - k := 1 - for j := 1; j < 4; j++ { - bt := s[i] * int8(t[j].parity()) - t[j].fshr(1) - t[j].dec(int(bt) >> 1) - t[j].norm() - w[i] += bt * int8(k) - k *= 2 - } - } - - // Main loop - P.selector(T, int32(2*w[nb-1]+1)) - for i := nb - 2; i >= 0; i-- { - P.dbl() - W.selector(T, int32(2*w[i]+s[i])) - P.Add(W) - } - - // apply correction - W.Copy(P) - W.Sub(Q[0]) - P.cmove(W, pb) - - P.Affine() - return P -} - -/* Deterministic mapping of Fp to point on curve */ - func ECP2_hashit(h *BIG) *ECP2 { - // SWU method - W:=NewFP2int(1) - B := NewFP2big(NewBIGints(CURVE_B)) - t:=NewFPbig(h) - s:=NewFPint(-3) - one:=NewFPint(1) - if SEXTIC_TWIST == D_TYPE { - B.div_ip() - } - if SEXTIC_TWIST == M_TYPE { - B.mul_ip() - } - B.norm() - sgn:=t.sign() - w:=s.sqrt(nil) - j:=NewFPcopy(w); j.sub(one); j.norm(); j.div2() - - w.mul(t) - b:=NewFPcopy(t) - b.sqr() - b.add(one) - Y:=NewFP2fp(b) - B.add(Y); B.norm(); B.inverse() - B.pmul(w) - - X1:=NewFP2copy(B); X1.pmul(t) - Y.copy(NewFP2fp(j)) - X2:=NewFP2copy(X1); X2.sub(Y); X2.norm() - X1.copy(X2); X1.neg(); X1.norm() - X2.sub(W); X2.norm() - - B.sqr(); B.inverse() - X3:=NewFP2copy(B); X3.add(W); X3.norm() - - Y.copy(RHS2(X2)) - X1.cmove(X2,Y.qr()) - Y.copy(RHS2(X3)) - X1.cmove(X3,Y.qr()) - Y.copy(RHS2(X1)) - Y.sqrt() - - ne:=Y.sign()^sgn - W.copy(Y); W.neg(); W.norm() - Y.cmove(W,ne) - - return NewECP2fp2s(X1,Y); -} - -/* Map octet string to curve point */ -func ECP2_mapit(h []byte) *ECP2 { - q := NewBIGints(Modulus) - dx:=DBIG_fromBytes(h); - x:=dx.mod(q); - - Q:=ECP2_hashit(x) - Q.Cfp() - return Q -} - -func ECP2_generator() *ECP2 { - var G *ECP2 - G = NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa), NewBIGints(CURVE_Pxb)), NewFP2bigs(NewBIGints(CURVE_Pya), NewBIGints(CURVE_Pyb))) - return G -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/FP.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/FP.go deleted file mode 100644 index 4ccfec31a63..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/FP.go +++ /dev/null @@ -1,707 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* Finite Field arithmetic */ -/* CLINT mod p functions */ - -package FP256BN - - -type FP struct { - x *BIG - XES int32 -} - -/* Constructors */ - -func NewFP() *FP { - F := new(FP) - F.x = NewBIG() - F.XES = 1 - return F -} - -func NewFPint(a int) *FP { - F := new(FP) - if a < 0 { - m := NewBIGints(Modulus) - m.inc(a); m.norm(); - F.x = NewBIGcopy(m) - } else { - F.x = NewBIGint(a) - } - F.nres() - return F -} - -func NewFPbig(a *BIG) *FP { - F := new(FP) - F.x = NewBIGcopy(a) - F.nres() - return F -} - -func NewFPcopy(a *FP) *FP { - F := new(FP) - F.x = NewBIGcopy(a.x) - F.XES = a.XES - return F -} - -func (F *FP) toString() string { - F.reduce() - return F.redc().ToString() -} - -/* convert to Montgomery n-residue form */ -func (F *FP) nres() { - if MODTYPE != PSEUDO_MERSENNE && MODTYPE != GENERALISED_MERSENNE { - r := NewBIGints(R2modp) - d := mul(F.x, r) - F.x.copy(mod(d)) - F.XES = 2 - } else { - F.XES = 1 - } -} - -/* convert back to regular form */ -func (F *FP) redc() *BIG { - if MODTYPE != PSEUDO_MERSENNE && MODTYPE != GENERALISED_MERSENNE { - d := NewDBIGscopy(F.x) - return mod(d) - } else { - r := NewBIGcopy(F.x) - return r - } -} - -/* reduce a DBIG to a BIG using the appropriate form of the modulus */ - -func mod(d *DBIG) *BIG { - if MODTYPE == PSEUDO_MERSENNE { - t := d.split(MODBITS) - b := NewBIGdcopy(d) - - v := t.pmul(int(MConst)) - - t.add(b) - t.norm() - - tw := t.w[NLEN-1] - t.w[NLEN-1] &= TMASK - t.w[0] += (MConst * ((tw >> TBITS) + (v << (BASEBITS - TBITS)))) - - t.norm() - return t - } - if MODTYPE == MONTGOMERY_FRIENDLY { - for i := 0; i < NLEN; i++ { - top, bot := muladd(d.w[i], MConst-1, d.w[i], d.w[NLEN+i-1]) - d.w[NLEN+i-1] = bot - d.w[NLEN+i] += top - } - b := NewBIG() - - for i := 0; i < NLEN; i++ { - b.w[i] = d.w[NLEN+i] - } - b.norm() - return b - } - - if MODTYPE == GENERALISED_MERSENNE { // GoldiLocks only - t := d.split(MODBITS) - b := NewBIGdcopy(d) - b.add(t) - dd := NewDBIGscopy(t) - dd.shl(MODBITS / 2) - - tt := dd.split(MODBITS) - lo := NewBIGdcopy(dd) - b.add(tt) - b.add(lo) - b.norm() - tt.shl(MODBITS / 2) - b.add(tt) - - carry := b.w[NLEN-1] >> TBITS - b.w[NLEN-1] &= TMASK - b.w[0] += carry - - b.w[224/BASEBITS] += carry << (224 % BASEBITS) - b.norm() - return b - } - - if MODTYPE == NOT_SPECIAL { - md := NewBIGints(Modulus) - return monty(md, MConst, d) - } - return NewBIG() -} - -// find appoximation to quotient of a/m -// Out by at most 2. -// Note that MAXXES is bounded to be 2-bits less than half a word -func quo(n *BIG, m *BIG) int { - var num Chunk - var den Chunk - hb := uint(CHUNK) / 2 - if TBITS < hb { - sh := hb - TBITS - num = (n.w[NLEN-1] << sh) | (n.w[NLEN-2] >> (BASEBITS - sh)) - den = (m.w[NLEN-1] << sh) | (m.w[NLEN-2] >> (BASEBITS - sh)) - - } else { - num = n.w[NLEN-1] - den = m.w[NLEN-1] - } - return int(num / (den + 1)) -} - -/* reduce this mod Modulus */ -func (F *FP) reduce() { - m := NewBIGints(Modulus) - r := NewBIGints(Modulus) - var sb uint - F.x.norm() - - if F.XES > 16 { - q := quo(F.x, m) - carry := r.pmul(q) - r.w[NLEN-1] += carry << BASEBITS - F.x.sub(r) - F.x.norm() - sb = 2 - } else { - sb = logb2(uint32(F.XES - 1)) - } - - m.fshl(sb) - for sb > 0 { - sr := ssn(r, F.x, m) - F.x.cmove(r, 1-sr) - sb -= 1 - } - - F.XES = 1 -} - -/* test this=0? */ -func (F *FP) iszilch() bool { - W := NewFPcopy(F) - W.reduce() - return W.x.iszilch() -} - -func (F *FP) isunity() bool { - W:=NewFPcopy(F) - W.reduce() - return W.redc().isunity() -} - -/* copy from FP b */ -func (F *FP) copy(b *FP) { - F.x.copy(b.x) - F.XES = b.XES -} - -/* set this=0 */ -func (F *FP) zero() { - F.x.zero() - F.XES = 1 -} - -/* set this=1 */ -func (F *FP) one() { - F.x.one() - F.nres() -} - -/* return sign */ -func (F *FP) sign() int { - W:=NewFPcopy(F) - W.reduce() - return W.redc().parity() -} - -/* normalise this */ -func (F *FP) norm() { - F.x.norm() -} - -/* swap FPs depending on d */ -func (F *FP) cswap(b *FP, d int) { - c := int32(d) - c = ^(c - 1) - t := c & (F.XES ^ b.XES) - F.XES ^= t - b.XES ^= t - F.x.cswap(b.x, d) -} - -/* copy FPs depending on d */ -func (F *FP) cmove(b *FP, d int) { - F.x.cmove(b.x, d) - c := int32(-d) - F.XES ^= (F.XES ^ b.XES) & c -} - -/* this*=b mod Modulus */ -func (F *FP) mul(b *FP) { - - if int64(F.XES)*int64(b.XES) > int64(FEXCESS) { - F.reduce() - } - - d := mul(F.x, b.x) - F.x.copy(mod(d)) - F.XES = 2 -} - -/* this = -this mod Modulus */ -func (F *FP) neg() { - m := NewBIGints(Modulus) - sb := logb2(uint32(F.XES - 1)) - - m.fshl(sb) - F.x.rsub(m) - - F.XES = (1 << sb) + 1 - if F.XES > FEXCESS { - F.reduce() - } -} - -/* this*=c mod Modulus, where c is a small int */ -func (F *FP) imul(c int) { - // F.norm() - s := false - if c < 0 { - c = -c - s = true - } - - if MODTYPE == PSEUDO_MERSENNE || MODTYPE == GENERALISED_MERSENNE { - d := F.x.pxmul(c) - F.x.copy(mod(d)) - F.XES = 2 - } else { - if F.XES*int32(c) <= FEXCESS { - F.x.pmul(c) - F.XES *= int32(c) - } else { - n := NewFPint(c) - F.mul(n) - } - } - if s { - F.neg() - F.norm() - } -} - -/* this*=this mod Modulus */ -func (F *FP) sqr() { - if int64(F.XES)*int64(F.XES) > int64(FEXCESS) { - F.reduce() - } - d := sqr(F.x) - F.x.copy(mod(d)) - F.XES = 2 -} - -/* this+=b */ -func (F *FP) add(b *FP) { - F.x.add(b.x) - F.XES += b.XES - if F.XES > FEXCESS { - F.reduce() - } -} - -/* this-=b */ -func (F *FP) sub(b *FP) { - n := NewFPcopy(b) - n.neg() - F.add(n) -} - -func (F *FP) rsub(b *FP) { - F.neg() - F.add(b) -} - -/* this/=2 mod Modulus */ -func (F *FP) div2() { - p:=NewBIGints(Modulus) - pr:=F.x.parity() - w:=NewBIGcopy(F.x) - F.x.fshr(1) - w.add(p); w.norm() - w.fshr(1) - F.x.cmove(w,pr) -} - - -/* return jacobi symbol (this/Modulus) */ -func (F *FP) jacobi() int { - w := F.redc() - p := NewBIGints(Modulus) - return w.Jacobi(p) -} - -/* return TRUE if this==a */ -func (F *FP) Equals(a *FP) bool { - f := NewFPcopy(F) - s := NewFPcopy(a) - - s.reduce() - f.reduce() - if Comp(s.x, f.x) == 0 { - return true - } - return false -} - -func (F *FP) pow(e *BIG) *FP { - var tb []*FP - var w [1 + (NLEN*int(BASEBITS)+3)/4]int8 - F.norm() - t := NewBIGcopy(e) - t.norm() - nb := 1 + (t.nbits()+3)/4 - - for i := 0; i < nb; i++ { - lsbs := t.lastbits(4) - t.dec(lsbs) - t.norm() - w[i] = int8(lsbs) - t.fshr(4) - } - tb = append(tb, NewFPint(1)) - tb = append(tb, NewFPcopy(F)) - for i := 2; i < 16; i++ { - tb = append(tb, NewFPcopy(tb[i-1])) - tb[i].mul(F) - } - r := NewFPcopy(tb[w[nb-1]]) - for i := nb - 2; i >= 0; i-- { - r.sqr() - r.sqr() - r.sqr() - r.sqr() - r.mul(tb[w[i]]) - } - r.reduce() - return r -} - -// See https://eprint.iacr.org/2018/1038 -// return this^(p-3)/4 or this^(p-5)/8 -func (F *FP) fpow() *FP { - ac := [11]int{1, 2, 3, 6, 12, 15, 30, 60, 120, 240, 255} - var xp []*FP - // phase 1 - xp = append(xp, NewFPcopy(F)) - xp = append(xp, NewFPcopy(F)) - xp[1].sqr() - xp = append(xp, NewFPcopy(xp[1])) - xp[2].mul(F) - xp = append(xp, NewFPcopy(xp[2])) - xp[3].sqr() - xp = append(xp, NewFPcopy(xp[3])) - xp[4].sqr() - xp = append(xp, NewFPcopy(xp[4])) - xp[5].mul(xp[2]) - xp = append(xp, NewFPcopy(xp[5])) - xp[6].sqr() - xp = append(xp, NewFPcopy(xp[6])) - xp[7].sqr() - xp = append(xp, NewFPcopy(xp[7])) - xp[8].sqr() - xp = append(xp, NewFPcopy(xp[8])) - xp[9].sqr() - xp = append(xp, NewFPcopy(xp[9])) - xp[10].mul(xp[5]) - var n, c int - - e := int(PM1D2) - - n = int(MODBITS) - if MODTYPE == GENERALISED_MERSENNE { // Goldilocks ONLY - n /= 2 - } - - n-=(e+1) - c=(int(MConst)+(1< k { - i-- - } - key.copy(xp[i]) - k -= ac[i] - } - - for k != 0 { - i-- - if ac[i] > k { - continue - } - key.mul(xp[i]) - k -= ac[i] - } - // phase 2 - xp[1].copy(xp[2]) - xp[2].copy(xp[5]) - xp[3].copy(xp[10]) - - j := 3 - m := 8 - nw := n - bw - t := NewFP() - for 2*m < nw { - t.copy(xp[j]) - j++ - for i = 0; i < m; i++ { - t.sqr() - } - xp[j].copy(xp[j-1]) - xp[j].mul(t) - m *= 2 - } - lo := nw - m - r := NewFPcopy(xp[j]) - - for lo != 0 { - m /= 2 - j-- - if lo < m { - continue - } - lo -= m - t.copy(r) - for i = 0; i < m; i++ { - t.sqr() - } - r.copy(t) - r.mul(xp[j]) - } - // phase 3 - if bw != 0 { - for i = 0; i < bw; i++ { - r.sqr() - } - r.mul(key) - } - - if MODTYPE == GENERALISED_MERSENNE { // Goldilocks ONLY - key.copy(r) - r.sqr() - r.mul(F) - for i = 0; i < n+1; i++ { - r.sqr() - } - r.mul(key) - } - - return r -} - -// calculates r=x^(p-1-2^e)/2^{e+1) where 2^e|p-1 -func (F *FP) invsqrt() { - if (MODTYPE == PSEUDO_MERSENNE || MODTYPE == GENERALISED_MERSENNE) { - F.copy(F.fpow()) - return - } - e:=uint(PM1D2) - m := NewBIGints(Modulus) - m.dec(1); - m.shr(e); - m.dec(1); - m.fshr(1); - F.copy(F.pow(m)); -} - -/* this=1/this mod Modulus */ -func (F *FP) inverse() { - e:=int(PM1D2) - F.norm() - s:=NewFPcopy(F) - for i:=0;i1;k-- { - for j:=1;j. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* MiotCL Fp^12 functions */ -/* FP12 elements are of the form a+i.b+i^2.c */ - -package FP256BN - - - -type FP12 struct { - a *FP4 - b *FP4 - c *FP4 - stype int -} - -/* Constructors */ -func NewFP12fp4(d *FP4) *FP12 { - F := new(FP12) - F.a = NewFP4copy(d) - F.b = NewFP4() - F.c = NewFP4() - F.stype = FP_SPARSEST - return F -} - -func NewFP12() *FP12 { - F := new(FP12) - F.a = NewFP4() - F.b = NewFP4() - F.c = NewFP4() - F.stype = FP_ZERO - - return F -} - -func NewFP12int(d int) *FP12 { - F := new(FP12) - F.a = NewFP4int(d) - F.b = NewFP4() - F.c = NewFP4() - if d == 1 { - F.stype = FP_ONE - } else { - F.stype = FP_SPARSEST - } - return F -} - -func NewFP12fp4s(d *FP4, e *FP4, f *FP4) *FP12 { - F := new(FP12) - F.a = NewFP4copy(d) - F.b = NewFP4copy(e) - F.c = NewFP4copy(f) - F.stype = FP_DENSE - return F -} - -func NewFP12copy(x *FP12) *FP12 { - F := new(FP12) - F.a = NewFP4copy(x.a) - F.b = NewFP4copy(x.b) - F.c = NewFP4copy(x.c) - F.stype = x.stype - return F -} - -/* reduce all components of this mod Modulus */ -func (F *FP12) reduce() { - F.a.reduce() - F.b.reduce() - F.c.reduce() -} - -/* normalise all components of this */ -func (F *FP12) norm() { - F.a.norm() - F.b.norm() - F.c.norm() -} - -/* test x==0 ? */ -func (F *FP12) iszilch() bool { - return (F.a.iszilch() && F.b.iszilch() && F.c.iszilch()) -} - -/* Conditional move */ -func (F *FP12) cmove(g *FP12, d int) { - F.a.cmove(g.a, d) - F.b.cmove(g.b, d) - F.c.cmove(g.c, d) - d = ^(d - 1) - F.stype ^= (F.stype ^ g.stype) & d -} - -/* Constant time select from pre-computed table */ -func (F *FP12) selector(g []*FP12, b int32) { - - m := b >> 31 - babs := (b ^ m) - m - - babs = (babs - 1) / 2 - - F.cmove(g[0], teq(babs, 0)) // conditional move - F.cmove(g[1], teq(babs, 1)) - F.cmove(g[2], teq(babs, 2)) - F.cmove(g[3], teq(babs, 3)) - F.cmove(g[4], teq(babs, 4)) - F.cmove(g[5], teq(babs, 5)) - F.cmove(g[6], teq(babs, 6)) - F.cmove(g[7], teq(babs, 7)) - - invF := NewFP12copy(F) - invF.conj() - F.cmove(invF, int(m&1)) -} - -/* test x==1 ? */ -func (F *FP12) Isunity() bool { - one := NewFP4int(1) - return (F.a.Equals(one) && F.b.iszilch() && F.c.iszilch()) -} - -/* return 1 if x==y, else 0 */ -func (F *FP12) Equals(x *FP12) bool { - return (F.a.Equals(x.a) && F.b.Equals(x.b) && F.c.Equals(x.c)) -} - -/* extract a from this */ -func (F *FP12) geta() *FP4 { - return F.a -} - -/* extract b */ -func (F *FP12) getb() *FP4 { - return F.b -} - -/* extract c */ -func (F *FP12) getc() *FP4 { - return F.c -} - -/* copy this=x */ -func (F *FP12) Copy(x *FP12) { - F.a.copy(x.a) - F.b.copy(x.b) - F.c.copy(x.c) - F.stype = x.stype -} - -/* set this=1 */ -func (F *FP12) one() { - F.a.one() - F.b.zero() - F.c.zero() - F.stype = FP_ONE -} - -/* set this=0 */ -func (F *FP12) zero() { - F.a.zero() - F.b.zero() - F.c.zero() - F.stype = FP_ZERO -} - -/* this=conj(this) */ -func (F *FP12) conj() { - F.a.conj() - F.b.nconj() - F.c.conj() -} - -/* Granger-Scott Unitary Squaring */ -func (F *FP12) usqr() { - A := NewFP4copy(F.a) - B := NewFP4copy(F.c) - C := NewFP4copy(F.b) - D := NewFP4() - - F.a.sqr() - D.copy(F.a) - D.add(F.a) - F.a.add(D) - - F.a.norm() - A.nconj() - - A.add(A) - F.a.add(A) - B.sqr() - B.times_i() - - D.copy(B) - D.add(B) - B.add(D) - B.norm() - - C.sqr() - D.copy(C) - D.add(C) - C.add(D) - C.norm() - - F.b.conj() - F.b.add(F.b) - F.c.nconj() - - F.c.add(F.c) - F.b.add(B) - F.c.add(C) - F.reduce() - F.stype = FP_DENSE - -} - -/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */ -func (F *FP12) sqr() { - if F.stype == FP_ONE { - return - } - - A := NewFP4copy(F.a) - B := NewFP4copy(F.b) - C := NewFP4copy(F.c) - D := NewFP4copy(F.a) - - A.sqr() - B.mul(F.c) - B.add(B) - B.norm() - C.sqr() - D.mul(F.b) - D.add(D) - - F.c.add(F.a) - F.c.add(F.b) - F.c.norm() - F.c.sqr() - - F.a.copy(A) - - A.add(B) - A.norm() - A.add(C) - A.add(D) - A.norm() - - A.neg() - B.times_i() - C.times_i() - - F.a.add(B) - - F.b.copy(C) - F.b.add(D) - F.c.add(A) - if F.stype == FP_SPARSER || F.stype == FP_SPARSEST { - F.stype = FP_SPARSE - } else { - F.stype = FP_DENSE - } - F.norm() -} - -/* FP12 full multiplication this=this*y */ -func (F *FP12) Mul(y *FP12) { - z0 := NewFP4copy(F.a) - z1 := NewFP4() - z2 := NewFP4copy(F.b) - z3 := NewFP4() - t0 := NewFP4copy(F.a) - t1 := NewFP4copy(y.a) - - z0.mul(y.a) - z2.mul(y.b) - - t0.add(F.b) - t0.norm() - t1.add(y.b) - t1.norm() - - z1.copy(t0) - z1.mul(t1) - t0.copy(F.b) - t0.add(F.c) - t0.norm() - - t1.copy(y.b) - t1.add(y.c) - t1.norm() - z3.copy(t0) - z3.mul(t1) - - t0.copy(z0) - t0.neg() - t1.copy(z2) - t1.neg() - - z1.add(t0) - F.b.copy(z1) - F.b.add(t1) - - z3.add(t1) - z2.add(t0) - - t0.copy(F.a) - t0.add(F.c) - t0.norm() - t1.copy(y.a) - t1.add(y.c) - t1.norm() - t0.mul(t1) - z2.add(t0) - - t0.copy(F.c) - t0.mul(y.c) - t1.copy(t0) - t1.neg() - - F.c.copy(z2) - F.c.add(t1) - z3.add(t1) - t0.times_i() - F.b.add(t0) - z3.norm() - z3.times_i() - F.a.copy(z0) - F.a.add(z3) - F.stype = FP_DENSE - F.norm() -} - -/* FP12 full multiplication w=w*y */ -/* Supports sparse multiplicands */ -/* Usually w is denser than y */ -func (F *FP12) ssmul(y *FP12) { - if F.stype == FP_ONE { - F.Copy(y) - return - } - if y.stype == FP_ONE { - return - } - if y.stype >= FP_SPARSE { - z0 := NewFP4copy(F.a) - z1 := NewFP4() - z2 := NewFP4() - z3 := NewFP4() - z0.mul(y.a) - - if SEXTIC_TWIST == M_TYPE { - if y.stype == FP_SPARSE || F.stype == FP_SPARSE { - z2.getb().copy(F.b.getb()) - z2.getb().mul(y.b.getb()) - z2.geta().zero() - if y.stype != FP_SPARSE { - z2.geta().copy(F.b.getb()) - z2.geta().mul(y.b.geta()) - } - if F.stype != FP_SPARSE { - z2.geta().copy(F.b.geta()) - z2.geta().mul(y.b.getb()) - } - z2.times_i() - } else { - z2.copy(F.b) - z2.mul(y.b) - } - } else { - z2.copy(F.b) - z2.mul(y.b) - } - t0 := NewFP4copy(F.a) - t1 := NewFP4copy(y.a) - t0.add(F.b) - t0.norm() - t1.add(y.b) - t1.norm() - - z1.copy(t0) - z1.mul(t1) - t0.copy(F.b) - t0.add(F.c) - t0.norm() - t1.copy(y.b) - t1.add(y.c) - t1.norm() - - z3.copy(t0) - z3.mul(t1) - - t0.copy(z0) - t0.neg() - t1.copy(z2) - t1.neg() - - z1.add(t0) - F.b.copy(z1) - F.b.add(t1) - - z3.add(t1) - z2.add(t0) - - t0.copy(F.a) - t0.add(F.c) - t0.norm() - t1.copy(y.a) - t1.add(y.c) - t1.norm() - - t0.mul(t1) - z2.add(t0) - - if SEXTIC_TWIST == D_TYPE { - if y.stype == FP_SPARSE || F.stype == FP_SPARSE { - t0.geta().copy(F.c.geta()) - t0.geta().mul(y.c.geta()) - t0.getb().zero() - if y.stype != FP_SPARSE { - t0.getb().copy(F.c.geta()) - t0.getb().mul(y.c.getb()) - } - if F.stype != FP_SPARSE { - t0.getb().copy(F.c.getb()) - t0.getb().mul(y.c.geta()) - } - } else { - t0.copy(F.c) - t0.mul(y.c) - } - } else { - t0.copy(F.c) - t0.mul(y.c) - } - t1.copy(t0) - t1.neg() - - F.c.copy(z2) - F.c.add(t1) - z3.add(t1) - t0.times_i() - F.b.add(t0) - z3.norm() - z3.times_i() - F.a.copy(z0) - F.a.add(z3) - } else { - if F.stype == FP_SPARSER || F.stype == FP_SPARSEST { - F.smul(y) - return - } - if SEXTIC_TWIST == D_TYPE { // dense by sparser - 13m - z0 := NewFP4copy(F.a) - z2 := NewFP4copy(F.b) - z3 := NewFP4copy(F.b) - t0 := NewFP4() - t1 := NewFP4copy(y.a) - z0.mul(y.a) - - if y.stype == FP_SPARSEST { - z2.qmul(y.b.a.a) - } else { - z2.pmul(y.b.a) - } - F.b.add(F.a) - t1.geta().add(y.b.geta()) - - t1.norm() - F.b.norm() - F.b.mul(t1) - z3.add(F.c) - z3.norm() - - if y.stype == FP_SPARSEST { - z3.qmul(y.b.a.a) - } else { - z3.pmul(y.b.a) - } - - t0.copy(z0) - t0.neg() - t1.copy(z2) - t1.neg() - - F.b.add(t0) - - F.b.add(t1) - z3.add(t1) - z2.add(t0) - - t0.copy(F.a) - t0.add(F.c) - t0.norm() - z3.norm() - t0.mul(y.a) - F.c.copy(z2) - F.c.add(t0) - - z3.times_i() - F.a.copy(z0) - F.a.add(z3) - } - if SEXTIC_TWIST == M_TYPE { - z0 := NewFP4copy(F.a) - z1 := NewFP4() - z2 := NewFP4() - z3 := NewFP4() - t0 := NewFP4copy(F.a) - t1 := NewFP4() - - z0.mul(y.a) - t0.add(F.b) - t0.norm() - - z1.copy(t0) - z1.mul(y.a) - t0.copy(F.b) - t0.add(F.c) - t0.norm() - - z3.copy(t0) - - if y.stype == FP_SPARSEST { - z3.qmul(y.c.b.a) - } else { - z3.pmul(y.c.b) - } - z3.times_i() - - t0.copy(z0) - t0.neg() - z1.add(t0) - F.b.copy(z1) - z2.copy(t0) - - t0.copy(F.a) - t0.add(F.c) - t0.norm() - t1.copy(y.a) - t1.add(y.c) - t1.norm() - - t0.mul(t1) - z2.add(t0) - t0.copy(F.c) - - if y.stype == FP_SPARSEST { - t0.qmul(y.c.b.a) - } else { - t0.pmul(y.c.b) - } - t0.times_i() - t1.copy(t0) - t1.neg() - - F.c.copy(z2) - F.c.add(t1) - z3.add(t1) - t0.times_i() - F.b.add(t0) - z3.norm() - z3.times_i() - F.a.copy(z0) - F.a.add(z3) - } - } - F.stype = FP_DENSE - F.norm() -} - -/* Special case of multiplication arises from special form of ATE pairing line function */ -/* F and y are both sparser or sparsest line functions - cost <= 6m */ -func (F *FP12) smul(y *FP12) { - if SEXTIC_TWIST == D_TYPE { - w1 := NewFP2copy(F.a.geta()) - w2 := NewFP2copy(F.a.getb()) - var w3 *FP2 - - w1.mul(y.a.geta()) - w2.mul(y.a.getb()) - - if y.stype == FP_SPARSEST || F.stype == FP_SPARSEST { - if y.stype == FP_SPARSEST && F.stype == FP_SPARSEST { - t := NewFPcopy(F.b.a.a) - t.mul(y.b.a.a) - w3 = NewFP2fp(t) - } else { - if y.stype != FP_SPARSEST { - w3 = NewFP2copy(y.b.geta()) - w3.pmul(F.b.a.a) - } else { - w3 = NewFP2copy(F.b.geta()) - w3.pmul(y.b.a.a) - } - } - } else { - w3 = NewFP2copy(F.b.geta()) - w3.mul(y.b.geta()) - } - - ta := NewFP2copy(F.a.geta()) - tb := NewFP2copy(y.a.geta()) - ta.add(F.a.getb()) - ta.norm() - tb.add(y.a.getb()) - tb.norm() - tc := NewFP2copy(ta) - tc.mul(tb) - t := NewFP2copy(w1) - t.add(w2) - t.neg() - tc.add(t) - - ta.copy(F.a.geta()) - ta.add(F.b.geta()) - ta.norm() - tb.copy(y.a.geta()) - tb.add(y.b.geta()) - tb.norm() - td := NewFP2copy(ta) - td.mul(tb) - t.copy(w1) - t.add(w3) - t.neg() - td.add(t) - - ta.copy(F.a.getb()) - ta.add(F.b.geta()) - ta.norm() - tb.copy(y.a.getb()) - tb.add(y.b.geta()) - tb.norm() - te := NewFP2copy(ta) - te.mul(tb) - t.copy(w2) - t.add(w3) - t.neg() - te.add(t) - - w2.mul_ip() - w1.add(w2) - - F.a.geta().copy(w1) - F.a.getb().copy(tc) - F.b.geta().copy(td) - F.b.getb().copy(te) - F.c.geta().copy(w3) - F.c.getb().zero() - - F.a.norm() - F.b.norm() - } else { - w1 := NewFP2copy(F.a.geta()) - w2 := NewFP2copy(F.a.getb()) - var w3 *FP2 - - w1.mul(y.a.geta()) - w2.mul(y.a.getb()) - - if y.stype == FP_SPARSEST || F.stype == FP_SPARSEST { - if y.stype == FP_SPARSEST && F.stype == FP_SPARSEST { - t := NewFPcopy(F.c.b.a) - t.mul(y.c.b.a) - w3 = NewFP2fp(t) - } else { - if y.stype != FP_SPARSEST { - w3 = NewFP2copy(y.c.getb()) - w3.pmul(F.c.b.a) - } else { - w3 = NewFP2copy(F.c.getb()) - w3.pmul(y.c.b.a) - } - } - } else { - w3 = NewFP2copy(F.c.getb()) - w3.mul(y.c.getb()) - } - - ta := NewFP2copy(F.a.geta()) - tb := NewFP2copy(y.a.geta()) - ta.add(F.a.getb()) - ta.norm() - tb.add(y.a.getb()) - tb.norm() - tc := NewFP2copy(ta) - tc.mul(tb) - t := NewFP2copy(w1) - t.add(w2) - t.neg() - tc.add(t) - - ta.copy(F.a.geta()) - ta.add(F.c.getb()) - ta.norm() - tb.copy(y.a.geta()) - tb.add(y.c.getb()) - tb.norm() - td := NewFP2copy(ta) - td.mul(tb) - t.copy(w1) - t.add(w3) - t.neg() - td.add(t) - - ta.copy(F.a.getb()) - ta.add(F.c.getb()) - ta.norm() - tb.copy(y.a.getb()) - tb.add(y.c.getb()) - tb.norm() - te := NewFP2copy(ta) - te.mul(tb) - t.copy(w2) - t.add(w3) - t.neg() - te.add(t) - - w2.mul_ip() - w1.add(w2) - F.a.geta().copy(w1) - F.a.getb().copy(tc) - - w3.mul_ip() - w3.norm() - F.b.geta().zero() - F.b.getb().copy(w3) - - te.norm() - te.mul_ip() - F.c.geta().copy(te) - F.c.getb().copy(td) - - F.a.norm() - F.c.norm() - - } - F.stype = FP_SPARSE -} - -/* this=1/this */ -func (F *FP12) Inverse() { - f0 := NewFP4copy(F.a) - f1 := NewFP4copy(F.b) - f2 := NewFP4copy(F.a) - f3 := NewFP4() - - F.norm() - f0.sqr() - f1.mul(F.c) - f1.times_i() - f0.sub(f1) - f0.norm() - - f1.copy(F.c) - f1.sqr() - f1.times_i() - f2.mul(F.b) - f1.sub(f2) - f1.norm() - - f2.copy(F.b) - f2.sqr() - f3.copy(F.a) - f3.mul(F.c) - f2.sub(f3) - f2.norm() - - f3.copy(F.b) - f3.mul(f2) - f3.times_i() - F.a.mul(f0) - f3.add(F.a) - F.c.mul(f1) - F.c.times_i() - - f3.add(F.c) - f3.norm() - f3.inverse() - F.a.copy(f0) - F.a.mul(f3) - F.b.copy(f1) - F.b.mul(f3) - F.c.copy(f2) - F.c.mul(f3) - F.stype = FP_DENSE -} - -/* this=this^p using Frobenius */ -func (F *FP12) frob(f *FP2) { - f2 := NewFP2copy(f) - f3 := NewFP2copy(f) - - f2.sqr() - f3.mul(f2) - - F.a.frob(f3) - F.b.frob(f3) - F.c.frob(f3) - - F.b.pmul(f) - F.c.pmul(f2) - F.stype = FP_DENSE -} - -/* trace function */ -func (F *FP12) trace() *FP4 { - t := NewFP4() - t.copy(F.a) - t.imul(3) - t.reduce() - return t -} - -/* convert from byte array to FP12 */ -func FP12_fromBytes(w []byte) *FP12 { - var t [int(MODBYTES)]byte - MB := int(MODBYTES) - - for i := 0; i < MB; i++ { - t[i] = w[i] - } - a := FromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+MB] - } - b := FromBytes(t[:]) - c := NewFP2bigs(a, b) - - for i := 0; i < MB; i++ { - t[i] = w[i+2*MB] - } - a = FromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+3*MB] - } - b = FromBytes(t[:]) - d := NewFP2bigs(a, b) - - e := NewFP4fp2s(c, d) - - for i := 0; i < MB; i++ { - t[i] = w[i+4*MB] - } - a = FromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+5*MB] - } - b = FromBytes(t[:]) - c = NewFP2bigs(a, b) - - for i := 0; i < MB; i++ { - t[i] = w[i+6*MB] - } - a = FromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+7*MB] - } - b = FromBytes(t[:]) - d = NewFP2bigs(a, b) - - f := NewFP4fp2s(c, d) - - for i := 0; i < MB; i++ { - t[i] = w[i+8*MB] - } - a = FromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+9*MB] - } - b = FromBytes(t[:]) - - c = NewFP2bigs(a, b) - - for i := 0; i < MB; i++ { - t[i] = w[i+10*MB] - } - a = FromBytes(t[:]) - for i := 0; i < MB; i++ { - t[i] = w[i+11*MB] - } - b = FromBytes(t[:]) - d = NewFP2bigs(a, b) - - g := NewFP4fp2s(c, d) - - return NewFP12fp4s(e, f, g) -} - -/* convert this to byte array */ -func (F *FP12) ToBytes(w []byte) { - var t [int(MODBYTES)]byte - MB := int(MODBYTES) - F.a.geta().GetA().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i] = t[i] - } - F.a.geta().GetB().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+MB] = t[i] - } - F.a.getb().GetA().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+2*MB] = t[i] - } - F.a.getb().GetB().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+3*MB] = t[i] - } - - F.b.geta().GetA().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+4*MB] = t[i] - } - F.b.geta().GetB().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+5*MB] = t[i] - } - F.b.getb().GetA().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+6*MB] = t[i] - } - F.b.getb().GetB().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+7*MB] = t[i] - } - - F.c.geta().GetA().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+8*MB] = t[i] - } - F.c.geta().GetB().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+9*MB] = t[i] - } - F.c.getb().GetA().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+10*MB] = t[i] - } - F.c.getb().GetB().ToBytes(t[:]) - for i := 0; i < MB; i++ { - w[i+11*MB] = t[i] - } -} - -/* convert to hex string */ -func (F *FP12) ToString() string { - return ("[" + F.a.toString() + "," + F.b.toString() + "," + F.c.toString() + "]") -} - -/* this=this^e */ -func (F *FP12) Pow(e *BIG) *FP12 { - //F.norm() - e1 := NewBIGcopy(e) - e1.norm() - e3 := NewBIGcopy(e1) - e3.pmul(3) - e3.norm() - sf := NewFP12copy(F) - sf.norm() - w := NewFP12copy(sf) - - nb := e3.nbits() - for i := nb - 2; i >= 1; i-- { - w.usqr() - bt := e3.bit(i) - e1.bit(i) - if bt == 1 { - w.Mul(sf) - } - if bt == -1 { - sf.conj() - w.Mul(sf) - sf.conj() - } - } - w.reduce() - return w -} - -/* constant time powering by small integer of max length bts */ -func (F *FP12) pinpow(e int, bts int) { - var R []*FP12 - R = append(R, NewFP12int(1)) - R = append(R, NewFP12copy(F)) - - for i := bts - 1; i >= 0; i-- { - b := (e >> uint(i)) & 1 - R[1-b].Mul(R[b]) - R[b].usqr() - } - F.Copy(R[0]) -} - -/* Fast compressed FP4 power of unitary FP12 */ -func (F *FP12) Compow(e *BIG, r *BIG) *FP4 { - q := NewBIGints(Modulus) - f := NewFP2bigs(NewBIGints(Fra), NewBIGints(Frb)) - - m := NewBIGcopy(q) - m.Mod(r) - - a := NewBIGcopy(e) - a.Mod(m) - - b := NewBIGcopy(e) - b.div(m) - - g1 := NewFP12copy(F) - c := g1.trace() - - if b.iszilch() { - c = c.xtr_pow(e) - return c - } - - g2 := NewFP12copy(F) - g2.frob(f) - cp := g2.trace() - - g1.conj() - g2.Mul(g1) - cpm1 := g2.trace() - g2.Mul(g1) - cpm2 := g2.trace() - - c = c.xtr_pow2(cp, cpm1, cpm2, a, b) - return c -} - -/* p=q0^u0.q1^u1.q2^u2.q3^u3 */ -// Bos & Costello https://eprint.iacr.org/2013/458.pdf -// Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf -// Side channel attack secure - -func pow4(q []*FP12, u []*BIG) *FP12 { - var g []*FP12 - var w [NLEN*int(BASEBITS) + 1]int8 - var s [NLEN*int(BASEBITS) + 1]int8 - var t []*BIG - r := NewFP12() - p := NewFP12() - mt := NewBIGint(0) - - for i := 0; i < 4; i++ { - t = append(t, NewBIGcopy(u[i])) - } - - g = append(g, NewFP12copy(q[0])) // q[0] - g = append(g, NewFP12copy(g[0])) - g[1].Mul(q[1]) // q[0].q[1] - g = append(g, NewFP12copy(g[0])) - g[2].Mul(q[2]) // q[0].q[2] - g = append(g, NewFP12copy(g[1])) - g[3].Mul(q[2]) // q[0].q[1].q[2] - g = append(g, NewFP12copy(g[0])) - g[4].Mul(q[3]) // q[0].q[3] - g = append(g, NewFP12copy(g[1])) - g[5].Mul(q[3]) // q[0].q[1].q[3] - g = append(g, NewFP12copy(g[2])) - g[6].Mul(q[3]) // q[0].q[2].q[3] - g = append(g, NewFP12copy(g[3])) - g[7].Mul(q[3]) // q[0].q[1].q[2].q[3] - - // Make it odd - pb := 1 - t[0].parity() - t[0].inc(pb) - // t[0].norm(); - - // Number of bits - mt.zero() - for i := 0; i < 4; i++ { - t[i].norm() - mt.or(t[i]) - } - - nb := 1 + mt.nbits() - - // Sign pivot - s[nb-1] = 1 - for i := 0; i < nb-1; i++ { - t[0].fshr(1) - s[i] = 2*int8(t[0].parity()) - 1 - } - - // Recoded exponent - for i := 0; i < nb; i++ { - w[i] = 0 - k := 1 - for j := 1; j < 4; j++ { - bt := s[i] * int8(t[j].parity()) - t[j].fshr(1) - t[j].dec(int(bt) >> 1) - t[j].norm() - w[i] += bt * int8(k) - k *= 2 - } - } - - // Main loop - p.selector(g, int32(2*w[nb-1]+1)) - for i := nb - 2; i >= 0; i-- { - p.usqr() - r.selector(g, int32(2*w[i]+s[i])) - p.Mul(r) - } - - // apply correction - r.Copy(q[0]) - r.conj() - r.Mul(p) - p.cmove(r, pb) - - p.reduce() - return p -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/FP2.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/FP2.go deleted file mode 100644 index e308c4d502e..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/FP2.go +++ /dev/null @@ -1,412 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* Finite Field arithmetic Fp^2 functions */ - -/* FP2 elements are of the form a+ib, where i is sqrt(-1) */ - -package FP256BN - - - -type FP2 struct { - a *FP - b *FP -} - -func NewFP2() *FP2 { - F := new(FP2) - F.a = NewFP() - F.b = NewFP() - return F -} - -/* Constructors */ -func NewFP2int(a int) *FP2 { - F := new(FP2) - F.a = NewFPint(a) - F.b = NewFP() - return F -} - -func NewFP2ints(a int, b int) *FP2 { - F := new(FP2) - F.a = NewFPint(a) - F.b = NewFPint(b) - return F -} - -func NewFP2copy(x *FP2) *FP2 { - F := new(FP2) - F.a = NewFPcopy(x.a) - F.b = NewFPcopy(x.b) - return F -} - -func NewFP2fps(c *FP, d *FP) *FP2 { - F := new(FP2) - F.a = NewFPcopy(c) - F.b = NewFPcopy(d) - return F -} - -func NewFP2bigs(c *BIG, d *BIG) *FP2 { - F := new(FP2) - F.a = NewFPbig(c) - F.b = NewFPbig(d) - return F -} - -func NewFP2fp(c *FP) *FP2 { - F := new(FP2) - F.a = NewFPcopy(c) - F.b = NewFP() - return F -} - -func NewFP2big(c *BIG) *FP2 { - F := new(FP2) - F.a = NewFPbig(c) - F.b = NewFP() - return F -} - -/* reduce components mod Modulus */ -func (F *FP2) reduce() { - F.a.reduce() - F.b.reduce() -} - -/* normalise components of w */ -func (F *FP2) norm() { - F.a.norm() - F.b.norm() -} - -/* test this=0 ? */ -func (F *FP2) iszilch() bool { - return (F.a.iszilch() && F.b.iszilch()) -} - -func (F *FP2) cmove(g *FP2, d int) { - F.a.cmove(g.a, d) - F.b.cmove(g.b, d) -} - -/* test this=1 ? */ -func (F *FP2) isunity() bool { - one := NewFPint(1) - return (F.a.Equals(one) && F.b.iszilch()) -} - -/* test this=x */ -func (F *FP2) Equals(x *FP2) bool { - return (F.a.Equals(x.a) && F.b.Equals(x.b)) -} - -/* extract a */ -func (F *FP2) GetA() *BIG { - return F.a.redc() -} - -/* extract b */ -func (F *FP2) GetB() *BIG { - return F.b.redc() -} - -/* copy this=x */ -func (F *FP2) copy(x *FP2) { - F.a.copy(x.a) - F.b.copy(x.b) -} - -/* set this=0 */ -func (F *FP2) zero() { - F.a.zero() - F.b.zero() -} - -/* set this=1 */ -func (F *FP2) one() { - F.a.one() - F.b.zero() -} -/* Return sign */ -func (F *FP2) sign() int { - m := F.a.redc() - return m.parity() -} - -/* negate this mod Modulus */ -func (F *FP2) neg() { - m := NewFPcopy(F.a) - t := NewFP() - - m.add(F.b) - m.neg() - t.copy(m) - t.add(F.b) - F.b.copy(m) - F.b.add(F.a) - F.a.copy(t) -} - -/* set to a-ib */ -func (F *FP2) conj() { - F.b.neg() - F.b.norm() -} - -/* this+=a */ -func (F *FP2) add(x *FP2) { - F.a.add(x.a) - F.b.add(x.b) -} - -/* this-=a */ -func (F *FP2) sub(x *FP2) { - m := NewFP2copy(x) - m.neg() - F.add(m) -} - -/* this-=a */ -func (F *FP2) rsub(x *FP2) { - F.neg() - F.add(x) -} - -/* this*=s, where s is an FP */ -func (F *FP2) pmul(s *FP) { - F.a.mul(s) - F.b.mul(s) -} - -/* this*=i, where i is an int */ -func (F *FP2) imul(c int) { - F.a.imul(c) - F.b.imul(c) -} - -/* this*=this */ -func (F *FP2) sqr() { - w1 := NewFPcopy(F.a) - w3 := NewFPcopy(F.a) - mb := NewFPcopy(F.b) - w1.add(F.b) - - w3.add(F.a) - w3.norm() - F.b.mul(w3) - - mb.neg() - F.a.add(mb) - - w1.norm() - F.a.norm() - - F.a.mul(w1) -} - -/* this*=y */ -/* Now using Lazy reduction */ -func (F *FP2) mul(y *FP2) { - - if int64(F.a.XES+F.b.XES)*int64(y.a.XES+y.b.XES) > int64(FEXCESS) { - if F.a.XES > 1 { - F.a.reduce() - } - if F.b.XES > 1 { - F.b.reduce() - } - } - - pR := NewDBIG() - C := NewBIGcopy(F.a.x) - D := NewBIGcopy(y.a.x) - p := NewBIGints(Modulus) - - pR.ucopy(p) - - A := mul(F.a.x, y.a.x) - B := mul(F.b.x, y.b.x) - - C.add(F.b.x) - C.norm() - D.add(y.b.x) - D.norm() - - E := mul(C, D) - FF := NewDBIGcopy(A) - FF.add(B) - B.rsub(pR) - - A.add(B) - A.norm() - E.sub(FF) - E.norm() - - F.a.x.copy(mod(A)) - F.a.XES = 3 - F.b.x.copy(mod(E)) - F.b.XES = 2 - -} -/* -func (F *FP2) pow(b *BIG) { - w := NewFP2copy(F); - r := NewFP2int(1) - z := NewBIGcopy(b) - for true { - bt := z.parity() - z.shr(1) - if bt==1 { - r.mul(w) - } - if z.iszilch() {break} - w.sqr() - } - r.reduce() - F.copy(r) -} -*/ -func (F *FP2) qr() int { - c := NewFP2copy(F) - c.conj() - c.mul(F) - return c.a.qr(nil) -} - -/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */ -func (F *FP2) sqrt() { - if F.iszilch() { - return - } - w1 := NewFPcopy(F.b) - w2 := NewFPcopy(F.a) - w3 := NewFP(); - w1.sqr() - w2.sqr() - w1.add(w2); w1.norm() - - w1 = w1.sqrt(nil) - w2.copy(F.a) - w3.copy(F.a) - - w2.add(w1) - w2.norm() - w2.div2() - - w3.sub(w1) - w3.norm() - w3.div2() - - w2.cmove(w3,w3.qr(nil)) - - w2 = w2.sqrt(nil) - F.a.copy(w2) - w2.add(w2); w2.norm() - w2.inverse() - F.b.mul(w2) -} - -/* output to hex string */ -func (F *FP2) ToString() string { - return ("[" + F.a.toString() + "," + F.b.toString() + "]") -} - -/* output to hex string */ -func (F *FP2) toString() string { - return ("[" + F.a.toString() + "," + F.b.toString() + "]") -} - -/* this=1/this */ -func (F *FP2) inverse() { - F.norm() - w1 := NewFPcopy(F.a) - w2 := NewFPcopy(F.b) - - w1.sqr() - w2.sqr() - w1.add(w2) - w1.inverse() - F.a.mul(w1) - w1.neg() - w1.norm() - F.b.mul(w1) -} - -/* this/=2 */ -func (F *FP2) div2() { - F.a.div2() - F.b.div2() -} - -/* this*=sqrt(-1) */ -func (F *FP2) times_i() { - z := NewFPcopy(F.a) - F.a.copy(F.b) - F.a.neg() - F.b.copy(z) -} - -/* w*=(1+sqrt(-1)) */ -/* where X*2-(2^i+sqrt(-1)) is irreducible for FP4 */ -func (F *FP2) mul_ip() { - t := NewFP2copy(F) - i := QNRI - F.times_i() - for i > 0 { - t.add(t) - t.norm() - i-- - } - F.add(t) - - if TOWER == POSITOWER { - F.norm() - F.neg() - } - -} - -/* w/=(2^i+sqrt(-1)) */ -func (F *FP2) div_ip() { - z := NewFP2ints(1<. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* Finite Field arithmetic Fp^4 functions */ - -/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1)) */ - -package FP256BN - - - -type FP4 struct { - a *FP2 - b *FP2 -} - -func NewFP4() *FP4 { - F := new(FP4) - F.a = NewFP2() - F.b = NewFP2() - return F -} - -/* Constructors */ -func NewFP4int(a int) *FP4 { - F := new(FP4) - F.a = NewFP2int(a) - F.b = NewFP2() - return F -} - -func NewFP4copy(x *FP4) *FP4 { - F := new(FP4) - F.a = NewFP2copy(x.a) - F.b = NewFP2copy(x.b) - return F -} - -func NewFP4fp2s(c *FP2, d *FP2) *FP4 { - F := new(FP4) - F.a = NewFP2copy(c) - F.b = NewFP2copy(d) - return F -} - -func NewFP4fp2(c *FP2) *FP4 { - F := new(FP4) - F.a = NewFP2copy(c) - F.b = NewFP2() - return F -} - -func NewFP4fp(c *FP) *FP4 { - F := new(FP4) - F.a = NewFP2fp(c) - F.b = NewFP2() - return F -} - -/* reduce all components of this mod Modulus */ -func (F *FP4) reduce() { - F.a.reduce() - F.b.reduce() -} - -/* normalise all components of this mod Modulus */ -func (F *FP4) norm() { - F.a.norm() - F.b.norm() -} - -/* test this==0 ? */ -func (F *FP4) iszilch() bool { - return F.a.iszilch() && F.b.iszilch() -} - -/* Conditional move */ -func (F *FP4) cmove(g *FP4, d int) { - F.a.cmove(g.a, d) - F.b.cmove(g.b, d) -} - -/* test this==1 ? */ -func (F *FP4) isunity() bool { - one := NewFP2int(1) - return F.a.Equals(one) && F.b.iszilch() -} - -/* test is w real? That is in a+ib test b is zero */ -func (F *FP4) isreal() bool { - return F.b.iszilch() -} - -/* extract real part a */ -func (F *FP4) real() *FP2 { - return F.a -} - -func (F *FP4) geta() *FP2 { - return F.a -} - -/* extract imaginary part b */ -func (F *FP4) getb() *FP2 { - return F.b -} - -/* test this=x? */ -func (F *FP4) Equals(x *FP4) bool { - return (F.a.Equals(x.a) && F.b.Equals(x.b)) -} - -/* copy this=x */ -func (F *FP4) copy(x *FP4) { - F.a.copy(x.a) - F.b.copy(x.b) -} - -/* set this=0 */ -func (F *FP4) zero() { - F.a.zero() - F.b.zero() -} - -/* set this=1 */ -func (F *FP4) one() { - F.a.one() - F.b.zero() -} - -/* Return sign */ -func (F *FP4) sign() int { - m := F.a.a.redc() - return m.parity() -} - -/* set this=-this */ -func (F *FP4) neg() { - F.norm() - m := NewFP2copy(F.a) - t := NewFP2() - m.add(F.b) - m.neg() - t.copy(m) - t.add(F.b) - F.b.copy(m) - F.b.add(F.a) - F.a.copy(t) - F.norm() -} - -/* this=conjugate(this) */ -func (F *FP4) conj() { - F.b.neg() - F.norm() -} - -/* this=-conjugate(this) */ -func (F *FP4) nconj() { - F.a.neg() - F.norm() -} - -/* this+=x */ -func (F *FP4) add(x *FP4) { - F.a.add(x.a) - F.b.add(x.b) -} - -/* this-=x */ -func (F *FP4) sub(x *FP4) { - m := NewFP4copy(x) - m.neg() - F.add(m) -} - -/* this-=x */ -func (F *FP4) rsub(x *FP4) { - F.neg() - F.add(x) -} - -/* this*=s where s is FP2 */ -func (F *FP4) pmul(s *FP2) { - F.a.mul(s) - F.b.mul(s) -} - -/* this*=s where s is FP2 */ -func (F *FP4) qmul(s *FP) { - F.a.pmul(s) - F.b.pmul(s) -} - -/* this*=c where c is int */ -func (F *FP4) imul(c int) { - F.a.imul(c) - F.b.imul(c) -} - -/* this*=this */ -func (F *FP4) sqr() { - t1 := NewFP2copy(F.a) - t2 := NewFP2copy(F.b) - t3 := NewFP2copy(F.a) - - t3.mul(F.b) - t1.add(F.b) - t2.mul_ip() - - t2.add(F.a) - - t1.norm() - t2.norm() - - F.a.copy(t1) - - F.a.mul(t2) - - t2.copy(t3) - t2.mul_ip() - t2.add(t3) - t2.norm() - t2.neg() - F.a.add(t2) - - F.b.copy(t3) - F.b.add(t3) - - F.norm() -} - -/* this*=y */ -func (F *FP4) mul(y *FP4) { - t1 := NewFP2copy(F.a) - t2 := NewFP2copy(F.b) - t3 := NewFP2() - t4 := NewFP2copy(F.b) - - t1.mul(y.a) - t2.mul(y.b) - t3.copy(y.b) - t3.add(y.a) - t4.add(F.a) - - t3.norm() - t4.norm() - - t4.mul(t3) - - t3.copy(t1) - t3.neg() - t4.add(t3) - t4.norm() - - t3.copy(t2) - t3.neg() - F.b.copy(t4) - F.b.add(t3) - - t2.mul_ip() - F.a.copy(t2) - F.a.add(t1) - - F.norm() -} - -/* convert this to hex string */ -func (F *FP4) toString() string { - return ("[" + F.a.toString() + "," + F.b.toString() + "]") -} - -/* this=1/this */ -func (F *FP4) inverse() { - t1 := NewFP2copy(F.a) - t2 := NewFP2copy(F.b) - - t1.sqr() - t2.sqr() - t2.mul_ip() - t2.norm() - t1.sub(t2) - - t1.inverse() - F.a.mul(t1) - t1.neg() - t1.norm() - F.b.mul(t1) -} - -/* this*=i where i = sqrt(2^i+sqrt(-1)) */ -func (F *FP4) times_i() { - t := NewFP2copy(F.b) - F.b.copy(F.a) - t.mul_ip() - F.a.copy(t) - F.norm() - if TOWER == POSITOWER { - F.neg() - F.norm() - } -} - -/* this=this^p using Frobenius */ -func (F *FP4) frob(f *FP2) { - F.a.conj() - F.b.conj() - F.b.mul(f) -} - -/* this=this^e -func (F *FP4) pow(e *BIG) *FP4 { - w := NewFP4copy(F) - w.norm() - z := NewBIGcopy(e) - r := NewFP4int(1) - z.norm() - for true { - bt := z.parity() - z.fshr(1) - if bt == 1 { - r.mul(w) - } - if z.iszilch() { - break - } - w.sqr() - } - r.reduce() - return r -} -*/ -/* XTR xtr_a function */ -func (F *FP4) xtr_A(w *FP4, y *FP4, z *FP4) { - r := NewFP4copy(w) - t := NewFP4copy(w) - r.sub(y) - r.norm() - r.pmul(F.a) - t.add(y) - t.norm() - t.pmul(F.b) - t.times_i() - - F.copy(r) - F.add(t) - F.add(z) - - F.norm() -} - -/* XTR xtr_d function */ -func (F *FP4) xtr_D() { - w := NewFP4copy(F) - F.sqr() - w.conj() - w.add(w) - w.norm() - F.sub(w) - F.reduce() -} - -/* r=x^n using XTR method on traces of FP12s */ -func (F *FP4) xtr_pow(n *BIG) *FP4 { - a := NewFP4int(3) - b := NewFP4copy(F) - c := NewFP4copy(b) - c.xtr_D() - t := NewFP4() - r := NewFP4() - sf := NewFP4copy(F) - sf.norm() - - par := n.parity() - v := NewBIGcopy(n) - v.norm() - v.fshr(1) - if par == 0 { - v.dec(1) - v.norm() - } - - nb := v.nbits() - for i := nb - 1; i >= 0; i-- { - if v.bit(i) != 1 { - t.copy(b) - sf.conj() - c.conj() - b.xtr_A(a, sf, c) - sf.conj() - c.copy(t) - c.xtr_D() - a.xtr_D() - } else { - t.copy(a) - t.conj() - a.copy(b) - a.xtr_D() - b.xtr_A(c, sf, t) - c.xtr_D() - } - } - if par == 0 { - r.copy(c) - } else { - r.copy(b) - } - r.reduce() - return r -} - -/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */ -func (F *FP4) xtr_pow2(ck *FP4, ckml *FP4, ckm2l *FP4, a *BIG, b *BIG) *FP4 { - - e := NewBIGcopy(a) - d := NewBIGcopy(b) - w := NewBIGint(0) - e.norm() - d.norm() - - cu := NewFP4copy(ck) // can probably be passed in w/o copying - cv := NewFP4copy(F) - cumv := NewFP4copy(ckml) - cum2v := NewFP4copy(ckm2l) - r := NewFP4() - t := NewFP4() - - f2 := 0 - for d.parity() == 0 && e.parity() == 0 { - d.fshr(1) - e.fshr(1) - f2++ - } - - for Comp(d, e) != 0 { - if Comp(d, e) > 0 { - w.copy(e) - w.imul(4) - w.norm() - if Comp(d, w) <= 0 { - w.copy(d) - d.copy(e) - e.rsub(w) - e.norm() - - t.copy(cv) - t.xtr_A(cu, cumv, cum2v) - cum2v.copy(cumv) - cum2v.conj() - cumv.copy(cv) - cv.copy(cu) - cu.copy(t) - } else { - if d.parity() == 0 { - d.fshr(1) - r.copy(cum2v) - r.conj() - t.copy(cumv) - t.xtr_A(cu, cv, r) - cum2v.copy(cumv) - cum2v.xtr_D() - cumv.copy(t) - cu.xtr_D() - } else { - if e.parity() == 1 { - d.sub(e) - d.norm() - d.fshr(1) - t.copy(cv) - t.xtr_A(cu, cumv, cum2v) - cu.xtr_D() - cum2v.copy(cv) - cum2v.xtr_D() - cum2v.conj() - cv.copy(t) - } else { - w.copy(d) - d.copy(e) - d.fshr(1) - e.copy(w) - t.copy(cumv) - t.xtr_D() - cumv.copy(cum2v) - cumv.conj() - cum2v.copy(t) - cum2v.conj() - t.copy(cv) - t.xtr_D() - cv.copy(cu) - cu.copy(t) - } - } - } - } - if Comp(d, e) < 0 { - w.copy(d) - w.imul(4) - w.norm() - if Comp(e, w) <= 0 { - e.sub(d) - e.norm() - t.copy(cv) - t.xtr_A(cu, cumv, cum2v) - cum2v.copy(cumv) - cumv.copy(cu) - cu.copy(t) - } else { - if e.parity() == 0 { - w.copy(d) - d.copy(e) - d.fshr(1) - e.copy(w) - t.copy(cumv) - t.xtr_D() - cumv.copy(cum2v) - cumv.conj() - cum2v.copy(t) - cum2v.conj() - t.copy(cv) - t.xtr_D() - cv.copy(cu) - cu.copy(t) - } else { - if d.parity() == 1 { - w.copy(e) - e.copy(d) - w.sub(d) - w.norm() - d.copy(w) - d.fshr(1) - t.copy(cv) - t.xtr_A(cu, cumv, cum2v) - cumv.conj() - cum2v.copy(cu) - cum2v.xtr_D() - cum2v.conj() - cu.copy(cv) - cu.xtr_D() - cv.copy(t) - } else { - d.fshr(1) - r.copy(cum2v) - r.conj() - t.copy(cumv) - t.xtr_A(cu, cv, r) - cum2v.copy(cumv) - cum2v.xtr_D() - cumv.copy(t) - cu.xtr_D() - } - } - } - } - } - r.copy(cv) - r.xtr_A(cu, cumv, cum2v) - for i := 0; i < f2; i++ { - r.xtr_D() - } - r = r.xtr_pow(d) - return r -} - -/* this/=2 */ -func (F *FP4) div2() { - F.a.div2() - F.b.div2() -} - -func (F *FP4) div_i() { - u := NewFP2copy(F.a) - v := NewFP2copy(F.b) - u.div_ip() - F.a.copy(v) - F.b.copy(u) - if TOWER == POSITOWER { - F.neg() - F.norm() - } -} -/* -func (F *FP4) pow(b *BIG) { - w := NewFP4copy(F); - r := NewFP4int(1) - z := NewBIGcopy(b) - for true { - bt := z.parity() - z.shr(1) - if bt==1 { - r.mul(w) - } - if z.iszilch() {break} - w.sqr() - } - r.reduce(); - F.copy(r); -} -*/ -/* Test for Quadratic Residue */ -func (F *FP4) qr() int { - c := NewFP4copy(F) - c.conj() - c.mul(F) - return c.a.qr() -} - -/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */ -func (F *FP4) sqrt() { - if F.iszilch() { - return - } - - a := NewFP2copy(F.a) - b := NewFP2() - s := NewFP2copy(F.b) - t := NewFP2copy(F.a) - - s.sqr() - a.sqr() - s.mul_ip() - s.norm() - a.sub(s) - - s.copy(a); s.norm() - s.sqrt(); - - a.copy(t) - b.copy(t) - - a.add(s) - a.norm() - a.div2() - - b.sub(s) - b.norm() - b.div2() - - a.cmove(b,b.qr()) - - a.sqrt() - t.copy(F.b) - s.copy(a) - s.add(a); s.norm() - s.inverse() - - t.mul(s) - F.a.copy(a) - F.b.copy(t) - -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/MPIN.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/MPIN.go deleted file mode 100644 index ee3f93d3d9b..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/MPIN.go +++ /dev/null @@ -1,796 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* MPIN API Functions */ - -package FP256BN - -import "time" -import "github.com/hyperledger/fabric-amcl/core" - - - -const MFS int = int(MODBYTES) -const MGS int = int(MODBYTES) -const BAD_PARAMS int = -11 -const INVALID_POINT int = -14 -const WRONG_ORDER int = -18 -const BAD_PIN int = -19 - -/* Configure your PIN here */ - -const MAXPIN int32 = 10000 /* PIN less than this */ -const PBLEN int32 = 14 /* Number of bits in PIN */ -const TS int = 10 /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */ -const TRAP int = 200 /* 200 for 4 digit PIN, 2000 for 6-digit PIN - approx 2*sqrt(MAXPIN) */ - -func mpin_hash(sha int, c *FP4, U *ECP) []byte { - var w [MFS]byte - var t [6 * MFS]byte - - c.geta().GetA().ToBytes(w[:]) - for i := 0; i < MFS; i++ { - t[i] = w[i] - } - c.geta().GetB().ToBytes(w[:]) - for i := MFS; i < 2*MFS; i++ { - t[i] = w[i-MFS] - } - c.getb().GetA().ToBytes(w[:]) - for i := 2 * MFS; i < 3*MFS; i++ { - t[i] = w[i-2*MFS] - } - c.getb().GetB().ToBytes(w[:]) - for i := 3 * MFS; i < 4*MFS; i++ { - t[i] = w[i-3*MFS] - } - - U.GetX().ToBytes(w[:]) - for i := 4 * MFS; i < 5*MFS; i++ { - t[i] = w[i-4*MFS] - } - U.GetY().ToBytes(w[:]) - for i := 5 * MFS; i < 6*MFS; i++ { - t[i] = w[i-5*MFS] - } - - h := core.SPhashit(core.MC_SHA2,sha,t[:]) - - if h == nil { - return nil - } - R := make([]byte, AESKEY) - for i := 0; i < AESKEY; i++ { - R[i] = h[i] - } - return R -} - -/* Hash number (optional) and string to coordinate on curve */ - -/* return time in slots since epoch */ -func Today() int { - now := time.Now() - return int(now.Unix()) / (60 * 1440) -} - -/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */ -/* maps a random u to a point on the curve */ -func emap(u *BIG, cb int) *ECP { - var P *ECP - x := NewBIGcopy(u) - p := NewBIGints(Modulus) - x.Mod(p) - for true { - P = NewECPbigint(x, cb) - if !P.Is_infinity() { - break - } - x.inc(1) - x.norm() - } - return P -} - -/* returns u derived from P. Random value in range 1 to return value should then be added to u */ -func unmap(u *BIG, P *ECP) int { - s := P.GetS() - var R *ECP - r := 0 - x := P.GetX() - u.copy(x) - for true { - u.dec(1) - u.norm() - r++ - R = NewECPbigint(u, s) - if !R.Is_infinity() { - break - } - } - return r -} - -func MPIN_HASH_ID(sha int, ID []byte) []byte { - return core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,-1,ID) - //return mhashit(sha, 0, ID) -} - -/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */ -/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */ -/* Note that u and v are indistinguisible from random strings */ -func MPIN_ENCODING(rng *core.RAND, E []byte) int { - var T [MFS]byte - - for i := 0; i < MFS; i++ { - T[i] = E[i+1] - } - u := FromBytes(T[:]) - for i := 0; i < MFS; i++ { - T[i] = E[i+MFS+1] - } - v := FromBytes(T[:]) - - P := NewECPbigs(u, v) - if P.Is_infinity() { - return INVALID_POINT - } - - p := NewBIGints(Modulus) - u = Randomnum(p, rng) - - su := int(rng.GetByte()) - su %= 2 - - W := emap(u, su) - P.Sub(W) - sv := P.GetS() - rn := unmap(v, P) - m := int(rng.GetByte()) - m %= rn - v.inc(m + 1) - E[0] = byte(su + 2*sv) - u.ToBytes(T[:]) - for i := 0; i < MFS; i++ { - E[i+1] = T[i] - } - v.ToBytes(T[:]) - for i := 0; i < MFS; i++ { - E[i+MFS+1] = T[i] - } - - return 0 -} - -func MPIN_DECODING(D []byte) int { - var T [MFS]byte - - if (D[0] & 0x04) != 0 { - return INVALID_POINT - } - - for i := 0; i < MFS; i++ { - T[i] = D[i+1] - } - u := FromBytes(T[:]) - for i := 0; i < MFS; i++ { - T[i] = D[i+MFS+1] - } - v := FromBytes(T[:]) - - su := int(D[0] & 1) - sv := int((D[0] >> 1) & 1) - W := emap(u, su) - P := emap(v, sv) - P.Add(W) - u = P.GetX() - v = P.GetY() - D[0] = 0x04 - u.ToBytes(T[:]) - for i := 0; i < MFS; i++ { - D[i+1] = T[i] - } - v.ToBytes(T[:]) - for i := 0; i < MFS; i++ { - D[i+MFS+1] = T[i] - } - - return 0 -} - -/* R=R1+R2 in group G1 */ -func MPIN_RECOMBINE_G1(R1 []byte, R2 []byte, R []byte) int { - P := ECP_fromBytes(R1) - Q := ECP_fromBytes(R2) - - if P.Is_infinity() || Q.Is_infinity() { - return INVALID_POINT - } - - P.Add(Q) - - P.ToBytes(R[:], false) - return 0 -} - -/* W=W1+W2 in group G2 */ -func MPIN_RECOMBINE_G2(W1 []byte, W2 []byte, W []byte) int { - P := ECP2_fromBytes(W1) - Q := ECP2_fromBytes(W2) - - if P.Is_infinity() || Q.Is_infinity() { - return INVALID_POINT - } - - P.Add(Q) - - P.ToBytes(W[:],false) - return 0 -} - -/* create random secret S */ -func MPIN_RANDOM_GENERATE(rng *core.RAND, S []byte) int { - r := NewBIGints(CURVE_Order) - s := Randtrunc(r, 16*AESKEY, rng) - s.ToBytes(S) - return 0 -} - -func MPIN_EXTRACT_PIN(sha int, CID []byte, pin int, TOKEN []byte) int { - return MPIN_EXTRACT_FACTOR(sha, CID, int32(pin)%MAXPIN, PBLEN, TOKEN) -} - -/* Extract factor from TOKEN for identity CID */ -func MPIN_EXTRACT_FACTOR(sha int, CID []byte, factor int32, facbits int32, TOKEN []byte) int { - P := ECP_fromBytes(TOKEN) - if P.Is_infinity() { - return INVALID_POINT - } - h := core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,-1,CID) - //h := mhashit(sha, 0, CID) - R := ECP_mapit(h) - - R = R.pinmul(factor, facbits) - P.Sub(R) - - P.ToBytes(TOKEN, false) - - return 0 -} - -/* Restore factor to TOKEN for identity CID */ -func MPIN_RESTORE_FACTOR(sha int, CID []byte, factor int32, facbits int32, TOKEN []byte) int { - P := ECP_fromBytes(TOKEN) - if P.Is_infinity() { - return INVALID_POINT - } - h := core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,-1,CID) - //h := mhashit(sha, 0, CID) - R := ECP_mapit(h) - - R = R.pinmul(factor, facbits) - P.Add(R) - - P.ToBytes(TOKEN, false) - - return 0 -} - -/* Implement step 2 on client side of MPin protocol */ -func MPIN_CLIENT_2(X []byte, Y []byte, SEC []byte) int { - r := NewBIGints(CURVE_Order) - P := ECP_fromBytes(SEC) - if P.Is_infinity() { - return INVALID_POINT - } - - px := FromBytes(X) - py := FromBytes(Y) - px.add(py) - px.Mod(r) - - P = G1mul(P, px) - P.Neg() - P.ToBytes(SEC, false) - - return 0 -} - -/* Implement step 1 on client side of MPin protocol */ -func MPIN_CLIENT_1(sha int, date int, CLIENT_ID []byte, rng *core.RAND, X []byte, pin int, TOKEN []byte, SEC []byte, xID []byte, xCID []byte, PERMIT []byte) int { - r := NewBIGints(CURVE_Order) - - var x *BIG - if rng != nil { - x = Randtrunc(r, 16*AESKEY, rng) - x.ToBytes(X) - } else { - x = FromBytes(X) - } - - h := core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,-1,CLIENT_ID) - //h := mhashit(sha, 0, CLIENT_ID) - P := ECP_mapit(h) - - T := ECP_fromBytes(TOKEN) - if T.Is_infinity() { - return INVALID_POINT - } - - W := P.pinmul(int32(pin)%MAXPIN, PBLEN) - T.Add(W) - if date != 0 { - W = ECP_fromBytes(PERMIT) - if W.Is_infinity() { - return INVALID_POINT - } - T.Add(W) - h = core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,int32(date),h) - //h = mhashit(sha, int32(date), h) - W = ECP_mapit(h) - if xID != nil { - P = G1mul(P, x) - P.ToBytes(xID, false) - W = G1mul(W, x) - P.Add(W) - } else { - P.Add(W) - P = G1mul(P, x) - } - if xCID != nil { - P.ToBytes(xCID, false) - } - } else { - if xID != nil { - P = G1mul(P, x) - P.ToBytes(xID, false) - } - } - - T.ToBytes(SEC, false) - return 0 -} - -/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */ -func MPIN_GET_SERVER_SECRET(S []byte, SST []byte) int { - Q := ECP2_generator() - s := FromBytes(S) - Q = G2mul(Q, s) - Q.ToBytes(SST,false) - return 0 -} - -/* - W=x*H(G); - if RNG == NULL then X is passed in - if RNG != NULL the X is passed out - if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve -*/ -func MPIN_GET_G1_MULTIPLE(rng *core.RAND, typ int, X []byte, G []byte, W []byte) int { - var x *BIG - r := NewBIGints(CURVE_Order) - if rng != nil { - x = Randtrunc(r, 16*AESKEY, rng) - x.ToBytes(X) - } else { - x = FromBytes(X) - } - var P *ECP - if typ == 0 { - P = ECP_fromBytes(G) - if P.Is_infinity() { - return INVALID_POINT - } - } else { - P = ECP_mapit(G) - } - - G1mul(P, x).ToBytes(W, false) - return 0 -} - -/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */ -/* CID is hashed externally */ -func MPIN_GET_CLIENT_SECRET(S []byte, CID []byte, CST []byte) int { - return MPIN_GET_G1_MULTIPLE(nil, 1, S, CID, CST) -} - -/* Time Permit CTT=S*(date|H(CID)) where S is master secret */ -func MPIN_GET_CLIENT_PERMIT(sha, date int, S []byte, CID []byte, CTT []byte) int { - - h := core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,int32(date),CID) - //h := mhashit(sha, int32(date), CID) - P := ECP_mapit(h) - - s := FromBytes(S) - G1mul(P, s).ToBytes(CTT, false) - return 0 -} - -/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */ -func MPIN_SERVER_1(sha int, date int, CID []byte, HID []byte, HTID []byte) { - h := core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,-1,CID) - //h := mhashit(sha, 0, CID) - P := ECP_mapit(h) - - P.ToBytes(HID, false) - if date != 0 { - h = core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,int32(date),h) - //h = mhashit(sha, int32(date), h) - R := ECP_mapit(h) - P.Add(R) - P.ToBytes(HTID, false) - } -} - -/* Implement step 2 of MPin protocol on server side */ -func MPIN_SERVER_2(date int, HID []byte, HTID []byte, Y []byte, SST []byte, xID []byte, xCID []byte, mSEC []byte, E []byte, F []byte) int { - Q := ECP2_generator() - - sQ := ECP2_fromBytes(SST) - if sQ.Is_infinity() { - return INVALID_POINT - } - - var R *ECP - if date != 0 { - R = ECP_fromBytes(xCID) - } else { - if xID == nil { - return BAD_PARAMS - } - R = ECP_fromBytes(xID) - } - if R.Is_infinity() { - return INVALID_POINT - } - - y := FromBytes(Y) - var P *ECP - if date != 0 { - P = ECP_fromBytes(HTID) - } else { - if HID == nil { - return BAD_PARAMS - } - P = ECP_fromBytes(HID) - } - - if P.Is_infinity() { - return INVALID_POINT - } - - P = G1mul(P, y) - P.Add(R) - R = ECP_fromBytes(mSEC) - if R.Is_infinity() { - return INVALID_POINT - } - - var g *FP12 - - g = Ate2(Q, R, sQ, P) - g = Fexp(g) - - if !g.Isunity() { - if HID != nil && xID != nil && E != nil && F != nil { - g.ToBytes(E) - if date != 0 { - P = ECP_fromBytes(HID) - if P.Is_infinity() { - return INVALID_POINT - } - R = ECP_fromBytes(xID) - if R.Is_infinity() { - return INVALID_POINT - } - - P = G1mul(P, y) - P.Add(R) - //P.Affine() - } - g = Ate(Q, P) - g = Fexp(g) - g.ToBytes(F) - } - return BAD_PIN - } - - return 0 -} - -/* Pollards kangaroos used to return PIN error */ -func MPIN_KANGAROO(E []byte, F []byte) int { - ge := FP12_fromBytes(E) - gf := FP12_fromBytes(F) - var distance [TS]int - t := NewFP12copy(gf) - - var table []*FP12 - var i int - s := 1 - for m := 0; m < TS; m++ { - distance[m] = s - table = append(table, NewFP12copy(t)) - s *= 2 - t.usqr() - } - t.one() - dn := 0 - for j := 0; j < TRAP; j++ { - i = t.geta().geta().GetA().lastbits(20) % TS - t.Mul(table[i]) - dn += distance[i] - } - gf.Copy(t) - gf.conj() - steps := 0 - dm := 0 - res := 0 - for dm-dn < int(MAXPIN) { - steps++ - if steps > 4*TRAP { - break - } - i = ge.geta().geta().GetA().lastbits(20) % TS - ge.Mul(table[i]) - dm += distance[i] - if ge.Equals(t) { - res = dm - dn - break - } - if ge.Equals(gf) { - res = dn - dm - break - } - - } - if steps > 4*TRAP || dm-dn >= int(MAXPIN) { - res = 0 - } // Trap Failed - probable invalid token - return int(res) -} - -/* Functions to support M-Pin Full */ - -func MPIN_PRECOMPUTE(TOKEN []byte, CID []byte, G1 []byte, G2 []byte) int { - var P, T *ECP - var g *FP12 - - T = ECP_fromBytes(TOKEN) - if T.Is_infinity() { - return INVALID_POINT - } - - P = ECP_mapit(CID) - - Q := ECP2_generator() - - g = Ate(Q, T) - g = Fexp(g) - g.ToBytes(G1) - - g = Ate(Q, P) - g = Fexp(g) - g.ToBytes(G2) - - return 0 -} - -/* Hash the M-Pin transcript - new */ - -func MPIN_HASH_ALL(sha int, HID []byte, xID []byte, xCID []byte, SEC []byte, Y []byte, R []byte, W []byte) []byte { - tlen := 0 - var T [10*int(MODBYTES) + 4]byte - - for i := 0; i < len(HID); i++ { - T[i] = HID[i] - } - tlen += len(HID) - if xCID != nil { - for i := 0; i < len(xCID); i++ { - T[i+tlen] = xCID[i] - } - tlen += len(xCID) - } else { - for i := 0; i < len(xID); i++ { - T[i+tlen] = xID[i] - } - tlen += len(xID) - } - for i := 0; i < len(SEC); i++ { - T[i+tlen] = SEC[i] - } - tlen += len(SEC) - for i := 0; i < len(Y); i++ { - T[i+tlen] = Y[i] - } - tlen += len(Y) - for i := 0; i < len(R); i++ { - T[i+tlen] = R[i] - } - tlen += len(R) - for i := 0; i < len(W); i++ { - T[i+tlen] = W[i] - } - tlen += len(W) - - return core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,-1,T[:]) - //return mhashit(sha, 0, T[:]) -} - -/* calculate common key on client side */ -/* wCID = w.(A+AT) */ -func MPIN_CLIENT_KEY(sha int, G1 []byte, G2 []byte, pin int, R []byte, X []byte, H []byte, wCID []byte, CK []byte) int { - - g1 := FP12_fromBytes(G1) - g2 := FP12_fromBytes(G2) - z := FromBytes(R) - x := FromBytes(X) - h := FromBytes(H) - - W := ECP_fromBytes(wCID) - if W.Is_infinity() { - return INVALID_POINT - } - - W = G1mul(W, x) - - r := NewBIGints(CURVE_Order) - - z.add(h) //new - z.Mod(r) - - g2.pinpow(pin, int(PBLEN)) - g1.Mul(g2) - - c := g1.Compow(z, r) - - t := mpin_hash(sha, c, W) - - for i := 0; i < AESKEY; i++ { - CK[i] = t[i] - } - - return 0 -} - -/* calculate common key on server side */ -/* Z=r.A - no time permits involved */ - -func MPIN_SERVER_KEY(sha int, Z []byte, SST []byte, W []byte, H []byte, HID []byte, xID []byte, xCID []byte, SK []byte) int { - sQ := ECP2_fromBytes(SST) - if sQ.Is_infinity() { - return INVALID_POINT - } - R := ECP_fromBytes(Z) - if R.Is_infinity() { - return INVALID_POINT - } - A := ECP_fromBytes(HID) - if A.Is_infinity() { - return INVALID_POINT - } - - var U *ECP - if xCID != nil { - U = ECP_fromBytes(xCID) - } else { - U = ECP_fromBytes(xID) - } - if U.Is_infinity() { - return INVALID_POINT - } - - w := FromBytes(W) - h := FromBytes(H) - A = G1mul(A, h) // new - R.Add(A) - - U = G1mul(U, w) - g := Ate(sQ, R) - g = Fexp(g) - - c := g.trace() - - t := mpin_hash(sha, c, U) - - for i := 0; i < AESKEY; i++ { - SK[i] = t[i] - } - - return 0 -} - -/* return time since epoch */ -func MPIN_GET_TIME() int { - now := time.Now() - return int(now.Unix()) -} - -/* Generate Y = H(epoch, xCID/xID) */ -func MPIN_GET_Y(sha int, TimeValue int, xCID []byte, Y []byte) { - h := core.GPhashit(core.MC_SHA2,sha,int(MODBYTES),nil,int32(TimeValue), xCID) - //h := mhashit(sha, int32(TimeValue), xCID) - y := FromBytes(h) - q := NewBIGints(CURVE_Order) - y.Mod(q) - y.ToBytes(Y) -} - -/* One pass MPIN Client */ -func MPIN_CLIENT(sha int, date int, CLIENT_ID []byte, RNG *core.RAND, X []byte, pin int, TOKEN []byte, SEC []byte, xID []byte, xCID []byte, PERMIT []byte, TimeValue int, Y []byte) int { - rtn := 0 - - var pID []byte - if date == 0 { - pID = xID - } else { - pID = xCID - } - - rtn = MPIN_CLIENT_1(sha, date, CLIENT_ID, RNG, X, pin, TOKEN, SEC, xID, xCID, PERMIT) - if rtn != 0 { - return rtn - } - - MPIN_GET_Y(sha, TimeValue, pID, Y) - - rtn = MPIN_CLIENT_2(X, Y, SEC) - if rtn != 0 { - return rtn - } - - return 0 -} - -/* One pass MPIN Server */ -func MPIN_SERVER(sha int, date int, HID []byte, HTID []byte, Y []byte, SST []byte, xID []byte, xCID []byte, SEC []byte, E []byte, F []byte, CID []byte, TimeValue int) int { - rtn := 0 - - var pID []byte - if date == 0 { - pID = xID - } else { - pID = xCID - } - - MPIN_SERVER_1(sha, date, CID, HID, HTID) - MPIN_GET_Y(sha, TimeValue, pID, Y) - - rtn = MPIN_SERVER_2(date, HID, HTID, Y, SST, xID, xCID, SEC, E, F) - if rtn != 0 { - return rtn - } - - return 0 -} diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/PAIR.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/PAIR.go deleted file mode 100644 index 54ad68e7052..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/PAIR.go +++ /dev/null @@ -1,984 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* BN/BLS Curve Pairing functions */ - -package FP256BN - - - -// Point doubling for pairings -func dbl(A *ECP2, AA *FP2, BB *FP2, CC *FP2) { - CC.copy(A.getx()) //X - YY := NewFP2copy(A.gety()) //Y - BB.copy(A.getz()) //Z - AA.copy(YY) //Y - AA.mul(BB) //YZ - CC.sqr() //X^2 - YY.sqr() //Y^2 - BB.sqr() //Z^2 - - AA.add(AA) - AA.neg() - AA.norm() //-2AA - AA.mul_ip() - AA.norm() - - sb := 3 * CURVE_B_I - BB.imul(sb) - CC.imul(3) - if SEXTIC_TWIST == D_TYPE { - YY.mul_ip() - YY.norm() - CC.mul_ip() - CC.norm() - } - if SEXTIC_TWIST == M_TYPE { - BB.mul_ip() - BB.norm() - } - BB.sub(YY) - BB.norm() - - A.dbl() - - /* - AA.imul(4) - AA.neg() - AA.norm() //-4YZ - - CC.imul(6) //6X^2 - - sb := 3 * CURVE_B_I - BB.imul(sb) // 3bZ^2 - if SEXTIC_TWIST == D_TYPE { - BB.div_ip2() - } - if SEXTIC_TWIST == M_TYPE { - BB.mul_ip() - BB.add(BB) - AA.mul_ip() - AA.norm() - } - BB.norm() // 3b.Z^2 - - YY.add(YY) - BB.sub(YY) - BB.norm() // 3b.Z^2-2Y^2 - - A.dbl() */ -} - -// Point addition for pairings -func add(A *ECP2, B *ECP2, AA *FP2, BB *FP2, CC *FP2) { - AA.copy(A.getx()) // X1 - CC.copy(A.gety()) // Y1 - T1 := NewFP2copy(A.getz()) // Z1 - BB.copy(A.getz()) // Z1 - - T1.mul(B.gety()) // T1=Z1.Y2 - BB.mul(B.getx()) // T2=Z1.X2 - - AA.sub(BB) - AA.norm() // X1=X1-Z1.X2 - CC.sub(T1) - CC.norm() // Y1=Y1-Z1.Y2 - - T1.copy(AA) // T1=X1-Z1.X2 - - if SEXTIC_TWIST == M_TYPE { - AA.mul_ip() - AA.norm() - } - - T1.mul(B.gety()) // T1=(X1-Z1.X2).Y2 - - BB.copy(CC) // T2=Y1-Z1.Y2 - BB.mul(B.getx()) // T2=(Y1-Z1.Y2).X2 - BB.sub(T1) - BB.norm() // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2 - CC.neg() - CC.norm() // Y1=-(Y1-Z1.Y2).Xs - - A.Add(B) -} - -/* Line function */ -func line(A *ECP2, B *ECP2, Qx *FP, Qy *FP) *FP12 { - AA := NewFP2() - BB := NewFP2() - CC := NewFP2() - - var a *FP4 - var b *FP4 - var c *FP4 - - if A == B { - dbl(A, AA, BB, CC) - } else { - add(A, B, AA, BB, CC) - } - - CC.pmul(Qx) - AA.pmul(Qy) - - a = NewFP4fp2s(AA, BB) - - if SEXTIC_TWIST == D_TYPE { - b = NewFP4fp2(CC) // L(0,1) | L(0,0) | L(1,0) - c = NewFP4() - } - if SEXTIC_TWIST == M_TYPE { - b = NewFP4() - c = NewFP4fp2(CC) - c.times_i() - } - - r := NewFP12fp4s(a, b, c) - r.stype = FP_SPARSER - return r -} - -/* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */ -func lbits(n3 *BIG, n *BIG) int { - n.copy(NewBIGints(CURVE_Bnx)) - if CURVE_PAIRING_TYPE == BN { - n.pmul(6) - if SIGN_OF_X == POSITIVEX { - n.inc(2) - } else { - n.dec(2) - } - } - - n.norm() - n3.copy(n) - n3.pmul(3) - n3.norm() - return n3.nbits() -} - -/* prepare for multi-pairing */ -func Initmp() []*FP12 { - var r []*FP12 - for i := ATE_BITS - 1; i >= 0; i-- { - r = append(r, NewFP12int(1)) - } - return r -} - -/* basic Miller loop */ -func Miller(r []*FP12) *FP12 { - res := NewFP12int(1) - for i := ATE_BITS - 1; i >= 1; i-- { - res.sqr() - res.ssmul(r[i]) - r[i].zero() - } - - if SIGN_OF_X == NEGATIVEX { - res.conj() - } - res.ssmul(r[0]) - r[0].zero() - return res -} - -// Store precomputed line details in an FP4 -func pack(AA *FP2, BB *FP2, CC *FP2) *FP4 { - i := NewFP2copy(CC) - i.inverse() - a := NewFP2copy(AA) - a.mul(i) - b := NewFP2copy(BB) - b.mul(i) - return NewFP4fp2s(a, b) -} - -// Unpack G2 line function details and include G1 -func unpack(T *FP4, Qx *FP, Qy *FP) *FP12 { - var a *FP4 - var b *FP4 - var c *FP4 - - a = NewFP4copy(T) - a.geta().pmul(Qy) - t := NewFP2fp(Qx) - if SEXTIC_TWIST == D_TYPE { - b = NewFP4fp2(t) - c = NewFP4() - } - if SEXTIC_TWIST == M_TYPE { - b = NewFP4() - c = NewFP4fp2(t) - c.times_i() - } - v := NewFP12fp4s(a, b, c) - v.stype = FP_SPARSEST - return v -} - -func precomp(GV *ECP2) []*FP4 { - var f *FP2 - n := NewBIG() - n3 := NewBIG() - K := NewECP2() - AA := NewFP2() - BB := NewFP2() - CC := NewFP2() - var bt int - P := NewECP2() - P.Copy(GV) - - if CURVE_PAIRING_TYPE == BN { - f = NewFP2bigs(NewBIGints(Fra), NewBIGints(Frb)) - if SEXTIC_TWIST == M_TYPE { - f.inverse() - f.norm() - } - } - A := NewECP2() - A.Copy(P) - MP := NewECP2() - MP.Copy(P) - MP.neg() - - nb := lbits(n3, n) - var T []*FP4 - - for i := nb - 2; i >= 1; i-- { - dbl(A, AA, BB, CC) - T = append(T, pack(AA, BB, CC)) - bt = n3.bit(i) - n.bit(i) - if bt == 1 { - add(A, P, AA, BB, CC) - T = append(T, pack(AA, BB, CC)) - } - if bt == -1 { - add(A, MP, AA, BB, CC) - T = append(T, pack(AA, BB, CC)) - } - } - if CURVE_PAIRING_TYPE == BN { - if SIGN_OF_X == NEGATIVEX { - A.neg() - } - K.Copy(P) - K.frob(f) - add(A, K, AA, BB, CC) - T = append(T, pack(AA, BB, CC)) - K.frob(f) - K.neg() - add(A, K, AA, BB, CC) - T = append(T, pack(AA, BB, CC)) - } - return T -} - -/* Accumulate another set of line functions for n-pairing, assuming precomputation on G2 */ -func Another_pc(r []*FP12, T []*FP4, QV *ECP) { - n := NewBIG() - n3 := NewBIG() - var lv, lv2 *FP12 - var bt, j int - - if QV.Is_infinity() { - return - } - - Q := NewECP() - Q.Copy(QV) - Q.Affine() - Qx := NewFPcopy(Q.getx()) - Qy := NewFPcopy(Q.gety()) - - nb := lbits(n3, n) - j = 0 - for i := nb - 2; i >= 1; i-- { - lv = unpack(T[j], Qx, Qy) - j += 1 - bt = n3.bit(i) - n.bit(i) - if bt == 1 { - lv2 = unpack(T[j], Qx, Qy) - j += 1 - lv.smul(lv2) - } - if bt == -1 { - lv2 = unpack(T[j], Qx, Qy) - j += 1 - lv.smul(lv2) - } - r[i].ssmul(lv) - } - if CURVE_PAIRING_TYPE == BN { - lv = unpack(T[j], Qx, Qy) - j += 1 - lv2 = unpack(T[j], Qx, Qy) - j += 1 - lv.smul(lv2) - r[0].ssmul(lv) - } -} - -/* Accumulate another set of line functions for n-pairing */ -func Another(r []*FP12, P1 *ECP2, Q1 *ECP) { - f := NewFP2bigs(NewBIGints(Fra), NewBIGints(Frb)) - n := NewBIG() - n3 := NewBIG() - K := NewECP2() - var lv, lv2 *FP12 - - if Q1.Is_infinity() { - return - } - - // P is needed in affine form for line function, Q for (Qx,Qy) extraction - P := NewECP2() - P.Copy(P1) - Q := NewECP() - Q.Copy(Q1) - - P.Affine() - Q.Affine() - - if CURVE_PAIRING_TYPE == BN { - if SEXTIC_TWIST == M_TYPE { - f.inverse() - f.norm() - } - } - - Qx := NewFPcopy(Q.getx()) - Qy := NewFPcopy(Q.gety()) - - A := NewECP2() - A.Copy(P) - - MP := NewECP2() - MP.Copy(P) - MP.neg() - - nb := lbits(n3, n) - - for i := nb - 2; i >= 1; i-- { - lv = line(A, A, Qx, Qy) - - bt := n3.bit(i) - n.bit(i) - if bt == 1 { - lv2 = line(A, P, Qx, Qy) - lv.smul(lv2) - } - if bt == -1 { - lv2 = line(A, MP, Qx, Qy) - lv.smul(lv2) - } - r[i].ssmul(lv) - } - - /* R-ate fixup required for BN curves */ - if CURVE_PAIRING_TYPE == BN { - if SIGN_OF_X == NEGATIVEX { - A.neg() - } - K.Copy(P) - K.frob(f) - lv = line(A, K, Qx, Qy) - K.frob(f) - K.neg() - lv2 = line(A, K, Qx, Qy) - lv.smul(lv2) - r[0].ssmul(lv) - } -} - -/* Optimal R-ate pairing */ -func Ate(P1 *ECP2, Q1 *ECP) *FP12 { - f := NewFP2bigs(NewBIGints(Fra), NewBIGints(Frb)) - n := NewBIG() - n3 := NewBIG() - K := NewECP2() - var lv, lv2 *FP12 - - if Q1.Is_infinity() { - return NewFP12int(1) - } - - if CURVE_PAIRING_TYPE == BN { - if SEXTIC_TWIST == M_TYPE { - f.inverse() - f.norm() - } - } - - P := NewECP2() - P.Copy(P1) - P.Affine() - Q := NewECP() - Q.Copy(Q1) - Q.Affine() - - Qx := NewFPcopy(Q.getx()) - Qy := NewFPcopy(Q.gety()) - - A := NewECP2() - r := NewFP12int(1) - - A.Copy(P) - - NP := NewECP2() - NP.Copy(P) - NP.neg() - - nb := lbits(n3, n) - - for i := nb - 2; i >= 1; i-- { - r.sqr() - lv = line(A, A, Qx, Qy) - bt := n3.bit(i) - n.bit(i) - if bt == 1 { - lv2 = line(A, P, Qx, Qy) - lv.smul(lv2) - } - if bt == -1 { - lv2 = line(A, NP, Qx, Qy) - lv.smul(lv2) - } - r.ssmul(lv) - } - - if SIGN_OF_X == NEGATIVEX { - r.conj() - } - - /* R-ate fixup required for BN curves */ - - if CURVE_PAIRING_TYPE == BN { - if SIGN_OF_X == NEGATIVEX { - A.neg() - } - - K.Copy(P) - K.frob(f) - lv = line(A, K, Qx, Qy) - K.frob(f) - K.neg() - lv2 = line(A, K, Qx, Qy) - lv.smul(lv2) - r.ssmul(lv) - } - - return r -} - -/* Optimal R-ate double pairing e(P,Q).e(R,S) */ -func Ate2(P1 *ECP2, Q1 *ECP, R1 *ECP2, S1 *ECP) *FP12 { - f := NewFP2bigs(NewBIGints(Fra), NewBIGints(Frb)) - n := NewBIG() - n3 := NewBIG() - K := NewECP2() - var lv, lv2 *FP12 - - if Q1.Is_infinity() { - return Ate(R1, S1) - } - if S1.Is_infinity() { - return Ate(P1, Q1) - } - if CURVE_PAIRING_TYPE == BN { - if SEXTIC_TWIST == M_TYPE { - f.inverse() - f.norm() - } - } - - P := NewECP2() - P.Copy(P1) - P.Affine() - Q := NewECP() - Q.Copy(Q1) - Q.Affine() - R := NewECP2() - R.Copy(R1) - R.Affine() - S := NewECP() - S.Copy(S1) - S.Affine() - - Qx := NewFPcopy(Q.getx()) - Qy := NewFPcopy(Q.gety()) - Sx := NewFPcopy(S.getx()) - Sy := NewFPcopy(S.gety()) - - A := NewECP2() - B := NewECP2() - r := NewFP12int(1) - - A.Copy(P) - B.Copy(R) - NP := NewECP2() - NP.Copy(P) - NP.neg() - NR := NewECP2() - NR.Copy(R) - NR.neg() - - nb := lbits(n3, n) - - for i := nb - 2; i >= 1; i-- { - r.sqr() - lv = line(A, A, Qx, Qy) - lv2 = line(B, B, Sx, Sy) - lv.smul(lv2) - r.ssmul(lv) - bt := n3.bit(i) - n.bit(i) - if bt == 1 { - lv = line(A, P, Qx, Qy) - lv2 = line(B, R, Sx, Sy) - lv.smul(lv2) - r.ssmul(lv) - } - if bt == -1 { - lv = line(A, NP, Qx, Qy) - lv2 = line(B, NR, Sx, Sy) - lv.smul(lv2) - r.ssmul(lv) - } - } - - if SIGN_OF_X == NEGATIVEX { - r.conj() - } - - /* R-ate fixup */ - if CURVE_PAIRING_TYPE == BN { - if SIGN_OF_X == NEGATIVEX { - A.neg() - B.neg() - } - K.Copy(P) - K.frob(f) - - lv = line(A, K, Qx, Qy) - K.frob(f) - K.neg() - lv2 = line(A, K, Qx, Qy) - lv.smul(lv2) - r.ssmul(lv) - K.Copy(R) - K.frob(f) - lv = line(B, K, Sx, Sy) - K.frob(f) - K.neg() - lv2 = line(B, K, Sx, Sy) - lv.smul(lv2) - r.ssmul(lv) - } - - return r -} - -/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */ -func Fexp(m *FP12) *FP12 { - f := NewFP2bigs(NewBIGints(Fra), NewBIGints(Frb)) - x := NewBIGints(CURVE_Bnx) - r := NewFP12copy(m) - - /* Easy part of final exp */ - lv := NewFP12copy(r) - lv.Inverse() - r.conj() - - r.Mul(lv) - lv.Copy(r) - r.frob(f) - r.frob(f) - r.Mul(lv) - - /* Hard part of final exp */ - if CURVE_PAIRING_TYPE == BN { - lv.Copy(r) - lv.frob(f) - x0 := NewFP12copy(lv) - x0.frob(f) - lv.Mul(r) - x0.Mul(lv) - x0.frob(f) - x1 := NewFP12copy(r) - x1.conj() - x4 := r.Pow(x) - if SIGN_OF_X == POSITIVEX { - x4.conj() - } - - x3 := NewFP12copy(x4) - x3.frob(f) - - x2 := x4.Pow(x) - if SIGN_OF_X == POSITIVEX { - x2.conj() - } - - x5 := NewFP12copy(x2) - x5.conj() - lv = x2.Pow(x) - if SIGN_OF_X == POSITIVEX { - lv.conj() - } - - x2.frob(f) - r.Copy(x2) - r.conj() - - x4.Mul(r) - x2.frob(f) - - r.Copy(lv) - r.frob(f) - lv.Mul(r) - - lv.usqr() - lv.Mul(x4) - lv.Mul(x5) - r.Copy(x3) - r.Mul(x5) - r.Mul(lv) - lv.Mul(x2) - r.usqr() - r.Mul(lv) - r.usqr() - lv.Copy(r) - lv.Mul(x1) - r.Mul(x0) - lv.usqr() - r.Mul(lv) - r.reduce() - } else { - - // Ghamman & Fouotsa Method - y0 := NewFP12copy(r) - y0.usqr() - y1 := y0.Pow(x) - if SIGN_OF_X == NEGATIVEX { - y1.conj() - } - - x.fshr(1) - y2 := y1.Pow(x) - if SIGN_OF_X == NEGATIVEX { - y2.conj() - } - - x.fshl(1) - y3 := NewFP12copy(r) - y3.conj() - y1.Mul(y3) - - y1.conj() - y1.Mul(y2) - - y2 = y1.Pow(x) - if SIGN_OF_X == NEGATIVEX { - y2.conj() - } - - y3 = y2.Pow(x) - if SIGN_OF_X == NEGATIVEX { - y3.conj() - } - - y1.conj() - y3.Mul(y1) - - y1.conj() - y1.frob(f) - y1.frob(f) - y1.frob(f) - y2.frob(f) - y2.frob(f) - y1.Mul(y2) - - y2 = y3.Pow(x) - if SIGN_OF_X == NEGATIVEX { - y2.conj() - } - - y2.Mul(y0) - y2.Mul(r) - - y1.Mul(y2) - y2.Copy(y3) - y2.frob(f) - y1.Mul(y2) - r.Copy(y1) - r.reduce() - } - return r -} - -/* GLV method */ -func glv(e *BIG) []*BIG { - var u []*BIG - if CURVE_PAIRING_TYPE == BN { - t := NewBIGint(0) - q := NewBIGints(CURVE_Order) - var v []*BIG - - for i := 0; i < 2; i++ { - t.copy(NewBIGints(CURVE_W[i])) // why not just t=new BIG(ROM.CURVE_W[i]); - d := mul(t, e) - v = append(v, NewBIGcopy(d.div(q))) - u = append(u, NewBIGint(0)) - } - u[0].copy(e) - for i := 0; i < 2; i++ { - for j := 0; j < 2; j++ { - t.copy(NewBIGints(CURVE_SB[j][i])) - t.copy(Modmul(v[j], t, q)) - u[i].add(q) - u[i].sub(t) - u[i].Mod(q) - } - } - } else { - q := NewBIGints(CURVE_Order) - x := NewBIGints(CURVE_Bnx) - x2 := smul(x, x) - u = append(u, NewBIGcopy(e)) - u[0].Mod(x2) - u = append(u, NewBIGcopy(e)) - u[1].div(x2) - u[1].rsub(q) - } - return u -} - -/* Galbraith & Scott Method */ -func gs(e *BIG) []*BIG { - var u []*BIG - if CURVE_PAIRING_TYPE == BN { - t := NewBIGint(0) - q := NewBIGints(CURVE_Order) - - var v []*BIG - for i := 0; i < 4; i++ { - t.copy(NewBIGints(CURVE_WB[i])) - d := mul(t, e) - v = append(v, NewBIGcopy(d.div(q))) - u = append(u, NewBIGint(0)) - } - u[0].copy(e) - for i := 0; i < 4; i++ { - for j := 0; j < 4; j++ { - t.copy(NewBIGints(CURVE_BB[j][i])) - t.copy(Modmul(v[j], t, q)) - u[i].add(q) - u[i].sub(t) - u[i].Mod(q) - } - } - } else { - q := NewBIGints(CURVE_Order) - x := NewBIGints(CURVE_Bnx) - w := NewBIGcopy(e) - for i := 0; i < 3; i++ { - u = append(u, NewBIGcopy(w)) - u[i].Mod(x) - w.div(x) - } - u = append(u, NewBIGcopy(w)) - if SIGN_OF_X == NEGATIVEX { - u[1].copy(Modneg(u[1], q)) - u[3].copy(Modneg(u[3], q)) - } - } - return u -} - -/* Multiply P by e in group G1 */ -func G1mul(P *ECP, e *BIG) *ECP { - var R *ECP - if USE_GLV { - R = NewECP() - R.Copy(P) - Q := NewECP() - Q.Copy(P) - Q.Affine() - q := NewBIGints(CURVE_Order) - cru := NewFPbig(NewBIGints(CURVE_Cru)) - t := NewBIGint(0) - u := glv(e) - Q.getx().mul(cru) - - np := u[0].nbits() - t.copy(Modneg(u[0], q)) - nn := t.nbits() - if nn < np { - u[0].copy(t) - R.Neg() - } - - np = u[1].nbits() - t.copy(Modneg(u[1], q)) - nn = t.nbits() - if nn < np { - u[1].copy(t) - Q.Neg() - } - u[0].norm() - u[1].norm() - R = R.Mul2(u[0], Q, u[1]) - - } else { - R = P.mul(e) - } - return R -} - -/* Multiply P by e in group G2 */ -func G2mul(P *ECP2, e *BIG) *ECP2 { - var R *ECP2 - if USE_GS_G2 { - var Q []*ECP2 - f := NewFP2bigs(NewBIGints(Fra), NewBIGints(Frb)) - - if SEXTIC_TWIST == M_TYPE { - f.inverse() - f.norm() - } - - q := NewBIGints(CURVE_Order) - u := gs(e) - - t := NewBIGint(0) - Q = append(Q, NewECP2()) - Q[0].Copy(P) - for i := 1; i < 4; i++ { - Q = append(Q, NewECP2()) - Q[i].Copy(Q[i-1]) - Q[i].frob(f) - } - for i := 0; i < 4; i++ { - np := u[i].nbits() - t.copy(Modneg(u[i], q)) - nn := t.nbits() - if nn < np { - u[i].copy(t) - Q[i].neg() - } - u[i].norm() - } - - R = mul4(Q, u) - - } else { - R = P.mul(e) - } - return R -} - -/* f=f^e */ -/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */ -func GTpow(d *FP12, e *BIG) *FP12 { - var r *FP12 - if USE_GS_GT { - var g []*FP12 - f := NewFP2bigs(NewBIGints(Fra), NewBIGints(Frb)) - q := NewBIGints(CURVE_Order) - t := NewBIGint(0) - - u := gs(e) - - g = append(g, NewFP12copy(d)) - for i := 1; i < 4; i++ { - g = append(g, NewFP12()) - g[i].Copy(g[i-1]) - g[i].frob(f) - } - for i := 0; i < 4; i++ { - np := u[i].nbits() - t.copy(Modneg(u[i], q)) - nn := t.nbits() - if nn < np { - u[i].copy(t) - g[i].conj() - } - u[i].norm() - } - r = pow4(g, u) - } else { - r = d.Pow(e) - } - return r -} - -/* test G1 group membership */ - func G1member(P *ECP) bool { - q := NewBIGints(CURVE_Order) - if P.Is_infinity() {return false} - W:=G1mul(P,q) - if !W.Is_infinity() {return false} - return true - } - -/* test G2 group membership */ - func G2member(P *ECP2) bool { - q := NewBIGints(CURVE_Order) - if P.Is_infinity() {return false} - W:=G2mul(P,q) - if !W.Is_infinity() {return false} - return true - } - -/* test group membership - no longer needed*/ -/* Check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */ - -func GTmember(m *FP12) bool { - if m.Isunity() {return false} - r:=NewFP12copy(m) - r.conj() - r.Mul(m) - if !r.Isunity() {return false} - - f:=NewFP2bigs(NewBIGints(Fra),NewBIGints(Frb)) - - r.Copy(m); r.frob(f); r.frob(f) - w:=NewFP12copy(r); w.frob(f); w.frob(f) - w.Mul(m) - if !w.Equals(r) {return false} - - q := NewBIGints(CURVE_Order) - w.Copy(m) - r.Copy(GTpow(w,q)) - if !r.Isunity() {return false} - return true -} - diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ROM.go b/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ROM.go deleted file mode 100644 index 2e2d838cdd2..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/FP256BN/ROM.go +++ /dev/null @@ -1,66 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* Fixed Data in ROM - Field and Curve parameters */ - -package FP256BN - -// Base Bits= 56 -var Modulus = [...]Chunk{0x292DDBAED33013, 0x65FB12980A82D3, 0x5EEE71A49F0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF} -var ROI = [...]Chunk{0x292DDBAED33012, 0x65FB12980A82D3, 0x5EEE71A49F0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF} -var R2modp = [...]Chunk{0xEDE336303B9F8B, 0x92FFEE9FEC54E8, 0x13C1C063C55F79, 0xA12F2EAC0123FA, 0x8E559B2A} - -const MConst Chunk = 0x6C964E0537E5E5 - -const CURVE_Cof_I int = 1 -const CURVE_A int = 0 -const CURVE_B_I int = 3 - -var CURVE_B = [...]Chunk{0x3, 0x0, 0x0, 0x0, 0x0} -var CURVE_Order = [...]Chunk{0x2D536CD10B500D, 0x65FB1299921AF6, 0x5EEE71A49E0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF} -var CURVE_Gx = [...]Chunk{0x1, 0x0, 0x0, 0x0, 0x0} -var CURVE_Gy = [...]Chunk{0x2, 0x0, 0x0, 0x0, 0x0} - -var Fra = [...]Chunk{0x760328AF943106, 0x71511E3AB28F74, 0x8DDB0867CF39A1, 0xCA786F352D1A6E, 0x3D617662} -var Frb = [...]Chunk{0xB32AB2FF3EFF0D, 0xF4A9F45D57F35E, 0xD113693CCFD33A, 0x3584819819CB83, 0xC29E899D} -var CURVE_Bnx = [...]Chunk{0x82F5C030B0A801, 0x68, 0x0, 0x0, 0x0} -var CURVE_Cof = [...]Chunk{0x1, 0x0, 0x0, 0x0, 0x0} -var CURVE_Cru = [...]Chunk{0x1C0A24A3A1B807, 0xD79DF1932D1EDB, 0x40921018659BCD, 0x13988E1, 0x0} -var CURVE_Pxa = [...]Chunk{0x2616B689C09EFB, 0x539A12BF843CD2, 0x577C28913ACE1C, 0xB4C96C2028560F, 0xFE0C3350} -var CURVE_Pxb = [...]Chunk{0x69ED34A37E6A2B, 0x78E287D03589D2, 0xC637D813B924DD, 0x738AC054DB5AE1, 0x4EA66057} -var CURVE_Pya = [...]Chunk{0x9B481BEDC27FF, 0x24758D615848E9, 0x75124E3E51EFCB, 0xC542A3B376770D, 0x702046E7} -var CURVE_Pyb = [...]Chunk{0x1281114AAD049B, 0xBE80821A98B3E0, 0x49297EB29F8B4C, 0xD388C29042EEA6, 0x554E3BC} -var CURVE_W = [2][5]Chunk{{0xF0036E1B054003, 0xFFFFFFFE78663A, 0xFFFF, 0x0, 0x0}, {0x5EB8061615001, 0xD1, 0x0, 0x0, 0x0}} -var CURVE_SB = [2][2][5]Chunk{{{0xF5EEEE7C669004, 0xFFFFFFFE78670B, 0xFFFF, 0x0, 0x0}, {0x5EB8061615001, 0xD1, 0x0, 0x0, 0x0}}, {{0x5EB8061615001, 0xD1, 0x0, 0x0, 0x0}, {0x3D4FFEB606100A, 0x65FB129B19B4BB, 0x5EEE71A49D0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF}}} -var CURVE_WB = [4][5]Chunk{{0x20678F0D30A800, 0x55555554D2CC10, 0x5555, 0x0, 0x0}, {0xD6764C0D7DC805, 0x8FBEA10BC3AD1A, 0x806160104467DE, 0xD105EB, 0x0}, {0xACB6061F173803, 0x47DF5085E1D6C1, 0xC030B0082233EF, 0x6882F5, 0x0}, {0x26530F6E91F801, 0x55555554D2CCE1, 0x5555, 0x0, 0x0}} -var CURVE_BB = [4][4][5]Chunk{{{0xAA5DACA05AA80D, 0x65FB1299921A8D, 0x5EEE71A49E0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF}, {0xAA5DACA05AA80C, 0x65FB1299921A8D, 0x5EEE71A49E0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF}, {0xAA5DACA05AA80C, 0x65FB1299921A8D, 0x5EEE71A49E0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF}, {0x5EB8061615002, 0xD1, 0x0, 0x0, 0x0}}, {{0x5EB8061615001, 0xD1, 0x0, 0x0, 0x0}, {0xAA5DACA05AA80C, 0x65FB1299921A8D, 0x5EEE71A49E0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF}, {0xAA5DACA05AA80D, 0x65FB1299921A8D, 0x5EEE71A49E0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF}, {0xAA5DACA05AA80C, 0x65FB1299921A8D, 0x5EEE71A49E0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF}}, {{0x5EB8061615002, 0xD1, 0x0, 0x0, 0x0}, {0x5EB8061615001, 0xD1, 0x0, 0x0, 0x0}, {0x5EB8061615001, 0xD1, 0x0, 0x0, 0x0}, {0x5EB8061615001, 0xD1, 0x0, 0x0, 0x0}}, {{0x82F5C030B0A802, 0x68, 0x0, 0x0, 0x0}, {0xBD700C2C2A002, 0x1A2, 0x0, 0x0, 0x0}, {0x2767EC6FAA000A, 0x65FB1299921A25, 0x5EEE71A49E0CDC, 0xFFFCF0CD46E5F2, 0xFFFFFFFF}, {0x82F5C030B0A802, 0x68, 0x0, 0x0, 0x0}}} - diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/GCM.go b/vendor/github.com/hyperledger/fabric-amcl/core/GCM.go deleted file mode 100644 index 5efa4446f01..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/GCM.go +++ /dev/null @@ -1,452 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* -* Implementation of the AES-GCM Encryption/Authentication -* -* Some restrictions.. -* 1. Only for use with AES -* 2. Returned tag is always 128-bits. Truncate at your own risk. -* 3. The order of function calls must follow some rules -* -* Typical sequence of calls.. -* 1. call GCM_init -* 2. call GCM_add_header any number of times, as long as length of header is multiple of 16 bytes (block size) -* 3. call GCM_add_header one last time with any length of header -* 4. call GCM_add_cipher any number of times, as long as length of cipher/plaintext is multiple of 16 bytes -* 5. call GCM_add_cipher one last time with any length of cipher/plaintext -* 6. call GCM_finish to extract the tag. -* -* See http://www.mindspring.com/~dmcgrew/gcm-nist-6.pdf - */ - -package core - -import ( - // "fmt" - "strconv" -) - -const gcm_NB int = 4 -const GCM_ACCEPTING_HEADER int = 0 -const GCM_ACCEPTING_CIPHER int = 1 -const GCM_NOT_ACCEPTING_MORE int = 2 -const GCM_FINISHED int = 3 -const GCM_ENCRYPTING int = 0 -const GCM_DECRYPTING int = 1 - -type GCM struct { - table [128][4]uint32 /* 2k bytes */ - stateX [16]byte - Y_0 [16]byte - counter int - lenA [2]uint32 - lenC [2]uint32 - status int - a *AES -} - -func gcm_pack(b [4]byte) uint32 { /* pack bytes into a 32-bit Word */ - return ((uint32(b[0]) & 0xff) << 24) | ((uint32(b[1]) & 0xff) << 16) | ((uint32(b[2]) & 0xff) << 8) | (uint32(b[3]) & 0xff) -} - -func gcm_unpack(a uint32) [4]byte { /* unpack bytes from a word */ - var b = [4]byte{byte((a >> 24) & 0xff), byte((a >> 16) & 0xff), byte((a >> 8) & 0xff), byte(a & 0xff)} - return b -} - -func (G *GCM) precompute(H []byte) { - var b [4]byte - j := 0 - for i := 0; i < gcm_NB; i++ { - b[0] = H[j] - b[1] = H[j+1] - b[2] = H[j+2] - b[3] = H[j+3] - G.table[0][i] = gcm_pack(b) - j += 4 - } - for i := 1; i < 128; i++ { - c := uint32(0) - for j := 0; j < gcm_NB; j++ { - G.table[i][j] = c | (G.table[i-1][j])>>1 - c = G.table[i-1][j] << 31 - } - if c != 0 { - G.table[i][0] ^= 0xE1000000 - } /* irreducible polynomial */ - } -} - -func (G *GCM) gf2mul() { /* gf2m mul - Z=H*X mod 2^128 */ - var P [4]uint32 - - for i := 0; i < 4; i++ { - P[i] = 0 - } - j := uint(8) - m := 0 - for i := 0; i < 128; i++ { - j-- - c := uint32((G.stateX[m] >> j) & 1) - c = ^c + 1 - for k := 0; k < gcm_NB; k++ { - P[k] ^= (G.table[i][k] & c) - } - if j == 0 { - j = 8 - m++ - if m == 16 { - break - } - } - } - j = 0 - for i := 0; i < gcm_NB; i++ { - b := gcm_unpack(P[i]) - G.stateX[j] = b[0] - G.stateX[j+1] = b[1] - G.stateX[j+2] = b[2] - G.stateX[j+3] = b[3] - j += 4 - } -} - -func (G *GCM) wrap() { /* Finish off GHASH */ - var F [4]uint32 - var L [16]byte - - /* convert lengths from bytes to bits */ - F[0] = (G.lenA[0] << 3) | (G.lenA[1]&0xE0000000)>>29 - F[1] = G.lenA[1] << 3 - F[2] = (G.lenC[0] << 3) | (G.lenC[1]&0xE0000000)>>29 - F[3] = G.lenC[1] << 3 - j := 0 - for i := 0; i < gcm_NB; i++ { - b := gcm_unpack(F[i]) - L[j] = b[0] - L[j+1] = b[1] - L[j+2] = b[2] - L[j+3] = b[3] - j += 4 - } - for i := 0; i < 16; i++ { - G.stateX[i] ^= L[i] - } - G.gf2mul() -} - -func (G *GCM) ghash(plain []byte, len int) bool { - if G.status == GCM_ACCEPTING_HEADER { - G.status = GCM_ACCEPTING_CIPHER - } - if G.status != GCM_ACCEPTING_CIPHER { - return false - } - - j := 0 - for j < len { - for i := 0; i < 16 && j < len; i++ { - G.stateX[i] ^= plain[j] - j++ - G.lenC[1]++ - if G.lenC[1] == 0 { - G.lenC[0]++ - } - } - G.gf2mul() - } - if len%16 != 0 { - G.status = GCM_NOT_ACCEPTING_MORE - } - return true -} - -/* Initialize GCM mode */ -func (G *GCM) Init(nk int, key []byte, niv int, iv []byte) { /* iv size niv is usually 12 bytes (96 bits). AES key size nk can be 16,24 or 32 bytes */ - var H [16]byte - - for i := 0; i < 16; i++ { - H[i] = 0 - G.stateX[i] = 0 - } - - G.a = new(AES) - - G.a.Init(AES_ECB, nk, key, iv) - G.a.ecb_encrypt(H[:]) /* E(K,0) */ - G.precompute(H[:]) - - G.lenA[0] = 0 - G.lenC[0] = 0 - G.lenA[1] = 0 - G.lenC[1] = 0 - if niv == 12 { - for i := 0; i < 12; i++ { - G.a.f[i] = iv[i] - } - b := gcm_unpack(uint32(1)) - G.a.f[12] = b[0] - G.a.f[13] = b[1] - G.a.f[14] = b[2] - G.a.f[15] = b[3] /* initialise IV */ - for i := 0; i < 16; i++ { - G.Y_0[i] = G.a.f[i] - } - } else { - G.status = GCM_ACCEPTING_CIPHER - G.ghash(iv, niv) /* GHASH(H,0,IV) */ - G.wrap() - for i := 0; i < 16; i++ { - G.a.f[i] = G.stateX[i] - G.Y_0[i] = G.a.f[i] - G.stateX[i] = 0 - } - G.lenA[0] = 0 - G.lenC[0] = 0 - G.lenA[1] = 0 - G.lenC[1] = 0 - } - G.status = GCM_ACCEPTING_HEADER -} - -/* Add Header data - included but not encrypted */ -func (G *GCM) Add_header(header []byte, len int) bool { /* Add some header. Won't be encrypted, but will be authenticated. len is length of header */ - if G.status != GCM_ACCEPTING_HEADER { - return false - } - - j := 0 - for j < len { - for i := 0; i < 16 && j < len; i++ { - G.stateX[i] ^= header[j] - j++ - G.lenA[1]++ - if G.lenA[1] == 0 { - G.lenA[0]++ - } - } - G.gf2mul() - } - if len%16 != 0 { - G.status = GCM_ACCEPTING_CIPHER - } - - return true -} - -/* Add Plaintext - included and encrypted */ -func (G *GCM) Add_plain(plain []byte, len int) []byte { - var B [16]byte - var b [4]byte - - cipher := make([]byte, len) - var counter uint32 = 0 - if G.status == GCM_ACCEPTING_HEADER { - G.status = GCM_ACCEPTING_CIPHER - } - if G.status != GCM_ACCEPTING_CIPHER { - return nil - } - - j := 0 - for j < len { - - b[0] = G.a.f[12] - b[1] = G.a.f[13] - b[2] = G.a.f[14] - b[3] = G.a.f[15] - counter = gcm_pack(b) - counter++ - b = gcm_unpack(counter) - G.a.f[12] = b[0] - G.a.f[13] = b[1] - G.a.f[14] = b[2] - G.a.f[15] = b[3] /* increment counter */ - for i := 0; i < 16; i++ { - B[i] = G.a.f[i] - } - G.a.ecb_encrypt(B[:]) /* encrypt it */ - - for i := 0; i < 16 && j < len; i++ { - cipher[j] = (plain[j] ^ B[i]) - G.stateX[i] ^= cipher[j] - j++ - G.lenC[1]++ - if G.lenC[1] == 0 { - G.lenC[0]++ - } - } - G.gf2mul() - } - if len%16 != 0 { - G.status = GCM_NOT_ACCEPTING_MORE - } - return cipher -} - -/* Add Ciphertext - decrypts to plaintext */ -func (G *GCM) Add_cipher(cipher []byte, len int) []byte { - var B [16]byte - var b [4]byte - - plain := make([]byte, len) - var counter uint32 = 0 - - if G.status == GCM_ACCEPTING_HEADER { - G.status = GCM_ACCEPTING_CIPHER - } - if G.status != GCM_ACCEPTING_CIPHER { - return nil - } - - j := 0 - for j < len { - b[0] = G.a.f[12] - b[1] = G.a.f[13] - b[2] = G.a.f[14] - b[3] = G.a.f[15] - counter = gcm_pack(b) - counter++ - b = gcm_unpack(counter) - G.a.f[12] = b[0] - G.a.f[13] = b[1] - G.a.f[14] = b[2] - G.a.f[15] = b[3] /* increment counter */ - for i := 0; i < 16; i++ { - B[i] = G.a.f[i] - } - G.a.ecb_encrypt(B[:]) /* encrypt it */ - for i := 0; i < 16 && j < len; i++ { - oc := cipher[j] - plain[j] = (cipher[j] ^ B[i]) - G.stateX[i] ^= oc - j++ - G.lenC[1]++ - if G.lenC[1] == 0 { - G.lenC[0]++ - } - } - G.gf2mul() - } - if len%16 != 0 { - G.status = GCM_NOT_ACCEPTING_MORE - } - return plain -} - -/* Finish and extract Tag */ -func (G *GCM) Finish(extract bool) [16]byte { /* Finish off GHASH and extract tag (MAC) */ - var tag [16]byte - - G.wrap() - /* extract tag */ - if extract { - G.a.ecb_encrypt(G.Y_0[:]) /* E(K,Y0) */ - for i := 0; i < 16; i++ { - G.Y_0[i] ^= G.stateX[i] - } - for i := 0; i < 16; i++ { - tag[i] = G.Y_0[i] - G.Y_0[i] = 0 - G.stateX[i] = 0 - } - } - G.status = GCM_FINISHED - G.a.End() - return tag -} - -func hex2bytes(s string) []byte { - lgh := len(s) - data := make([]byte, lgh/2) - - for i := 0; i < lgh; i += 2 { - a, _ := strconv.ParseInt(s[i:i+2], 16, 32) - data[i/2] = byte(a) - } - return data -} - -/* -func main() { - - KT:="feffe9928665731c6d6a8f9467308308" - MT:="d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39" - HT:="feedfacedeadbeeffeedfacedeadbeefabaddad2" - - NT:="9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b"; -// Tag should be 619cc5aefffe0bfa462af43c1699d050 - - g:=new(GCM) - - M:=hex2bytes(MT) - H:=hex2bytes(HT) - N:=hex2bytes(NT) - K:=hex2bytes(KT) - - lenM:=len(M) - lenH:=len(H) - lenK:=len(K) - lenIV:=len(N) - - fmt.Printf("Plaintext=\n"); - for i:=0;i. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* - * Implementation of the Secure Hashing Algorithm (SHA-256) - * - * Generates a 256 bit message digest. It should be impossible to come - * come up with two messages that hash to the same value ("collision free"). - * - * For use with byte-oriented messages only. - */ - -package core - -//import "fmt" -const SHA256 int = 32 - -const hash256_H0 uint32 = 0x6A09E667 -const hash256_H1 uint32 = 0xBB67AE85 -const hash256_H2 uint32 = 0x3C6EF372 -const hash256_H3 uint32 = 0xA54FF53A -const hash256_H4 uint32 = 0x510E527F -const hash256_H5 uint32 = 0x9B05688C -const hash256_H6 uint32 = 0x1F83D9AB -const hash256_H7 uint32 = 0x5BE0CD19 - -var hash256_K = [...]uint32{ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2} - -type HASH256 struct { - length [2]uint32 - h [8]uint32 - w [64]uint32 -} - -/* functions */ -func hash256_S(n uint32, x uint32) uint32 { - return (((x) >> n) | ((x) << (32 - n))) -} - -func hash256_R(n uint32, x uint32) uint32 { - return ((x) >> n) -} - -func hash256_Ch(x, y, z uint32) uint32 { - return ((x & y) ^ (^(x) & z)) -} - -func hash256_Maj(x, y, z uint32) uint32 { - return ((x & y) ^ (x & z) ^ (y & z)) -} - -func hash256_Sig0(x uint32) uint32 { - return (hash256_S(2, x) ^ hash256_S(13, x) ^ hash256_S(22, x)) -} - -func hash256_Sig1(x uint32) uint32 { - return (hash256_S(6, x) ^ hash256_S(11, x) ^ hash256_S(25, x)) -} - -func hash256_theta0(x uint32) uint32 { - return (hash256_S(7, x) ^ hash256_S(18, x) ^ hash256_R(3, x)) -} - -func hash256_theta1(x uint32) uint32 { - return (hash256_S(17, x) ^ hash256_S(19, x) ^ hash256_R(10, x)) -} - -func (H *HASH256) transform() { /* basic transformation step */ - for j := 16; j < 64; j++ { - H.w[j] = hash256_theta1(H.w[j-2]) + H.w[j-7] + hash256_theta0(H.w[j-15]) + H.w[j-16] - } - a := H.h[0] - b := H.h[1] - c := H.h[2] - d := H.h[3] - e := H.h[4] - f := H.h[5] - g := H.h[6] - hh := H.h[7] - for j := 0; j < 64; j++ { /* 64 times - mush it up */ - t1 := hh + hash256_Sig1(e) + hash256_Ch(e, f, g) + hash256_K[j] + H.w[j] - t2 := hash256_Sig0(a) + hash256_Maj(a, b, c) - hh = g - g = f - f = e - e = d + t1 - d = c - c = b - b = a - a = t1 + t2 - } - H.h[0] += a - H.h[1] += b - H.h[2] += c - H.h[3] += d - H.h[4] += e - H.h[5] += f - H.h[6] += g - H.h[7] += hh -} - -/* Initialise Hash function */ -func (H *HASH256) Init() { /* initialise */ - for i := 0; i < 64; i++ { - H.w[i] = 0 - } - H.length[0] = 0 - H.length[1] = 0 - H.h[0] = hash256_H0 - H.h[1] = hash256_H1 - H.h[2] = hash256_H2 - H.h[3] = hash256_H3 - H.h[4] = hash256_H4 - H.h[5] = hash256_H5 - H.h[6] = hash256_H6 - H.h[7] = hash256_H7 -} - -func NewHASH256() *HASH256 { - H := new(HASH256) - H.Init() - return H -} - -/* process a single byte */ -func (H *HASH256) Process(byt byte) { /* process the next message byte */ - cnt := (H.length[0] / 32) % 16 - - H.w[cnt] <<= 8 - H.w[cnt] |= uint32(byt & 0xFF) - H.length[0] += 8 - if H.length[0] == 0 { - H.length[1]++ - H.length[0] = 0 - } - if (H.length[0] % 512) == 0 { - H.transform() - } -} - -/* process an array of bytes */ -func (H *HASH256) Process_array(b []byte) { - for i := 0; i < len(b); i++ { - H.Process((b[i])) - } -} - -/* process a 32-bit integer */ -func (H *HASH256) Process_num(n int32) { - H.Process(byte((n >> 24) & 0xff)) - H.Process(byte((n >> 16) & 0xff)) - H.Process(byte((n >> 8) & 0xff)) - H.Process(byte(n & 0xff)) -} - -/* Generate 32-byte Hash */ -func (H *HASH256) Hash() []byte { /* pad message and finish - supply digest */ - var digest [32]byte - len0 := H.length[0] - len1 := H.length[1] - H.Process(0x80) - for (H.length[0] % 512) != 448 { - H.Process(0) - } - H.w[14] = len1 - H.w[15] = len0 - H.transform() - for i := 0; i < 32; i++ { /* convert to bytes */ - digest[i] = byte((H.h[i/4] >> uint(8*(3-i%4))) & 0xff) - } - H.Init() - return digest[0:32] -} - -/* test program: should produce digest */ - -//248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1 -/* -func main() { - - test := []byte("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") - sh:=NewHASH256() - - for i:=0;i. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* - * Implementation of the Secure Hashing Algorithm (SHA-384) - * - * Generates a 384 bit message digest. It should be impossible to come - * come up with two messages that hash to the same value ("collision free"). - * - * For use with byte-oriented messages only. - */ - -package core - -//import "fmt" - -const SHA384 int = 48 - -const hash384_H0 uint64 = 0xcbbb9d5dc1059ed8 -const hash384_H1 uint64 = 0x629a292a367cd507 -const hash384_H2 uint64 = 0x9159015a3070dd17 -const hash384_H3 uint64 = 0x152fecd8f70e5939 -const hash384_H4 uint64 = 0x67332667ffc00b31 -const hash384_H5 uint64 = 0x8eb44a8768581511 -const hash384_H6 uint64 = 0xdb0c2e0d64f98fa7 -const hash384_H7 uint64 = 0x47b5481dbefa4fa4 - -var hash384_K = [...]uint64{ - 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, - 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, - 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, - 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, - 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, - 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, - 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, - 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, - 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, - 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, - 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, - 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, - 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, - 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, - 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, - 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, - 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, - 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, - 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, - 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817} - -type HASH384 struct { - length [2]uint64 - h [8]uint64 - w [80]uint64 -} - -/* functions */ -func hash384_S(n uint64, x uint64) uint64 { - return (((x) >> n) | ((x) << (64 - n))) -} - -func hash384_R(n uint64, x uint64) uint64 { - return ((x) >> n) -} - -func hash384_Ch(x, y, z uint64) uint64 { - return ((x & y) ^ (^(x) & z)) -} - -func hash384_Maj(x, y, z uint64) uint64 { - return ((x & y) ^ (x & z) ^ (y & z)) -} - -func hash384_Sig0(x uint64) uint64 { - return (hash384_S(28, x) ^ hash384_S(34, x) ^ hash384_S(39, x)) -} - -func hash384_Sig1(x uint64) uint64 { - return (hash384_S(14, x) ^ hash384_S(18, x) ^ hash384_S(41, x)) -} - -func hash384_theta0(x uint64) uint64 { - return (hash384_S(1, x) ^ hash384_S(8, x) ^ hash384_R(7, x)) -} - -func hash384_theta1(x uint64) uint64 { - return (hash384_S(19, x) ^ hash384_S(61, x) ^ hash384_R(6, x)) -} - -func (H *HASH384) transform() { /* basic transformation step */ - for j := 16; j < 80; j++ { - H.w[j] = hash384_theta1(H.w[j-2]) + H.w[j-7] + hash384_theta0(H.w[j-15]) + H.w[j-16] - } - a := H.h[0] - b := H.h[1] - c := H.h[2] - d := H.h[3] - e := H.h[4] - f := H.h[5] - g := H.h[6] - hh := H.h[7] - for j := 0; j < 80; j++ { /* 80 times - mush it up */ - t1 := hh + hash384_Sig1(e) + hash384_Ch(e, f, g) + hash384_K[j] + H.w[j] - t2 := hash384_Sig0(a) + hash384_Maj(a, b, c) - hh = g - g = f - f = e - e = d + t1 - d = c - c = b - b = a - a = t1 + t2 - } - H.h[0] += a - H.h[1] += b - H.h[2] += c - H.h[3] += d - H.h[4] += e - H.h[5] += f - H.h[6] += g - H.h[7] += hh -} - -/* Initialise Hash function */ -func (H *HASH384) Init() { /* initialise */ - for i := 0; i < 80; i++ { - H.w[i] = 0 - } - H.length[0] = 0 - H.length[1] = 0 - H.h[0] = hash384_H0 - H.h[1] = hash384_H1 - H.h[2] = hash384_H2 - H.h[3] = hash384_H3 - H.h[4] = hash384_H4 - H.h[5] = hash384_H5 - H.h[6] = hash384_H6 - H.h[7] = hash384_H7 -} - -func NewHASH384() *HASH384 { - H := new(HASH384) - H.Init() - return H -} - -/* process a single byte */ -func (H *HASH384) Process(byt byte) { /* process the next message byte */ - cnt := (H.length[0] / 64) % 16 - - H.w[cnt] <<= 8 - H.w[cnt] |= uint64(byt & 0xFF) - H.length[0] += 8 - if H.length[0] == 0 { - H.length[1]++ - H.length[0] = 0 - } - if (H.length[0] % 1024) == 0 { - H.transform() - } -} - -/* process an array of bytes */ -func (H *HASH384) Process_array(b []byte) { - for i := 0; i < len(b); i++ { - H.Process((b[i])) - } -} - -/* process a 32-bit integer */ -func (H *HASH384) Process_num(n int32) { - H.Process(byte((n >> 24) & 0xff)) - H.Process(byte((n >> 16) & 0xff)) - H.Process(byte((n >> 8) & 0xff)) - H.Process(byte(n & 0xff)) -} - -/* Generate 32-byte Hash */ -func (H *HASH384) Hash() []byte { /* pad message and finish - supply digest */ - var digest [48]byte - len0 := H.length[0] - len1 := H.length[1] - H.Process(0x80) - for (H.length[0] % 1024) != 896 { - H.Process(0) - } - H.w[14] = len1 - H.w[15] = len0 - H.transform() - for i := 0; i < 48; i++ { /* convert to bytes */ - digest[i] = byte((H.h[i/8] >> uint(8*(7-i%8))) & 0xff) - } - H.Init() - return digest[0:48] -} - -/* test program: should produce digest */ - -//09330c33f71147e8 3d192fc782cd1b47 53111b173b3b05d2 2fa08086e3b0f712 fcc7c71a557e2db9 66c3e9fa91746039 -/* -func main() { - - test := []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") - sh:=NewHASH384() - - for i:=0;i. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* - * Implementation of the Secure Hashing Algorithm (SHA-384) - * - * Generates a 384 bit message digest. It should be impossible to come - * come up with two messages that hash to the same value ("collision free"). - * - * For use with byte-oriented messages only. - */ - -package core - -//import "fmt" - -const SHA512 int = 64 - -const hash512_H0 uint64 = 0x6a09e667f3bcc908 -const hash512_H1 uint64 = 0xbb67ae8584caa73b -const hash512_H2 uint64 = 0x3c6ef372fe94f82b -const hash512_H3 uint64 = 0xa54ff53a5f1d36f1 -const hash512_H4 uint64 = 0x510e527fade682d1 -const hash512_H5 uint64 = 0x9b05688c2b3e6c1f -const hash512_H6 uint64 = 0x1f83d9abfb41bd6b -const hash512_H7 uint64 = 0x5be0cd19137e2179 - -var hash512_K = [...]uint64{ - 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, - 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, - 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, - 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694, - 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, - 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, - 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, - 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70, - 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df, - 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b, - 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, - 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, - 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, - 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, - 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec, - 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, - 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, - 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b, - 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c, - 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817} - -type HASH512 struct { - length [2]uint64 - h [8]uint64 - w [80]uint64 -} - -/* functions */ -func hash512_S(n uint64, x uint64) uint64 { - return (((x) >> n) | ((x) << (64 - n))) -} - -func hash512_R(n uint64, x uint64) uint64 { - return ((x) >> n) -} - -func hash512_Ch(x, y, z uint64) uint64 { - return ((x & y) ^ (^(x) & z)) -} - -func hash512_Maj(x, y, z uint64) uint64 { - return ((x & y) ^ (x & z) ^ (y & z)) -} - -func hash512_Sig0(x uint64) uint64 { - return (hash512_S(28, x) ^ hash512_S(34, x) ^ hash512_S(39, x)) -} - -func hash512_Sig1(x uint64) uint64 { - return (hash512_S(14, x) ^ hash512_S(18, x) ^ hash512_S(41, x)) -} - -func hash512_theta0(x uint64) uint64 { - return (hash512_S(1, x) ^ hash512_S(8, x) ^ hash512_R(7, x)) -} - -func hash512_theta1(x uint64) uint64 { - return (hash512_S(19, x) ^ hash512_S(61, x) ^ hash512_R(6, x)) -} - -func (H *HASH512) transform() { /* basic transformation step */ - for j := 16; j < 80; j++ { - H.w[j] = hash512_theta1(H.w[j-2]) + H.w[j-7] + hash512_theta0(H.w[j-15]) + H.w[j-16] - } - a := H.h[0] - b := H.h[1] - c := H.h[2] - d := H.h[3] - e := H.h[4] - f := H.h[5] - g := H.h[6] - hh := H.h[7] - for j := 0; j < 80; j++ { /* 80 times - mush it up */ - t1 := hh + hash512_Sig1(e) + hash512_Ch(e, f, g) + hash512_K[j] + H.w[j] - t2 := hash512_Sig0(a) + hash512_Maj(a, b, c) - hh = g - g = f - f = e - e = d + t1 - d = c - c = b - b = a - a = t1 + t2 - } - H.h[0] += a - H.h[1] += b - H.h[2] += c - H.h[3] += d - H.h[4] += e - H.h[5] += f - H.h[6] += g - H.h[7] += hh -} - -/* Initialise Hash function */ -func (H *HASH512) Init() { /* initialise */ - for i := 0; i < 80; i++ { - H.w[i] = 0 - } - H.length[0] = 0 - H.length[1] = 0 - H.h[0] = hash512_H0 - H.h[1] = hash512_H1 - H.h[2] = hash512_H2 - H.h[3] = hash512_H3 - H.h[4] = hash512_H4 - H.h[5] = hash512_H5 - H.h[6] = hash512_H6 - H.h[7] = hash512_H7 -} - -func NewHASH512() *HASH512 { - H := new(HASH512) - H.Init() - return H -} - -/* process a single byte */ -func (H *HASH512) Process(byt byte) { /* process the next message byte */ - cnt := (H.length[0] / 64) % 16 - - H.w[cnt] <<= 8 - H.w[cnt] |= uint64(byt & 0xFF) - H.length[0] += 8 - if H.length[0] == 0 { - H.length[1]++ - H.length[0] = 0 - } - if (H.length[0] % 1024) == 0 { - H.transform() - } -} - -/* process an array of bytes */ -func (H *HASH512) Process_array(b []byte) { - for i := 0; i < len(b); i++ { - H.Process((b[i])) - } -} - -/* process a 32-bit integer */ -func (H *HASH512) Process_num(n int32) { - H.Process(byte((n >> 24) & 0xff)) - H.Process(byte((n >> 16) & 0xff)) - H.Process(byte((n >> 8) & 0xff)) - H.Process(byte(n & 0xff)) -} - -/* Generate 64-byte Hash */ -func (H *HASH512) Hash() []byte { /* pad message and finish - supply digest */ - var digest [64]byte - len0 := H.length[0] - len1 := H.length[1] - H.Process(0x80) - for (H.length[0] % 1024) != 896 { - H.Process(0) - } - H.w[14] = len1 - H.w[15] = len0 - H.transform() - for i := 0; i < 64; i++ { /* convert to bytes */ - digest[i] = byte((H.h[i/8] >> uint(8*(7-i%8))) & 0xff) - } - H.Init() - return digest[0:64] -} - -/* test program: should produce digest */ - -//8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018 501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909 -/* -func main() { - - test := []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") - sh:=NewHASH512() - - for i:=0;i. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* - * Implementation of the Secure Hashing Algorithm (SHA-256) - * - * Generates a 256 bit message digest. It should be impossible to come - * come up with two messages that hash to the same value ("collision free"). - * - * For use with byte-oriented messages only. - */ - -package core - -const MC_SHA2 int=2 -const MC_SHA3 int=3 - -/* Convert Integer to n-byte array */ -func InttoBytes(n int, len int) []byte { - var b []byte - var i int - for i = 0; i < len; i++ { - b = append(b, 0) - } - i = len - for n > 0 && i > 0 { - i-- - b[i] = byte(n & 0xff) - n /= 256 - } - return b -} -/* general purpose hashing of Byte array|integer|Byte array. Output of length olen, padded with leading zeros if required */ - -func GPhashit(hash int,hlen int, olen int, A []byte, n int32, B []byte) []byte { - var R []byte - if hash == MC_SHA2 { - if hlen == SHA256 { - H := NewHASH256() - if A != nil { - H.Process_array(A) - } - if n >= 0 { - H.Process_num(int32(n)) - } - if B != nil { - H.Process_array(B) - } - R = H.Hash() - } - if hlen == SHA384 { - H := NewHASH384() - if A != nil { - H.Process_array(A) - } - if n >= 0 { - H.Process_num(int32(n)) - } - if B != nil { - H.Process_array(B) - } - R = H.Hash() - } - if hlen == SHA512 { - H := NewHASH512() - if A != nil { - H.Process_array(A) - } - if n >= 0 { - H.Process_num(int32(n)) - } - if B != nil { - H.Process_array(B) - } - R = H.Hash() - } - } - if hash == MC_SHA3 { - H := NewSHA3(hlen) - if A != nil { - H.Process_array(A) - } - if n >= 0 { - H.Process_num(int32(n)) - } - if B != nil { - H.Process_array(B) - } - R = H.Hash() - } - - if R == nil { - return nil - } - - if olen == 0 { - return R - } - var W []byte - for i := 0; i < olen; i++ { - W = append(W, 0) - } - if olen <= hlen { - for i := 0; i < olen; i++ { - W[i] = R[i] - } - } else { - for i := 0; i < hlen; i++ { - W[i+olen-hlen] = R[i] - } - for i := 0; i < olen-hlen; i++ { - W[i] = 0 - } - } - return W -} - -/* Simple hashing of byte array */ -func SPhashit(hash int,hlen int, A []byte) []byte { - return GPhashit(hash,hlen,0,A,-1,nil) -} - -/* Key Derivation Function */ -/* Input octet Z */ -/* Output key of length olen */ - -func KDF2(hash int, sha int, Z []byte, P []byte, olen int) []byte { - /* NOTE: the parameter olen is the length of the output k in bytes */ - hlen := sha - var K []byte - k := 0 - - for i := 0; i < olen; i++ { - K = append(K, 0) - } - - cthreshold := olen / hlen - if olen%hlen != 0 { - cthreshold++ - } - - for counter := 1; counter <= cthreshold; counter++ { - B := GPhashit(hash,sha, 0, Z, int32(counter), P) - if k+hlen > olen { - for i := 0; i < olen%hlen; i++ { - K[k] = B[i] - k++ - } - } else { - for i := 0; i < hlen; i++ { - K[k] = B[i] - k++ - } - } - } - return K -} - -/* Password based Key Derivation Function */ -/* Input password p, salt s, and repeat count */ -/* Output key of length olen */ -func PBKDF2(hash int, sha int, Pass []byte, Salt []byte, rep int, olen int) []byte { - d := olen / sha - if olen%sha != 0 { - d++ - } - - var F []byte - var U []byte - var S []byte - var K []byte - - for i := 0; i < sha; i++ { - F = append(F, 0) - U = append(U, 0) - } - - for i := 1; i <= d; i++ { - for j := 0; j < len(Salt); j++ { - S = append(S, Salt[j]) - } - N := InttoBytes(i, 4) - for j := 0; j < 4; j++ { - S = append(S, N[j]) - } - - HMAC(MC_SHA2, sha, F[:], sha, Pass, S) - - for j := 0; j < sha; j++ { - U[j] = F[j] - } - for j := 2; j <= rep; j++ { - HMAC(MC_SHA2, sha, U[:], sha, Pass, U[:]) - for k := 0; k < sha; k++ { - F[k] ^= U[k] - } - } - for j := 0; j < sha; j++ { - K = append(K, F[j]) - } - } - var key []byte - for i := 0; i < olen; i++ { - key = append(key, K[i]) - } - return key -} - -/* Calculate HMAC of m using key k. HMAC is tag of length olen (which is length of tag) */ -func HMAC(hash int, sha int, tag []byte, olen int, K []byte, M []byte) int { - /* Input is from an octet m * - * olen is requested output length in bytes. k is the key * - * The output is the calculated tag */ - var B []byte - b := 0 - if hash == MC_SHA2 { - b = 64 - if sha > 32 { - b = 128 - } - } - if hash == MC_SHA3 { - b=200-2*sha - } - if b == 0 {return 0} - - var K0 [200]byte - //olen := len(tag) - - for i := 0; i < b; i++ { - K0[i] = 0 - } - - if len(K) > b { - B = SPhashit(hash, sha, K) - for i := 0; i < sha; i++ { - K0[i] = B[i] - } - } else { - for i := 0; i < len(K); i++ { - K0[i] = K[i] - } - } - - for i := 0; i < b; i++ { - K0[i] ^= 0x36 - } - B = GPhashit(hash, sha, 0, K0[0:b], -1, M) - - for i := 0; i < b; i++ { - K0[i] ^= 0x6a - } - B = GPhashit(hash, sha, olen, K0[0:b], -1, B) - - for i := 0; i < olen; i++ { - tag[i] = B[i] - } - - return 1 -} - -func HKDF_Extract(hash int, hlen int, SALT []byte, IKM []byte) []byte { - var PRK []byte - for i:=0;i 0 { - for j := 0; j < len(INFO); j++ { - T = append(T, INFO[j]) - } - T = append(T, byte(n+1)) - HMAC(hash,hlen,K[:],flen,PRK,T); - for j := 0; j < flen; j++ { - OKM = append(OKM, K[j]) - } - } - return OKM -} - - -/* -func main() { - var ikm []byte - var salt []byte - var info []byte - - for i:=0;i<22;i++ {ikm=append(ikm,0x0b)} - for i:=0;i<13;i++ {salt=append(salt,byte(i))} - for i:=0;i<10;i++ {info=append(info,byte(0xf0+i))} - - prk:=core.HKDF_Extract(core.MC_SHA2,32,salt,ikm) - fmt.Printf("PRK= ") - for i := 0; i < len(prk); i++ { - fmt.Printf("%02x", prk[i]) - } - - okm:=core.HKDF_Expand(core.MC_SHA2,32,42,prk,info) - fmt.Printf("\nOKM= ") - for i := 0; i < len(okm); i++ { - fmt.Printf("%02x", okm[i]) - } - -} -*/ - diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/NHS.go b/vendor/github.com/hyperledger/fabric-amcl/core/NHS.go deleted file mode 100644 index 25c07118333..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/NHS.go +++ /dev/null @@ -1,561 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -// NEWHOPE nhs_package main - -package core - -//import "fmt" - -const NHS_PRIME int32 = 0x3001 // q in Hex -const NHS_LGN uint = 10 // Degree n=2^LGN -const NHS_ND uint32 = 0xF7002FFF // 1/(R-q) mod R -const NHS_ONE int32 = 0x2AC8 // R mod q -const NHS_R2MODP uint64 = 0x1620 // R^2 mod q - -const NHS_DEGREE int = (1 << NHS_LGN) -const NHS_WL uint = 32 - -const NHS_inv int32 = 0xeab -const NHS_invpr int32 = 0x2c2a - -var NHS_roots = [1024]int32{0x2ac8, 0x2baf, 0x299b, 0x685, 0x2f04, 0x158d, 0x2d49, 0x24b5, 0x1edc, 0xab3, 0x2a95, 0x24d, 0x3cb, 0x6a8, 0x12f9, 0x15ba, 0x1861, 0x2a89, 0x1c5c, 0xbe6, 0xc1e, 0x2024, 0x207, 0x19ce, 0x2710, 0x1744, 0x18bc, 0x2cd7, 0x396, 0x18d5, 0x1c45, 0xc4, 0x21a6, 0xe03, 0x2b3c, 0x2d91, 0xc5d, 0x432, 0x1fbc, 0xcae, 0x2512, 0x2979, 0x3b2, 0x714, 0xb2e, 0x1a97, 0x1a03, 0x1bcd, 0x2216, 0x2701, 0xa, 0x263c, 0x1179, 0x200c, 0x2d08, 0x1c34, 0x291, 0x2c99, 0x2a5a, 0x723, 0xb1d, 0x1ccc, 0x1fb6, 0x2f58, 0x2bfe, 0x1cda, 0x2a0, 0x5f1, 0x2de, 0x1fc7, 0x1ea8, 0x1719, 0x2fa7, 0x27ec, 0x20ff, 0x12c0, 0x1ac1, 0x2232, 0x2f9b, 0xd3e, 0x2aed, 0x15f0, 0x11e8, 0xed0, 0x26a, 0x1de5, 0xa3f, 0xf43, 0xebf, 0x204e, 0xac7, 0x2d9c, 0x5ea, 0x25d1, 0xb6, 0x49c, 0x995, 0x2555, 0x26e2, 0x100, 0x1878, 0x5aa, 0x2e10, 0x271c, 0xcb, 0x1b4c, 0x2fb8, 0x25b7, 0x1543, 0x2c7b, 0x241a, 0x2223, 0x20ca, 0x24ed, 0x137, 0x1b65, 0x1dc2, 0x7c7, 0x2ec3, 0xd0c, 0x1169, 0x1c7a, 0x1ea1, 0xf89, 0x2199, 0x291d, 0x1088, 0x2046, 0x256d, 0x2bc7, 0x2e9b, 0x41f, 0x1b55, 0x2b38, 0xd0, 0x2e6a, 0x1755, 0x6bc, 0x2724, 0x3ba, 0x222e, 0x2c5c, 0x2da5, 0x213c, 0x10fe, 0x169a, 0x1552, 0x5d3, 0x300, 0x1b5d, 0x1342, 0x2004, 0x256f, 0x2039, 0x667, 0x23b5, 0x1123, 0xdb, 0x2da0, 0xe1e, 0x2f54, 0x2767, 0x154a, 0x40a, 0x11d3, 0x2821, 0xc09, 0x974, 0x694, 0xfbf, 0x27ba, 0x132, 0x83f, 0x2d06, 0x10e, 0x183f, 0x29ae, 0x28c3, 0x2dc9, 0x1144, 0x2c70, 0x2a4a, 0xf3c, 0x1e32, 0x1171, 0x1e43, 0xdd4, 0x2ddf, 0x28d2, 0xfac, 0x3c4, 0x2f19, 0x10a6, 0x2f7, 0xe1d, 0x828, 0x138f, 0x1332, 0xfab, 0xcf6, 0x13f8, 0x24a0, 0x112d, 0x2717, 0x6e7, 0x1044, 0x36e, 0xfe8, 0x6a, 0xba7, 0x1d69, 0x29ec, 0x23b2, 0xaee, 0x16df, 0x1068, 0x1a7e, 0x253f, 0x24c, 0xb33, 0x2683, 0x15ce, 0x1ad3, 0x1a36, 0xc96, 0xaea, 0x260a, 0xce, 0x28b1, 0xe4f, 0x2b11, 0x5f8, 0x1fc4, 0xe77, 0x2366, 0x11f9, 0x153c, 0x24eb, 0x20cd, 0x1398, 0x22, 0x2b97, 0x249b, 0x8eb, 0x12b2, 0x2fe3, 0x29c1, 0x1b00, 0x2663, 0xeaa, 0x2e06, 0xe0, 0x1569, 0x10f5, 0x284e, 0xa38, 0x201d, 0x1c53, 0x1681, 0x1f6f, 0x2f95, 0x2fe8, 0xacb, 0x1680, 0x17fd, 0x2c39, 0x165a, 0x10bb, 0x29d8, 0x2622, 0x1196, 0x884, 0x2a79, 0x140e, 0x2d80, 0x6fa, 0x11b2, 0x26c4, 0x355, 0x1054, 0x29e9, 0x23ed, 0xbe3, 0x24fa, 0x1fb3, 0x10ac, 0x2919, 0x2584, 0x10a4, 0xe85, 0x650, 0x1893, 0x1dc1, 0xd8e, 0x12dc, 0x2d42, 0x284d, 0xfff, 0x250f, 0xacd, 0x13c3, 0x6cc, 0x1a79, 0x1221, 0x2614, 0x270a, 0x1ea, 0x155, 0x2818, 0x222c, 0x2e5b, 0x25d8, 0x1dbf, 0x191c, 0xb0f, 0xdac, 0x1082, 0x12ef, 0x11b6, 0xfa8, 0x2b72, 0x159d, 0x209e, 0x31b, 0x2c7c, 0x14f7, 0xe09, 0x1bb2, 0x1ec7, 0x2404, 0x20ae, 0x6ad, 0xed6, 0x2b70, 0x1c7b, 0x18d1, 0x2732, 0x12da, 0xd56, 0x5c1, 0x1648, 0x18b7, 0x1605, 0x1bc4, 0x280, 0x2ece, 0xc, 0x1aae, 0x1c4, 0x1cdb, 0x22d6, 0x21d8, 0x257c, 0x51f, 0x211b, 0xff, 0x2ee0, 0x2585, 0xe1, 0x2c35, 0x26db, 0x2971, 0x2208, 0x17e1, 0x21be, 0x135e, 0x28d6, 0x2891, 0x1689, 0x2138, 0xb86, 0x2e3a, 0x1204, 0x2d10, 0x2324, 0xf3f, 0x2508, 0x33d, 0xcb2, 0x292a, 0xe27, 0x2e64, 0x29f8, 0x2d46, 0x9b7, 0x20eb, 0x1b7c, 0x9eb, 0x2b2a, 0x58c, 0x27d0, 0x121b, 0x272e, 0x29f6, 0x2dbd, 0x2697, 0x2aac, 0xd6f, 0x1c67, 0x2c5b, 0x108d, 0x363, 0x249d, 0x2d5e, 0x2fd, 0x2cb2, 0x1f8f, 0x20a4, 0xa19, 0x2ac9, 0x19b1, 0x1581, 0x17a2, 0x29eb, 0x1b72, 0x13b0, 0xee4, 0xa8f, 0x2315, 0x5e6, 0x951, 0x2e29, 0xdad, 0x1f2b, 0x224e, 0x37f, 0x1a72, 0xa91, 0x1407, 0x2df9, 0x3ad, 0x23f7, 0x1a24, 0x1d2a, 0x234b, 0x1df3, 0x1143, 0x7ff, 0x1a6d, 0x2774, 0x2690, 0x2ab5, 0x586, 0x2781, 0x2009, 0x2fdd, 0x2881, 0x399, 0x2fb6, 0x144, 0x137f, 0xfa0, 0x2e4c, 0x1c7f, 0x2fac, 0xb09, 0x1264, 0x127b, 0x198c, 0x2b40, 0x230, 0x1cf4, 0x180b, 0xb58, 0x144a, 0x2aec, 0xfb, 0x2602, 0x14ee, 0x783, 0x1098, 0x23d8, 0x203, 0xe9, 0x108a, 0x14b8, 0xeec, 0xc58, 0x1248, 0x243c, 0x28aa, 0x6bf, 0x27c4, 0x276e, 0x19b8, 0x1d11, 0x2e16, 0x472, 0x1464, 0x24b9, 0x662, 0x1097, 0x2067, 0x20d6, 0x171c, 0x4, 0x682, 0x17bb, 0x1186, 0x4f2, 0x3ff, 0x2a43, 0x1dc7, 0x1ae5, 0x8cc, 0x2e7c, 0x2ef8, 0x2ae0, 0x2904, 0xed4, 0x6c5, 0x14ae, 0xb72, 0x11c3, 0x337, 0x2da3, 0x2916, 0x6d8, 0x1cf9, 0x10ee, 0x1800, 0x1ae4, 0xa0d, 0x101b, 0x1a8d, 0x2e98, 0x24cd, 0x813, 0x1aa4, 0x9b9, 0x680, 0x2349, 0x24d1, 0x20f8, 0xe31, 0x249f, 0x216b, 0x12d9, 0x1d21, 0x19db, 0x191a, 0x1dd0, 0x5df, 0x55c, 0x2b86, 0x213, 0xe9e, 0x1ef1, 0x268a, 0x1d5e, 0x1e20, 0x28c1, 0x1379, 0x249, 0x19de, 0x18b, 0x1e41, 0x2a1e, 0x2612, 0x297, 0x2e96, 0x2102, 0x46, 0x1b9f, 0x1a4d, 0x2050, 0x1b32, 0x568, 0x11f7, 0x1829, 0x870, 0x1f4, 0x1dca, 0x990, 0x1df6, 0x2b62, 0x13ec, 0x9f2, 0x1260, 0x2997, 0x1412, 0x1e6d, 0x1694, 0x11ac, 0x2d8b, 0x276f, 0x26f5, 0x233e, 0x2b44, 0x2f5a, 0x2d37, 0x2cb1, 0xc75, 0x98d, 0x1d56, 0x7ae, 0x10e6, 0x113f, 0x17b8, 0xad3, 0x737, 0x221e, 0x1b70, 0x1f3e, 0x2966, 0x18b2, 0x4fa, 0x2044, 0x1312, 0x154e, 0x2029, 0x700, 0x1b45, 0x27a6, 0x226a, 0x21bf, 0x58d, 0x2f11, 0x2e02, 0x17fc, 0x4d2, 0x1757, 0xcb1, 0x2ef1, 0x2582, 0x1276, 0x881, 0x2fc0, 0x104a, 0x670, 0x274f, 0x2b53, 0x19dd, 0x752, 0x1663, 0xcbd, 0x2b2b, 0x2fc6, 0x13b6, 0x21e6, 0x15f6, 0x126b, 0x2637, 0x1cd9, 0x2f50, 0xe82, 0x5b0, 0x24e0, 0x1350, 0x2f24, 0x21f7, 0x1a16, 0x2f3e, 0x167e, 0x1f7d, 0x28a0, 0x16f0, 0xe33, 0x53b, 0x28c5, 0x1500, 0x2f88, 0x26cc, 0x2018, 0x1604, 0x218b, 0x2cd1, 0x9ee, 0x17f3, 0x5fd, 0x1f5a, 0x2d0, 0x2b46, 0x23cc, 0x503, 0x1c46, 0x1cc3, 0x28e2, 0x243e, 0x122b, 0x2e0c, 0xe37, 0x2611, 0x85e, 0x9b8, 0x1b24, 0x762, 0x19b6, 0x3bc, 0x2d50, 0x2079, 0x18da, 0x170a, 0x800, 0xaa2, 0x135a, 0x1a15, 0x13d1, 0xca, 0x2113, 0x2db9, 0xdb2, 0x1a5c, 0x29a9, 0x1488, 0x14c1, 0x2c9, 0x917, 0x28e7, 0x265c, 0xdab, 0x2ab9, 0x2bc6, 0x105b, 0x1839, 0x219c, 0x50, 0x11da, 0x1802, 0xf56, 0x2e6, 0x2190, 0xddb, 0x56e, 0x9d9, 0x1c81, 0x1016, 0x12d6, 0x296f, 0x14b4, 0x1014, 0x1e64, 0x1d90, 0x89f, 0x2bc2, 0x2777, 0x2819, 0x1c65, 0x1a41, 0x5a2, 0x2cd2, 0x427, 0xd71, 0x29c8, 0x1e58, 0x53f, 0x7c5, 0x1dcd, 0x4a1, 0x1268, 0x2597, 0x2926, 0xee, 0x111b, 0x1038, 0xe6c, 0x22dc, 0x2f2f, 0x441, 0x2cfd, 0x1cb0, 0x6a4, 0x2224, 0x620, 0x5dc, 0x16b1, 0x2a1d, 0x1787, 0x20c7, 0x641, 0xd84, 0x1c05, 0x2d0d, 0x2f52, 0x1b8c, 0xd7d, 0x17e8, 0x1589, 0xc73, 0x151b, 0x4e2, 0x1ae9, 0x1b18, 0xb9b, 0x949, 0x2c60, 0x1e7a, 0xd5, 0x1bdc, 0x1f57, 0x1753, 0x124a, 0x559, 0xb76, 0x2334, 0x12d1, 0x1de1, 0x14b2, 0x2faa, 0x1697, 0x147a, 0x5a1, 0x2c30, 0x1c02, 0x1043, 0x2ee1, 0x2402, 0x1cc8, 0x2a16, 0xff7, 0x1364, 0x1b9a, 0x2a53, 0x2f94, 0x294c, 0x1ee5, 0x1a87, 0x2141, 0xd66, 0x953, 0x28a3, 0x2f30, 0x2477, 0x18e3, 0x1035, 0x1fc1, 0x1d68, 0x2fb3, 0x138c, 0x2487, 0x1bf8, 0xd96, 0x1018, 0x748, 0x244e, 0x15bd, 0x175e, 0x2be, 0x23d, 0x1da, 0x176d, 0xc17, 0x24be, 0x2ebb, 0x7d8, 0x100a, 0x759, 0x1db4, 0x2259, 0x23f4, 0x2d59, 0x2847, 0xbf5, 0x1cfe, 0xa20, 0x258, 0x1180, 0x279c, 0x54, 0x2abf, 0xc5c, 0x9f9, 0x3d5, 0x2ce4, 0x165f, 0x23d9, 0x27b9, 0x6f9, 0x281a, 0x169e, 0x627, 0x156d, 0x1ff8, 0x211, 0x2e34, 0x1724, 0x2c2e, 0x2790, 0x2dd5, 0x2bf2, 0xdbc, 0x2884, 0x20a9, 0x2390, 0x1e1a, 0x1b6a, 0x5f7, 0xab7, 0x1333, 0x16ab, 0x28dd, 0x20, 0x30f, 0x24b6, 0x5c2, 0x1ce4, 0x1400, 0x2669, 0x60, 0x156c, 0xe20, 0x26d4, 0x26ab, 0x1ebb, 0x223d, 0x5b4, 0x2025, 0x1e1c, 0xaae, 0x2e08, 0x6cd, 0x1677, 0x13d9, 0x17b5, 0x1046, 0x1d8c, 0x14eb, 0x18d8, 0x1ce5, 0x2478, 0x16ae, 0xb79, 0x23d4, 0x684, 0x156b, 0x567, 0x1a, 0x29ce, 0x83a, 0x19e8, 0x58e, 0x294a, 0x1136, 0x2319, 0x2fba, 0x1a29, 0x1d, 0x1879, 0x291b, 0x19f6, 0x2c2f, 0x21c9, 0x19bb, 0xbbc, 0x26f9, 0xc22, 0x708, 0x11a1, 0x18d3, 0x7f8, 0x28f8, 0x2427, 0x1deb, 0xaed, 0x26aa, 0x2482, 0x203b, 0x2f05, 0x2b82, 0x192f, 0x2df4, 0x8dc, 0x2877, 0xd5e, 0x240e, 0x775, 0x2dae, 0x1d3e, 0x20ba, 0x215b, 0x22d1, 0xeba, 0xf50, 0xaa8, 0x184a, 0x1f67, 0x2e04, 0xc6e, 0x6dd, 0x1a09, 0x27f, 0x494, 0x1426, 0xae3, 0xe15, 0x65f, 0x13c4, 0x105, 0x872, 0x2667, 0x1ff6, 0xd9f, 0x2ca1, 0x2f39, 0x2657, 0x23fd, 0x2405, 0xb73, 0x2294, 0x1f1e, 0x2eba, 0x110a, 0x2cae, 0x141f, 0x22cd, 0x25d6, 0x11c1, 0x1c, 0x2d8e, 0x161a, 0x1aa8, 0x229e, 0x1bf9, 0x7cf, 0x106d, 0x2c40, 0xd93, 0x255e, 0x28c2, 0xc1a, 0x2f17, 0x7ca, 0x2f63, 0xbf} -var NHS_iroots = [1024]int32{0x2ac8, 0x452, 0x297c, 0x666, 0xb4c, 0x2b8, 0x1a74, 0xfd, 0x1a47, 0x1d08, 0x2959, 0x2c36, 0x2db4, 0x56c, 0x254e, 0x1125, 0x2f3d, 0x13bc, 0x172c, 0x2c6b, 0x32a, 0x1745, 0x18bd, 0x8f1, 0x1633, 0x2dfa, 0xfdd, 0x23e3, 0x241b, 0x13a5, 0x578, 0x17a0, 0xa9, 0x104b, 0x1335, 0x24e4, 0x28de, 0x5a7, 0x368, 0x2d70, 0x13cd, 0x2f9, 0xff5, 0x1e88, 0x9c5, 0x2ff7, 0x900, 0xdeb, 0x1434, 0x15fe, 0x156a, 0x24d3, 0x28ed, 0x2c4f, 0x688, 0xaef, 0x2353, 0x1045, 0x2bcf, 0x23a4, 0x270, 0x4c5, 0x21fe, 0xe5b, 0xfbb, 0x1f79, 0x6e4, 0xe68, 0x2078, 0x1160, 0x1387, 0x1e98, 0x22f5, 0x13e, 0x283a, 0x123f, 0x149c, 0x2eca, 0xb14, 0xf37, 0xdde, 0xbe7, 0x386, 0x1abe, 0xa4a, 0x49, 0x14b5, 0x2f36, 0x8e5, 0x1f1, 0x2a57, 0x1789, 0x2f01, 0x91f, 0xaac, 0x266c, 0x2b65, 0x2f4b, 0xa30, 0x2a17, 0x265, 0x253a, 0xfb3, 0x2142, 0x20be, 0x25c2, 0x121c, 0x2d97, 0x2131, 0x1e19, 0x1a11, 0x514, 0x22c3, 0x66, 0xdcf, 0x1540, 0x1d41, 0xf02, 0x815, 0x5a, 0x18e8, 0x1159, 0x103a, 0x2d23, 0x2a10, 0x2d61, 0x1327, 0x403, 0x25c9, 0x7b3, 0x1f0c, 0x1a98, 0x2f21, 0x1fb, 0x2157, 0x99e, 0x1501, 0x640, 0x1e, 0x1d4f, 0x2716, 0xb66, 0x46a, 0x2fdf, 0x1c69, 0xf34, 0xb16, 0x1ac5, 0x1e08, 0xc9b, 0x218a, 0x103d, 0x2a09, 0x4f0, 0x21b2, 0x750, 0x2f33, 0x9f7, 0x2517, 0x236b, 0x15cb, 0x152e, 0x1a33, 0x97e, 0x24ce, 0x2db5, 0xac2, 0x1583, 0x1f99, 0x1922, 0x2513, 0xc4f, 0x615, 0x1298, 0x245a, 0x2f97, 0x2019, 0x2c93, 0x1fbd, 0x291a, 0x8ea, 0x1ed4, 0xb61, 0x1c09, 0x230b, 0x2056, 0x1ccf, 0x1c72, 0x27d9, 0x21e4, 0x2d0a, 0x1f5b, 0xe8, 0x2c3d, 0x2055, 0x72f, 0x222, 0x222d, 0x11be, 0x1e90, 0x11cf, 0x20c5, 0x5b7, 0x391, 0x1ebd, 0x238, 0x73e, 0x653, 0x17c2, 0x2ef3, 0x2fb, 0x27c2, 0x2ecf, 0x847, 0x2042, 0x296d, 0x268d, 0x23f8, 0x7e0, 0x1e2e, 0x2bf7, 0x1ab7, 0x89a, 0xad, 0x21e3, 0x261, 0x2f26, 0x1ede, 0xc4c, 0x299a, 0xfc8, 0xa92, 0xffd, 0x1cbf, 0x14a4, 0x2d01, 0x2a2e, 0x1aaf, 0x1967, 0x1f03, 0xec5, 0x25c, 0x3a5, 0xdd3, 0x2c47, 0x8dd, 0x2945, 0x18ac, 0x197, 0x2f31, 0x4c9, 0x14ac, 0x2be2, 0x166, 0x43a, 0xa94, 0x1b53, 0x293c, 0x212d, 0x6fd, 0x521, 0x109, 0x185, 0x2735, 0x151c, 0x123a, 0x5be, 0x2c02, 0x2b0f, 0x1e7b, 0x1846, 0x297f, 0x2ffd, 0x18e5, 0xf2b, 0xf9a, 0x1f6a, 0x299f, 0xb48, 0x1b9d, 0x2b8f, 0x1eb, 0x12f0, 0x1649, 0x893, 0x83d, 0x2942, 0x757, 0xbc5, 0x1db9, 0x23a9, 0x2115, 0x1b49, 0x1f77, 0x2f18, 0x2dfe, 0xc29, 0x1f69, 0x287e, 0x1b13, 0x9ff, 0x2f06, 0x515, 0x1bb7, 0x24a9, 0x17f6, 0x130d, 0x2dd1, 0x4c1, 0x1675, 0x1d86, 0x1d9d, 0x24f8, 0x55, 0x1382, 0x1b5, 0x2061, 0x1c82, 0x2ebd, 0x4b, 0x2c68, 0x780, 0x24, 0xff8, 0x880, 0x2a7b, 0x54c, 0x971, 0x88d, 0x1594, 0x2802, 0x1ebe, 0x120e, 0xcb6, 0x12d7, 0x15dd, 0xc0a, 0x2c54, 0x208, 0x1bfa, 0x2570, 0x158f, 0x2c82, 0xdb3, 0x10d6, 0x2254, 0x1d8, 0x26b0, 0x2a1b, 0xcec, 0x2572, 0x211d, 0x1c51, 0x148f, 0x616, 0x185f, 0x1a80, 0x1650, 0x538, 0x25e8, 0xf5d, 0x1072, 0x34f, 0x2d04, 0x2a3, 0xb64, 0x2c9e, 0x1f74, 0x3a6, 0x139a, 0x2292, 0x555, 0x96a, 0x244, 0x60b, 0x8d3, 0x1de6, 0x831, 0x2a75, 0x4d7, 0x2616, 0x1485, 0xf16, 0x264a, 0x2bb, 0x609, 0x19d, 0x21da, 0x6d7, 0x234f, 0x2cc4, 0xaf9, 0x20c2, 0xcdd, 0x2f1, 0x1dfd, 0x1c7, 0x247b, 0xec9, 0x1978, 0x770, 0x72b, 0x1ca3, 0xe43, 0x1820, 0xdf9, 0x690, 0x926, 0x3cc, 0x2f20, 0xa7c, 0x121, 0x2f02, 0xee6, 0x2ae2, 0xa85, 0xe29, 0xd2b, 0x1326, 0x2e3d, 0x1553, 0x2ff5, 0x133, 0x2d81, 0x143d, 0x19fc, 0x174a, 0x19b9, 0x2a40, 0x22ab, 0x1d27, 0x8cf, 0x1730, 0x1386, 0x491, 0x212b, 0x2954, 0xf53, 0xbfd, 0x113a, 0x144f, 0x21f8, 0x1b0a, 0x385, 0x2ce6, 0xf63, 0x1a64, 0x48f, 0x2059, 0x1e4b, 0x1d12, 0x1f7f, 0x2255, 0x24f2, 0x16e5, 0x1242, 0xa29, 0x1a6, 0xdd5, 0x7e9, 0x2eac, 0x2e17, 0x8f7, 0x9ed, 0x1de0, 0x1588, 0x2935, 0x1c3e, 0x2534, 0xaf2, 0x2002, 0x7b4, 0x2bf, 0x1d25, 0x2273, 0x1240, 0x176e, 0x29b1, 0x217c, 0x1f5d, 0xa7d, 0x6e8, 0x1f55, 0x104e, 0xb07, 0x241e, 0xc14, 0x618, 0x1fad, 0x2cac, 0x93d, 0x1e4f, 0x2907, 0x281, 0x1bf3, 0x588, 0x277d, 0x1e6b, 0x9df, 0x629, 0x1f46, 0x19a7, 0x3c8, 0x1804, 0x1981, 0x2536, 0x19, 0x6c, 0x1092, 0x1980, 0x13ae, 0xfe4, 0x2f42, 0x9e, 0x2837, 0xea, 0x23e7, 0x73f, 0xaa3, 0x226e, 0x3c1, 0x1f94, 0x2832, 0x1408, 0xd63, 0x1559, 0x19e7, 0x273, 0x2fe5, 0x1e40, 0xa2b, 0xd34, 0x1be2, 0x353, 0x1ef7, 0x147, 0x10e3, 0xd6d, 0x248e, 0xbfc, 0xc04, 0x9aa, 0xc8, 0x360, 0x2262, 0x100b, 0x99a, 0x278f, 0x2efc, 0x1c3d, 0x29a2, 0x21ec, 0x251e, 0x1bdb, 0x2b6d, 0x2d82, 0x15f8, 0x2924, 0x2393, 0x1fd, 0x109a, 0x17b7, 0x2559, 0x20b1, 0x2147, 0xd30, 0xea6, 0xf47, 0x12c3, 0x253, 0x288c, 0xbf3, 0x22a3, 0x78a, 0x2725, 0x20d, 0x16d2, 0x47f, 0xfc, 0xfc6, 0xb7f, 0x957, 0x2514, 0x1216, 0xbda, 0x709, 0x2809, 0x172e, 0x1e60, 0x28f9, 0x23df, 0x908, 0x2445, 0x1646, 0xe38, 0x3d2, 0x160b, 0x6e6, 0x1788, 0x2fe4, 0x15d8, 0x47, 0xce8, 0x1ecb, 0x6b7, 0x2a73, 0x1619, 0x27c7, 0x633, 0x2fe7, 0x2a9a, 0x1a96, 0x297d, 0xc2d, 0x2488, 0x1953, 0xb89, 0x131c, 0x1729, 0x1b16, 0x1275, 0x1fbb, 0x184c, 0x1c28, 0x198a, 0x2934, 0x1f9, 0x2553, 0x11e5, 0xfdc, 0x2a4d, 0xdc4, 0x1146, 0x956, 0x92d, 0x21e1, 0x1a95, 0x2fa1, 0x998, 0x1c01, 0x131d, 0x2a3f, 0xb4b, 0x2cf2, 0x2fe1, 0x724, 0x1956, 0x1cce, 0x254a, 0x2a0a, 0x1497, 0x11e7, 0xc71, 0xf58, 0x77d, 0x2245, 0x40f, 0x22c, 0x871, 0x3d3, 0x18dd, 0x1cd, 0x2df0, 0x1009, 0x1a94, 0x29da, 0x1963, 0x7e7, 0x2908, 0x848, 0xc28, 0x19a2, 0x31d, 0x2c2c, 0x2608, 0x23a5, 0x542, 0x2fad, 0x865, 0x1e81, 0x2da9, 0x25e1, 0x1303, 0x240c, 0x7ba, 0x2a8, 0xc0d, 0xda8, 0x124d, 0x28a8, 0x1ff7, 0x2829, 0x146, 0xb43, 0x23ea, 0x1894, 0x2e27, 0x2dc4, 0x2d43, 0x18a3, 0x1a44, 0xbb3, 0x28b9, 0x1fe9, 0x226b, 0x1409, 0xb7a, 0x1c75, 0x4e, 0x1299, 0x1040, 0x1fcc, 0x171e, 0xb8a, 0xd1, 0x75e, 0x26ae, 0x229b, 0xec0, 0x157a, 0x111c, 0x6b5, 0x6d, 0x5ae, 0x1467, 0x1c9d, 0x200a, 0x5eb, 0x1339, 0xbff, 0x120, 0x1fbe, 0x13ff, 0x3d1, 0x2a60, 0x1b87, 0x196a, 0x57, 0x1b4f, 0x1220, 0x1d30, 0xccd, 0x248b, 0x2aa8, 0x1db7, 0x18ae, 0x10aa, 0x1425, 0x2f2c, 0x1187, 0x3a1, 0x26b8, 0x2466, 0x14e9, 0x1518, 0x2b1f, 0x1ae6, 0x238e, 0x1a78, 0x1819, 0x2284, 0x1475, 0xaf, 0x2f4, 0x13fc, 0x227d, 0x29c0, 0xf3a, 0x187a, 0x5e4, 0x1950, 0x2a25, 0x29e1, 0xddd, 0x295d, 0x1351, 0x304, 0x2bc0, 0xd2, 0xd25, 0x2195, 0x1fc9, 0x1ee6, 0x2f13, 0x6db, 0xa6a, 0x1d99, 0x2b60, 0x1234, 0x283c, 0x2ac2, 0x11a9, 0x639, 0x2290, 0x2bda, 0x32f, 0x2a5f, 0x15c0, 0x139c, 0x7e8, 0x88a, 0x43f, 0x2762, 0x1271, 0x119d, 0x1fed, 0x1b4d, 0x692, 0x1d2b, 0x1feb, 0x1380, 0x2628, 0x2a93, 0x2226, 0xe71, 0x2d1b, 0x20ab, 0x17ff, 0x1e27, 0x2fb1, 0xe65, 0x17c8, 0x1fa6, 0x43b, 0x548, 0x2256, 0x9a5, 0x71a, 0x26ea, 0x2d38, 0x1b40, 0x1b79, 0x658, 0x15a5, 0x224f, 0x248, 0xeee, 0x2f37, 0x1c30, 0x15ec, 0x1ca7, 0x255f, 0x2801, 0x18f7, 0x1727, 0xf88, 0x2b1, 0x2c45, 0x164b, 0x289f, 0x14dd, 0x2649, 0x27a3, 0x9f0, 0x21ca, 0x1f5, 0x1dd6, 0xbc3, 0x71f, 0x133e, 0x13bb, 0x2afe, 0xc35, 0x4bb, 0x2d31, 0x10a7, 0x2a04, 0x180e, 0x2613, 0x330, 0xe76, 0x19fd, 0xfe9, 0x935, 0x79, 0x1b01, 0x73c, 0x2ac6, 0x21ce, 0x1911, 0x761, 0x1084, 0x1983, 0xc3, 0x15eb, 0xe0a, 0xdd, 0x1cb1, 0xb21, 0x2a51, 0x217f, 0xb1, 0x1328, 0x9ca, 0x1d96, 0x1a0b, 0xe1b, 0x1c4b, 0x3b, 0x4d6, 0x2344, 0x199e, 0x28af, 0x1624, 0x4ae, 0x8b2, 0x2991, 0x1fb7, 0x41, 0x2780, 0x1d8b, 0xa7f, 0x110, 0x2350, 0x18aa, 0x2b2f, 0x1805, 0x1ff, 0xf0, 0x2a74, 0xe42, 0xd97, 0x85b, 0x14bc, 0x2901, 0xfd8, 0x1ab3, 0x1cef, 0xfbd, 0x2b07, 0x174f, 0x69b, 0x10c3, 0x1491, 0xde3, 0x28ca, 0x252e, 0x1849, 0x1ec2, 0x1f1b, 0x2853, 0x12ab, 0x2674, 0x238c, 0x350, 0x2ca, 0xa7, 0x4bd, 0xcc3, 0x90c, 0x892, 0x276, 0x1e55, 0x196d, 0x1194, 0x1bef, 0x66a, 0x1da1, 0x260f, 0x1c15, 0x49f, 0x120b, 0x2671, 0x1237, 0x2e0d, 0x2791, 0x17d8, 0x1e0a, 0x2a99, 0x14cf, 0xfb1, 0x15b4, 0x1462, 0x2fbb, 0xeff, 0x16b, 0x2d6a, 0x9ef, 0x5e3, 0x11c0, 0x2e76, 0x1623, 0x2db8, 0x1c88, 0x740, 0x11e1, 0x12a3, 0x977, 0x1110, 0x2163, 0x2dee, 0x47b, 0x2aa5, 0x2a22, 0x1231, 0x16e7, 0x1626, 0x12e0, 0x1d28, 0xe96, 0xb62, 0x21d0, 0xf09, 0xb30, 0xcb8, 0x2981, 0x2648, 0x155d, 0x27ee, 0xb34, 0x169, 0x1574, 0x1fe6, 0x25f4, 0x151d, 0x1801, 0x1f13, 0x1308, 0x2929, 0x6eb, 0x25e, 0x2cca, 0x1e3e, 0x248f} - -func round(a int32, b int32) int32 { - return (a + b/2) / b -} - -/* constant time absolute vaue */ -func nabs(x int32) int32 { - mask := (x >> 31) - return (x + mask) ^ mask -} - -/* Montgomery stuff */ - -func redc(T uint64) int32 { - m := (uint32(T) * NHS_ND) - return int32((uint64(m)*uint64(NHS_PRIME) + T) >> NHS_WL) -} - -func nres(x int32) int32 { - return redc(uint64(x) * NHS_R2MODP) -} - -func modmul(a int32, b int32) int32 { - return redc(uint64(a) * uint64(b)) -} - -/* NTT code */ -/* Cooley-Tukey NTT */ - -func ntt(x []int32) { - t := NHS_DEGREE / 2 - q := NHS_PRIME - - /* Convert to Montgomery form */ - for j := 0; j < NHS_DEGREE; j++ { - x[j] = nres(x[j]) - } - m := 1 - for m < NHS_DEGREE { - k := 0 - for i := 0; i < m; i++ { - S := NHS_roots[m+i] - for j := k; j < k+t; j++ { - U := x[j] - V := modmul(x[j+t], S) - x[j] = U + V - x[j+t] = U + 2*q - V - } - k += 2 * t - } - t /= 2 - m *= 2 - } -} - -/* Gentleman-Sande INTT */ - -func intt(x []int32) { - t := 1 - q := NHS_PRIME - - m := NHS_DEGREE / 2 - for m > 1 { - k := 0 - for i := 0; i < m; i++ { - S := NHS_iroots[m+i] - for j := k; j < k+t; j++ { - U := x[j] - V := x[j+t] - x[j] = U + V - W := U + int32(NHS_DEGREE)*q - V - x[j+t] = modmul(W, S) - } - k += 2 * t - } - t *= 2 - m /= 2 - } - - /* Last iteration merged with n^-1 */ - - t = NHS_DEGREE / 2 - for j := 0; j < t; j++ { - U := x[j] - V := x[j+t] - W := U + int32(NHS_DEGREE)*q - V - x[j+t] = modmul(W, NHS_invpr) - x[j] = modmul(U+V, NHS_inv) - } - /* convert back from Montgomery to "normal" form */ - for j := 0; j < NHS_DEGREE; j++ { - x[j] = redc(uint64(x[j])) - x[j] -= q - x[j] += (x[j] >> (NHS_WL - 1)) & q - } -} - -/* See https://eprint.iacr.org/2016/1157.pdf */ - -func encode(key []byte, poly []int32) { - - q2 := NHS_PRIME / 2 - j := 0 - for i := 0; i < 256; { - kj := key[j] - j++ - for k := 0; k < 8; k++ { - b := int32(kj & 1) - poly[i] = b * q2 - poly[i+256] = b * q2 - poly[i+512] = b * q2 - poly[i+768] = b * q2 - kj >>= 1 - i++ - } - } -} - -func decode(poly []int32, key []byte) { - q2 := NHS_PRIME / 2 - for i := 0; i < 32; i++ { - key[i] = 0 - } - - j := 0 - for i := 0; i < 256; { - for k := 0; k < 8; k++ { - t := nabs(poly[i]-q2) + nabs(poly[i+256]-q2) + nabs(poly[i+512]-q2) + nabs(poly[i+768]-q2) - b := t - NHS_PRIME - b = (b >> 31) & 1 - key[j] = (key[j] >> 1) + byte(b<<7) - i++ - } - j++ - } -} - -/* convert 32-byte seed to random polynomial */ - -func parse(seed []byte, poly []int32) { - var hash [4 * NHS_DEGREE]byte - sh := NewSHA3(SHA3_SHAKE128) - - for i := 0; i < 32; i++ { - sh.Process(seed[i]) - } - sh.Shake(hash[:], 4*NHS_DEGREE) - - j := 0 - for i := 0; i < NHS_DEGREE; i++ { - n := int32(hash[j] & 0x7f) - n <<= 8 - n += int32(hash[j+1]) - n <<= 8 - n += int32(hash[j+2]) - n <<= 8 - n += int32(hash[j+3]) - j += 4 - poly[i] = nres(n) - //poly[i]=modmul(n,NHS_ONE) // reduce 31-bit random number mod q - } -} - -/* Compress 14 bits polynomial coefficients into byte array */ -/* 7 bytes is 3x14 */ - -func nhs_pack(poly []int32, array []byte) { - j := 0 - for i := 0; i < NHS_DEGREE; { - a := poly[i] - b := poly[i+1] - c := poly[i+2] - d := poly[i+3] - i += 4 - array[j] = byte(a & 0xff) - array[j+1] = byte(((a >> 8) | (b << 6)) & 0xff) - array[j+2] = byte((b >> 2) & 0xff) - array[j+3] = byte(((b >> 10) | (c << 4)) & 0xff) - array[j+4] = byte((c >> 4) & 0xff) - array[j+5] = byte(((c >> 12) | (d << 2)) & 0xff) - array[j+6] = byte(d >> 6) - j += 7 - } -} - -func nhs_unpack(array []byte, poly []int32) { - j := 0 - for i := 0; i < NHS_DEGREE; { - a := int32((array[j]) & 0xff) - b := int32((array[j+1]) & 0xff) - c := int32((array[j+2]) & 0xff) - d := int32((array[j+3]) & 0xff) - e := int32((array[j+4]) & 0xff) - f := int32((array[j+5]) & 0xff) - g := int32((array[j+6]) & 0xff) - j += 7 - poly[i] = a | ((b & 0x3f) << 8) - poly[i+1] = (b >> 6) | (c << 2) | ((d & 0xf) << 10) - poly[i+2] = (d >> 4) | (e << 4) | ((f & 3) << 12) - poly[i+3] = (f >> 2) | (g << 6) - i += 4 - } -} - -/* See https://eprint.iacr.org/2016/1157.pdf */ - -func compress(poly []int32, array []byte) { - - var col int32 = 0 - j := 0 - for i := 0; i < NHS_DEGREE; { - for k := 0; k < 8; k++ { - b := round((poly[i]*8), NHS_PRIME) & 7 - col = (col << 3) + b - i += 1 - } - array[j] = byte(col & 0xff) - array[j+1] = byte((col >> 8) & 0xff) - array[j+2] = byte((col >> 16) & 0xff) - j += 3 - col = 0 - } -} - -func decompress(array []byte, poly []int32) { - var col int32 = 0 - j := 0 - for i := 0; i < NHS_DEGREE; { - col = int32(array[j+2]) & 0xff - col = (col << 8) + (int32(array[j+1]) & 0xff) - col = (col << 8) + (int32(array[j]) & 0xff) - j += 3 - for k := 0; k < 8; k++ { - b := (col & 0xe00000) >> 21 - col <<= 3 - poly[i] = round((b * NHS_PRIME), 8) - i += 1 - } - } -} - -/* generate centered binomial distribution */ - -func error(rng *RAND, poly []int32) { - var r int32 - for i := 0; i < NHS_DEGREE; i++ { - n1 := (int32(rng.GetByte()) & 0xff) + ((int32(rng.GetByte()) & 0xff) << 8) - n2 := (int32(rng.GetByte()) & 0xff) + ((int32(rng.GetByte()) & 0xff) << 8) - r = 0 - for j := 0; j < 16; j++ { - r += (n1 & 1) - (n2 & 1) - n1 >>= 1 - n2 >>= 1 - } - poly[i] = (r + NHS_PRIME) - } -} - -func redc_it(p []int32) { - for i := 0; i < NHS_DEGREE; i++ { - p[i] = redc(uint64(p[i])) - } -} - -func nres_it(p []int32) { - for i := 0; i < NHS_DEGREE; i++ { - p[i] = nres(p[i]) - } -} - -func poly_mul(p1 []int32, p2 []int32, p3 []int32) { - for i := 0; i < NHS_DEGREE; i++ { - p1[i] = modmul(p2[i], p3[i]) - } -} - -func poly_add(p1 []int32, p2 []int32, p3 []int32) { - for i := 0; i < NHS_DEGREE; i++ { - p1[i] = (p2[i] + p3[i]) - } -} - -func poly_sub(p1 []int32, p2 []int32, p3 []int32) { - for i := 0; i < NHS_DEGREE; i++ { - p1[i] = (p2[i] + NHS_PRIME - p3[i]) - } -} - -/* reduces inputs < 2q */ -func poly_soft_reduce(poly []int32) { - for i := 0; i < NHS_DEGREE; i++ { - e := poly[i] - NHS_PRIME - poly[i] = e + ((e >> (NHS_WL - 1)) & NHS_PRIME) - } -} - -/* fully reduces modulo q */ -func poly_hard_reduce(poly []int32) { - for i := 0; i < NHS_DEGREE; i++ { - e := modmul(poly[i], NHS_ONE) - e = e - NHS_PRIME - poly[i] = e + ((e >> (NHS_WL - 1)) & NHS_PRIME) - } -} - -/* API files */ - -func NHS_SERVER_1(rng *RAND, SB []byte, S []byte) { - var seed [32]byte - var array [1792]byte - var s [NHS_DEGREE]int32 - var e [NHS_DEGREE]int32 - var b [NHS_DEGREE]int32 - - for i := 0; i < 32; i++ { - seed[i] = rng.GetByte() - } - - parse(seed[:], b[:]) - - error(rng, e[:]) - error(rng, s[:]) - - ntt(s[:]) - ntt(e[:]) - poly_mul(b[:], b[:], s[:]) - poly_add(b[:], b[:], e[:]) - poly_hard_reduce(b[:]) - - redc_it(b[:]) - nhs_pack(b[:], array[:]) - - for i := 0; i < 32; i++ { - SB[i] = seed[i] - } - - for i := 0; i < 1792; i++ { - SB[i+32] = array[i] - } - - poly_hard_reduce(s[:]) - nhs_pack(s[:], array[:]) - - for i := 0; i < 1792; i++ { - S[i] = array[i] - } - -} - -func NHS_CLIENT(rng *RAND, SB []byte, UC []byte, KEY []byte) { - sh := NewSHA3(SHA3_HASH256) - var seed [32]byte - var array [1792]byte - var key [32]byte - var cc [384]byte - - var sd [NHS_DEGREE]int32 - var ed [NHS_DEGREE]int32 - var u [NHS_DEGREE]int32 - var k [NHS_DEGREE]int32 - var c [NHS_DEGREE]int32 - - error(rng, sd[:]) - error(rng, ed[:]) - - ntt(sd[:]) - ntt(ed[:]) - - for i := 0; i < 32; i++ { - seed[i] = SB[i] - } - - for i := 0; i < 1792; i++ { - array[i] = SB[i+32] - } - - parse(seed[:], u[:]) - - poly_mul(u[:], u[:], sd[:]) - poly_add(u[:], u[:], ed[:]) - poly_hard_reduce(u[:]) - - for i := 0; i < 32; i++ { - key[i] = rng.GetByte() - } - - for i := 0; i < 32; i++ { - sh.Process(key[i]) - } - hkey := sh.Hash() - - encode(hkey[:], k[:]) - - nhs_unpack(array[:], c[:]) - nres_it(c[:]) - - poly_mul(c[:], c[:], sd[:]) - intt(c[:]) - error(rng, ed[:]) - poly_add(c[:], c[:], ed[:]) - poly_add(c[:], c[:], k[:]) - - compress(c[:], cc[:]) - - sh.Init(SHA3_HASH256) - for i := 0; i < 32; i++ { - sh.Process(hkey[i]) - } - fkey := sh.Hash() - - for i := 0; i < 32; i++ { - KEY[i] = fkey[i] - } - - redc_it(u[:]) - nhs_pack(u[:], array[:]) - - for i := 0; i < 1792; i++ { - UC[i] = array[i] - } - - for i := 0; i < 384; i++ { - UC[i+1792] = cc[i] - } -} - -func NHS_SERVER_2(S []byte, UC []byte, KEY []byte) { - sh := NewSHA3(SHA3_HASH256) - - var c [NHS_DEGREE]int32 - var s [NHS_DEGREE]int32 - var k [NHS_DEGREE]int32 - - var array [1792]byte - var key [32]byte - var cc [384]byte - - for i := 0; i < 1792; i++ { - array[i] = UC[i] - } - - nhs_unpack(array[:], k[:]) - nres_it(k[:]) - - for i := 0; i < 384; i++ { - cc[i] = UC[i+1792] - } - - decompress(cc[:], c[:]) - - for i := 0; i < 1792; i++ { - array[i] = S[i] - } - - nhs_unpack(array[:], s[:]) - - poly_mul(k[:], k[:], s[:]) - intt(k[:]) - poly_sub(k[:], c[:], k[:]) - poly_soft_reduce(k[:]) - - decode(k[:], key[:]) - - for i := 0; i < 32; i++ { - sh.Process(key[i]) - } - hkey := sh.Hash() - - for i := 0; i < 32; i++ { - KEY[i] = hkey[i] - } -} - -/* -func main() { - - srng:=NewRAND() - var sraw [100]byte - for i:=0;i<100;i++ {sraw[i]=byte(i+1)} - srng.Seed(100,sraw[:]) - - crng:=NewRAND() - var craw [100]byte - for i:=0;i<100;i++ {craw[i]=byte(i+2)} - crng.Seed(100,craw[:]) - - var S [1792] byte - - var SB [1824] byte - NHS_SERVER_1(srng,SB[:],S[:]) - var UC [2176] byte - var KEYB [32] byte - NHS_CLIENT(crng,SB[:],UC[:],KEYB[:]) - - fmt.Printf("Bob's Key= ") - for i:=0;i<32;i++ { - fmt.Printf("%02x", KEYB[i]) - } - fmt.Printf("\n") - var KEYA [32] byte - NHS_SERVER_2(S[:],UC[:],KEYA[:]) - - fmt.Printf("Alice Key= ") - for i:=0;i<32;i++ { - fmt.Printf("%02x", KEYA[i]) - } - -} -*/ diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/RAND.go b/vendor/github.com/hyperledger/fabric-amcl/core/RAND.go deleted file mode 100644 index abbccc83fe3..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/RAND.go +++ /dev/null @@ -1,191 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* - * Cryptographic strong random number generator - * - * Unguessable seed -> SHA -> PRNG internal state -> SHA -> random numbers - * Slow - but secure - * - * See ftp://ftp.rsasecurity.com/pub/pdfs/bull-1.pdf for a justification - */ - -/* Marsaglia & Zaman Random number generator constants */ - -package core - -//import "fmt" - -const rand_NK int = 21 -const rand_NJ int = 6 -const rand_NV int = 8 - -type RAND struct { - ira [rand_NK]uint32 /* random number... */ - rndptr int - borrow uint32 - pool_ptr int - pool [32]byte -} - -/* Terminate and clean up */ -func (R *RAND) Clean() { /* kill internal state */ - R.pool_ptr = 0 - R.rndptr = 0 - for i := 0; i < 32; i++ { - R.pool[i] = 0 - } - for i := 0; i < rand_NK; i++ { - R.ira[i] = 0 - } - R.borrow = 0 -} - -func NewRAND() *RAND { - R := new(RAND) - R.Clean() - return R -} - -func (R *RAND) sbrand() uint32 { /* Marsaglia & Zaman random number generator */ - R.rndptr++ - if R.rndptr < rand_NK { - return R.ira[R.rndptr] - } - R.rndptr = 0 - k := rand_NK - rand_NJ - for i := 0; i < rand_NK; i++ { /* calculate next NK values */ - if k == rand_NK { - k = 0 - } - t := R.ira[k] - pdiff := t - R.ira[i] - R.borrow - if pdiff < t { - R.borrow = 0 - } - if pdiff > t { - R.borrow = 1 - } - R.ira[i] = pdiff - k++ - } - - return R.ira[0] -} - -func (R *RAND) sirand(seed uint32) { - var m uint32 = 1 - R.borrow = 0 - R.rndptr = 0 - R.ira[0] ^= seed - for i := 1; i < rand_NK; i++ { /* fill initialisation vector */ - in := (rand_NV * i) % rand_NK - R.ira[in] ^= m /* note XOR */ - t := m - m = seed - m - seed = t - } - for i := 0; i < 10000; i++ { - R.sbrand() - } /* "warm-up" & stir the generator */ -} - -func (R *RAND) fill_pool() { - sh := NewHASH256() - for i := 0; i < 128; i++ { - sh.Process(byte(R.sbrand() & 0xff)) - } - W := sh.Hash() - for i := 0; i < 32; i++ { - R.pool[i] = W[i] - } - R.pool_ptr = 0 -} - -func pack(b [4]byte) uint32 { /* pack 4 bytes into a 32-bit Word */ - return (((uint32(b[3])) & 0xff) << 24) | ((uint32(b[2]) & 0xff) << 16) | ((uint32(b[1]) & 0xff) << 8) | (uint32(b[0]) & 0xff) -} - -/* Initialize RNG with some real entropy from some external source */ -func (R *RAND) Seed(rawlen int, raw []byte) { /* initialise from at least 128 byte string of raw random entropy */ - var b [4]byte - sh := NewHASH256() - R.pool_ptr = 0 - - for i := 0; i < rand_NK; i++ { - R.ira[i] = 0 - } - if rawlen > 0 { - for i := 0; i < rawlen; i++ { - sh.Process(raw[i]) - } - digest := sh.Hash() - - /* initialise PRNG from distilled randomness */ - - for i := 0; i < 8; i++ { - b[0] = digest[4*i] - b[1] = digest[4*i+1] - b[2] = digest[4*i+2] - b[3] = digest[4*i+3] - R.sirand(pack(b)) - } - } - R.fill_pool() -} - -/* get random byte */ -func (R *RAND) GetByte() byte { - r := R.pool[R.pool_ptr] - R.pool_ptr++ - if R.pool_ptr >= 32 { - R.fill_pool() - } - return byte(r & 0xff) -} - -/* test main program */ -/* -func main() { - var raw [100]byte - rng:=NewRAND() - - rng.Clean() - for i:=0;i<100;i++ {raw[i]=byte(i)} - - rng.Seed(100,raw[:]) - - for i:=0;i<1000;i++ { - fmt.Printf("%03d ",rng.GetByte()) - } -} -*/ diff --git a/vendor/github.com/hyperledger/fabric-amcl/core/SHA3.go b/vendor/github.com/hyperledger/fabric-amcl/core/SHA3.go deleted file mode 100644 index 9adb3c77347..00000000000 --- a/vendor/github.com/hyperledger/fabric-amcl/core/SHA3.go +++ /dev/null @@ -1,293 +0,0 @@ -/* - Copyright (C) 2019 MIRACL UK Ltd. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - https://www.gnu.org/licenses/agpl-3.0.en.html - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - You can be released from the requirements of the license by purchasing - a commercial license. Buying such a license is mandatory as soon as you - develop commercial activities involving the MIRACL Core Crypto SDK - without disclosing the source code of your own applications, or shipping - the MIRACL Core Crypto SDK with a closed source product. -*/ - -/* - * Implementation of the Secure Hashing Algorithm (SHA-384) - * - * Generates a 384 bit message digest. It should be impossible to come - * come up with two messages that hash to the same value ("collision free"). - * - * For use with byte-oriented messages only. - */ - -//package main - -package core - -//import "fmt" - -const SHA3_HASH224 int = 28 -const SHA3_HASH256 int = 32 -const SHA3_HASH384 int = 48 -const SHA3_HASH512 int = 64 -const SHA3_SHAKE128 int = 16 -const SHA3_SHAKE256 int = 32 - -const sha3_ROUNDS int = 24 - -var sha3_RC = [24]uint64{ - 0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 0x8000000080008000, - 0x000000000000808B, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, - 0x000000000000008A, 0x0000000000000088, 0x0000000080008009, 0x000000008000000A, - 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 0x8000000000008003, - 0x8000000000008002, 0x8000000000000080, 0x000000000000800A, 0x800000008000000A, - 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008} - -type SHA3 struct { - length uint64 - rate int - len int - s [5][5]uint64 -} - -/* functions */ - -func sha3_ROTL(x uint64, n uint64) uint64 { - return (((x) << n) | ((x) >> (64 - n))) -} - -func (H *SHA3) transform() { /* basic transformation step */ - - var c [5]uint64 - var d [5]uint64 - var b [5][5]uint64 - - for k := 0; k < sha3_ROUNDS; k++ { - c[0] = H.s[0][0] ^ H.s[0][1] ^ H.s[0][2] ^ H.s[0][3] ^ H.s[0][4] - c[1] = H.s[1][0] ^ H.s[1][1] ^ H.s[1][2] ^ H.s[1][3] ^ H.s[1][4] - c[2] = H.s[2][0] ^ H.s[2][1] ^ H.s[2][2] ^ H.s[2][3] ^ H.s[2][4] - c[3] = H.s[3][0] ^ H.s[3][1] ^ H.s[3][2] ^ H.s[3][3] ^ H.s[3][4] - c[4] = H.s[4][0] ^ H.s[4][1] ^ H.s[4][2] ^ H.s[4][3] ^ H.s[4][4] - - d[0] = c[4] ^ sha3_ROTL(c[1], 1) - d[1] = c[0] ^ sha3_ROTL(c[2], 1) - d[2] = c[1] ^ sha3_ROTL(c[3], 1) - d[3] = c[2] ^ sha3_ROTL(c[4], 1) - d[4] = c[3] ^ sha3_ROTL(c[0], 1) - - for i := 0; i < 5; i++ { - for j := 0; j < 5; j++ { - H.s[i][j] ^= d[i] - } - } - - b[0][0] = H.s[0][0] - b[1][3] = sha3_ROTL(H.s[0][1], 36) - b[2][1] = sha3_ROTL(H.s[0][2], 3) - b[3][4] = sha3_ROTL(H.s[0][3], 41) - b[4][2] = sha3_ROTL(H.s[0][4], 18) - - b[0][2] = sha3_ROTL(H.s[1][0], 1) - b[1][0] = sha3_ROTL(H.s[1][1], 44) - b[2][3] = sha3_ROTL(H.s[1][2], 10) - b[3][1] = sha3_ROTL(H.s[1][3], 45) - b[4][4] = sha3_ROTL(H.s[1][4], 2) - - b[0][4] = sha3_ROTL(H.s[2][0], 62) - b[1][2] = sha3_ROTL(H.s[2][1], 6) - b[2][0] = sha3_ROTL(H.s[2][2], 43) - b[3][3] = sha3_ROTL(H.s[2][3], 15) - b[4][1] = sha3_ROTL(H.s[2][4], 61) - - b[0][1] = sha3_ROTL(H.s[3][0], 28) - b[1][4] = sha3_ROTL(H.s[3][1], 55) - b[2][2] = sha3_ROTL(H.s[3][2], 25) - b[3][0] = sha3_ROTL(H.s[3][3], 21) - b[4][3] = sha3_ROTL(H.s[3][4], 56) - - b[0][3] = sha3_ROTL(H.s[4][0], 27) - b[1][1] = sha3_ROTL(H.s[4][1], 20) - b[2][4] = sha3_ROTL(H.s[4][2], 39) - b[3][2] = sha3_ROTL(H.s[4][3], 8) - b[4][0] = sha3_ROTL(H.s[4][4], 14) - - for i := 0; i < 5; i++ { - for j := 0; j < 5; j++ { - H.s[i][j] = b[i][j] ^ (^b[(i+1)%5][j] & b[(i+2)%5][j]) - } - } - - H.s[0][0] ^= sha3_RC[k] - } -} - -/* Initialise Hash function */ -func (H *SHA3) Init(olen int) { - for i := 0; i < 5; i++ { - for j := 0; j < 5; j++ { - H.s[i][j] = 0 - } - } - H.length = 0 - H.len = olen - H.rate = 200 - 2*olen -} - -func NewSHA3(olen int) *SHA3 { - H := new(SHA3) - H.Init(olen) - return H -} - -/* process a single byte */ -func (H *SHA3) Process(byt byte) { /* process the next message byte */ - cnt := int(H.length % uint64(H.rate)) - b := cnt % 8 - cnt /= 8 - i := cnt % 5 - j := cnt / 5 - H.s[i][j] ^= uint64(byt&0xff) << uint(8*b) - H.length++ - if int(H.length%uint64(H.rate)) == 0 { - H.transform() - } -} - -/* process an array of bytes */ -func (H *SHA3) Process_array(b []byte) { - for i := 0; i < len(b); i++ { - H.Process((b[i])) - } -} - -/* process a 32-bit integer */ -func (H *SHA3) Process_num(n int32) { - H.Process(byte((n >> 24) & 0xff)) - H.Process(byte((n >> 16) & 0xff)) - H.Process(byte((n >> 8) & 0xff)) - H.Process(byte(n & 0xff)) -} - - -/* squeeze the sponge */ -func (H *SHA3) Squeeze(buff []byte, olen int) { - // olen:=len(buff) - done := false - m := 0 - /* extract by columns */ - for { - for j := 0; j < 5; j++ { - for i := 0; i < 5; i++ { - el := H.s[i][j] - for k := 0; k < 8; k++ { - buff[m] = byte(el & 0xff) - m++ - if m >= olen || (m%H.rate) == 0 { - done = true - break - } - el >>= 8 - } - if done { - break - } - } - if done { - break - } - } - if m >= olen { - break - } - done = false - H.transform() - - } -} - -/* Generate Hash */ -func (H *SHA3) Hash() []byte { /* generate a SHA3 hash of appropriate size */ - var digest [64]byte - q := H.rate - int(H.length%uint64(H.rate)) - if q == 1 { - H.Process(0x86) - } else { - H.Process(0x06) - for int(H.length%uint64(H.rate)) != (H.rate - 1) { - H.Process(0x00) - } - H.Process(0x80) - } - H.Squeeze(digest[:], H.len) - return digest[0:H.len] -} - -func (H *SHA3) Shake(hash []byte, olen int) { /* generate a SHA3 hash of appropriate size */ - q := H.rate - int(H.length%uint64(H.rate)) - if q == 1 { - H.Process(0x9f) - } else { - H.Process(0x1f) - for int(H.length%uint64(H.rate)) != H.rate-1 { - H.Process(0x00) - } - H.Process(0x80) - } - H.Squeeze(hash, olen) -} - -/* test program: should produce digest */ -//916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18 -//afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185 -//98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf4535423709b02843948684e029010badcc0acd8303fc85fdad3eabf4f78cae165635f57afd28810fc2 - -/* -func main() { - - test := []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu") - var digest [172]byte - - sh:=NewSHA3(SHA3_HASH256) - for i:=0;i