diff --git a/vendor/github.com/manudrijvers/amcl/LICENSE-2.0.TXT b/vendor/github.com/manudrijvers/amcl/LICENSE-2.0.TXT new file mode 100644 index 00000000000..7a4a3ea2424 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/LICENSE-2.0.TXT @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. \ No newline at end of file diff --git a/vendor/github.com/manudrijvers/amcl/NOTICE.txt b/vendor/github.com/manudrijvers/amcl/NOTICE.txt new file mode 100644 index 00000000000..434d2bb592b --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/NOTICE.txt @@ -0,0 +1,5 @@ +Apache Milagro Crypto Libraries +Copyright 2016 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). diff --git a/vendor/github.com/manudrijvers/amcl/go/AES.go b/vendor/github.com/manudrijvers/amcl/go/AES.go new file mode 100644 index 00000000000..668c8a87101 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/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 + +//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>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>(MODBITS%BASEBITS)) +} + +func FF_EXCESS(a* BIG) Chunk { + return ((a.w[NLEN-1]&P_OMASK)>>(P_MB)) +} + +/* 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 && 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 +} + +/* 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;i>TBITS)+(v<<(BASEBITS-TBITS)))) + + 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 { + return monty(d) + } + return NewBIG() +} + +/* Compare a and b, return 0 if a==b, -1 if ab. 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<>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; +} + +/* 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=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(m *BIG) { + 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 *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 *RAND) *BIG { + d:=NewDBIG(); + var j int=0 + var r byte=0 + for i:=0;i<2*int(MODBITS);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(a,b,m *BIG) *BIG { + a.mod(m) + b.mod(m) + d:=mul(a,b); + return d.mod(m) +} + +/* return a^2 mod m */ +func modsqr(a,m *BIG) *BIG { + a.mod(m) + d:=sqr(a) + return d.mod(m) +} + +/* return -a mod m */ +func modneg(a,m *BIG) *BIG { + 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.shr(1); + if x1.parity()!=0 { + x1.add(p) + x1.norm() + } + x1.shr(1) + } + for v.parity()==0 { + v.shr(1); + if x2.parity()!=0 { + x2.add(p) + x2.norm() + } + x2.shr(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(e *BIG,m *BIG) *BIG { + 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; +} +/* +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/manudrijvers/amcl/go/DBIG.go b/vendor/github.com/manudrijvers/amcl/go/DBIG.go new file mode 100644 index 00000000000..8cc960f4a40 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/DBIG.go @@ -0,0 +1,256 @@ +/* +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 amcl + +import "strconv" +//import "fmt" + +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 BIG */ +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/manudrijvers/amcl/go/ECDH.go b/vendor/github.com/manudrijvers/amcl/go/ECDH.go new file mode 100644 index 00000000000..31367ee1430 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/ECDH.go @@ -0,0 +1,547 @@ +/* +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 amcl + +//import "fmt" + +const ECDH_INVALID_PUBLIC_KEY int=-2 +const ECDH_ERROR int=-3 +const ECDH_INVALID int=-4 +const ECDH_EFS int=int(MODBYTES) +const ECDH_EGS int=int(MODBYTES) +const ECDH_EAS int=16 +const ECDH_EBS int=16 +const ECDH_SHA256 int=32 +const ECDH_SHA384 int=48 +const ECDH_SHA512 int=64 + +const ECDH_HASH_TYPE int=ECDH_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 hashitecdh(sha int,A []byte,n int,B []byte,pad int) []byte { + var R []byte + if sha==ECDH_SHA256 { + H:=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==ECDH_SHA384 { + H:=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==ECDH_SHA512 { + H:=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=hashitecdh(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) + + return res +} + +/* validate public key. Set full=true for fuller check */ +func ECDH_PUBLIC_KEY_VALIDATE(full bool,W []byte) int { + WP:=ECP_fromBytes(W) + res:=0 + + r:=NewBIGints(CURVE_Order) + + if WP.is_infinity() {res=ECDH_INVALID_PUBLIC_KEY} + if res==0 && full { + WP=WP.mul(r) + if !WP.is_infinity() {res=ECDH_INVALID_PUBLIC_KEY} + } + return res +} + +/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */ +func ECPSVDP_DH(S []byte,WD []byte,Z []byte) int { + res:=0; + var T [ECDH_EFS]byte + + s:=fromBytes(S) + + W:=ECP_fromBytes(WD) + if W.is_infinity() {res=ECDH_ERROR} + + if res==0 { + r:=NewBIGints(CURVE_Order) + s.mod(r) + W=W.mul(s) + if W.is_infinity() { + res=ECDH_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=ECDH_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=ECDH_ERROR + } else { + P:=NewECP() + P.copy(WP) + + P=P.mul2(h2,G,f) + + if P.is_infinity() { + res=ECDH_INVALID; + } else { + d=P.getX() + d.mod(r) + + if comp(d,c)!=0 {res=ECDH_INVALID} + } + } + } + + return res +} + +/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */ +func ECIES_ENCRYPT(sha int,P1 []byte,P2 []byte,RNG *RAND,W []byte,M []byte,V []byte,T []byte) []byte { + var Z [ECDH_EFS]byte + var VZ [3*ECDH_EFS+1]byte + var K1 [ECDH_EAS]byte + var K2 [ECDH_EAS]byte + var U [ECDH_EGS]byte + + if ECDH_KEY_PAIR_GENERATE(RNG,U[:],V)!=0 {return nil} + if ECPSVDP_DH(U[:],W,Z[:])!=0 {return nil} + + for i:=0;i<2*ECDH_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() + E.y.one() + 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} + if CURVETYPE==WEIERSTRASS { + zs2:=NewFPcopy(E.z); zs2.sqr() + zo2:=NewFPcopy(Q.z); zo2.sqr() + zs3:=NewFPcopy(zs2); zs3.mul(E.z) + zo3:=NewFPcopy(zo2); zo3.mul(Q.z) + zs2.mul(Q.x) + zo2.mul(E.x) + if !zs2.equals(zo2) {return false} + zs3.mul(Q.y) + zo3.mul(E.y) + if !zs3.equals(zo3) {return false} + } else { + 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==EDWARDS { + 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) + if CURVE_A==-1 {r.neg()} + r.sub(one) + 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() + if CURVETYPE==WEIERSTRASS { + z2:=NewFPcopy(E.z) + z2.sqr() + E.x.mul(z2); E.x.reduce() + E.y.mul(z2) + E.y.mul(E.z); E.y.reduce() + } + if CURVETYPE==EDWARDS { + E.x.mul(E.z); E.x.reduce() + E.y.mul(E.z); E.y.reduce() + } + if CURVETYPE==MONTGOMERY { + E.x.mul(E.z); E.x.reduce() + } + E.z.one() +} + +/* extract x as a BIG */ +func (E *ECP) getX() *BIG { + E.affine() + return E.x.redc() +} +/* extract y as a BIG */ +func (E *ECP) getY() *BIG { + E.affine() + return E.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) { + var t [int(MODBYTES)]byte + MB:=int(MODBYTES) + if CURVETYPE!=MONTGOMERY { + b[0]=0x04 + } else {b[0]=0x02} + + E.affine() + E.x.redc().toBytes(t[:]) + for i:=0;i=0 {return NewECP()} + + if (b[0]==0x04) { + for i:=0;i=0 {return NewECP()} + return NewECPbigs(px,py) + } else {return NewECPbig(px)} +} + +/* convert to hex string */ +func (E *ECP) toString() string { + if E.is_infinity() {return "infinity"} + E.affine(); + if CURVETYPE==MONTGOMERY { + return "("+E.x.redc().toString()+")" + } else {return "("+E.x.redc().toString()+","+E.y.redc().toString()+")"} +} + +/* this*=2 */ +func (E *ECP) dbl() { + if CURVETYPE==WEIERSTRASS { + if E.INF {return} + if E.y.iszilch() { + E.inf() + return + } + + w1:=NewFPcopy(E.x); + w6:=NewFPcopy(E.z); + w2:=NewFPint(0); + w3:=NewFPcopy(E.x) + w8:=NewFPcopy(E.x) + + if CURVE_A==-3 { + w6.sqr() + w1.copy(w6) + w1.neg() + w3.add(w1) + + w8.add(w6) + + w3.mul(w8) + w8.copy(w3) + w8.imul(3) + } else { + w1.sqr() + w8.copy(w1) + w8.imul(3) + } + + w2.copy(E.y); w2.sqr() + w3.copy(E.x); w3.mul(w2) + w3.imul(4) + w1.copy(w3); w1.neg() + // w1.norm(); + + + E.x.copy(w8); E.x.sqr() + E.x.add(w1) + E.x.add(w1) + // x.reduce(); + E.x.norm() + + E.z.mul(E.y) + E.z.add(E.z) + + w2.add(w2) + w2.sqr() + w2.add(w2) + w3.sub(E.x) + E.y.copy(w8); E.y.mul(w3); + // w2.norm(); + E.y.sub(w2) + // y.reduce(); + // z.reduce(); + E.y.norm() + 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) + C.sqr() + D.sqr() + if CURVE_A==-1 {C.neg()} + E.y.copy(C); E.y.add(D) + // y.norm(); + H.sqr(); H.add(H) + E.z.copy(E.y) + J.copy(E.y); J.sub(H) + E.x.mul(J) + C.sub(D) + E.y.mul(C) + E.z.mul(J) + + E.x.norm() + E.y.norm() + E.z.norm() + } + 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) + AA.copy(A); AA.sqr() + B.sub(E.z) + 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) + E.z.copy(BB); E.z.mul(C) + // x.reduce(); + // z.reduce(); + E.x.norm() + E.z.norm() + } + return; +} + +/* this+=Q */ +func (E *ECP) add(Q *ECP) { + if CURVETYPE==WEIERSTRASS { + if E.INF { + E.copy(Q) + return + } + if Q.INF {return} + + aff:=false + + one:=NewFPint(1) + if Q.z.equals(one) {aff=true} + + var A,C *FP + B:=NewFPcopy(E.z) + D:=NewFPcopy(E.z) + if !aff { + A=NewFPcopy(Q.z) + C=NewFPcopy(Q.z) + + A.sqr(); B.sqr() + C.mul(A); D.mul(B) + + A.mul(E.x) + C.mul(E.y) + } else { + A=NewFPcopy(E.x) + C=NewFPcopy(E.y) + + B.sqr() + D.mul(B) + } + + B.mul(Q.x); B.sub(A) + D.mul(Q.y); D.sub(C) + + if B.iszilch() { + if D.iszilch() { + E.dbl() + return + } else { + E.INF=true + return + } + } + + if !aff {E.z.mul(Q.z)} + E.z.mul(B) + + e:=NewFPcopy(B); e.sqr() + B.mul(e) + A.mul(e) + + e.copy(A) + e.add(A); e.add(B) + E.x.copy(D); E.x.sqr(); E.x.sub(e); + + A.sub(E.x); + E.y.copy(A); E.y.mul(D) + C.mul(B); E.y.sub(C) + + // x.reduce(); + // y.reduce(); + // z.reduce(); + E.x.norm() + E.y.norm() + 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) + //H:=NewFPint(0) + //I:=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.mul(D) + B.sub(C) + B.mul(F) + E.x.copy(A); E.x.mul(B) + + if CURVE_A==1 { + C.copy(EE); C.mul(G) + } + if CURVE_A==-1 { + C.mul(G) + } + E.y.copy(A); E.y.mul(C) + E.z.copy(F); E.z.mul(G) + // x.reduce(); y.reduce(); z.reduce(); + E.x.norm(); E.y.norm(); E.z.norm() + } + 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) + + DA.copy(D); DA.mul(A) + CB.copy(C); CB.mul(B) + + A.copy(DA); A.add(CB); A.sqr() + B.copy(DA); B.sub(CB); 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;} + + // x.reduce(); + E.x.norm(); +} + +/* this-=Q */ +func (E *ECP) sub(Q *ECP) { + Q.neg() + E.add(Q) + Q.neg() +} + +func multiaffine(m int,P []*ECP) { + t1:=NewFPint(0) + t2:=NewFPint(0) + + var work []*FP + + for i:=0;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) + } + + +// convert the table to affine + if CURVETYPE==WEIERSTRASS { + multiaffine(8,W[:]) + } + + +// 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 +} + +/* 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); + +// convert the table to affine + if CURVETYPE==WEIERSTRASS { + multiaffine(8,W) + } + +// 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 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/manudrijvers/amcl/go/ECP2-additions.go b/vendor/github.com/manudrijvers/amcl/go/ECP2-additions.go new file mode 100644 index 00000000000..c1df859a7a5 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/ECP2-additions.go @@ -0,0 +1,58 @@ +/* +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. +*/ + +/* AMCL Weierstrass elliptic curve functions over FP2 */ + +package amcl + +func (E *ECP2) Is_infinity() bool { + return E.is_infinity() +} +func (E *ECP2) Copy(P *ECP2) { + E.copy(P) +} +func (E *ECP2) Neg() { + E.neg() +} +func (E *ECP2) Equals(Q *ECP2) bool { + return E.equals(Q) +} +func (E *ECP2) GetX() *FP2 { + return E.getX() +} +func (E *ECP2) GetY() *FP2 { + return E.getY() +} +func (E *ECP2) ToBytes(b []byte) { + E.toBytes(b) +} +func (E *ECP2) ToString() string { + return E.toString() +} +func (E *ECP2) Add(Q *ECP2) int { + return E.add(Q) +} +func (E *ECP2) Sub(Q *ECP2) int { + return E.sub(Q) +} +func (E *ECP2) Mul(e *BIG) *ECP2 { + return E.mul(e) +} + + diff --git a/vendor/github.com/manudrijvers/amcl/go/ECP2.go b/vendor/github.com/manudrijvers/amcl/go/ECP2.go new file mode 100644 index 00000000000..186e82ea582 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/ECP2.go @@ -0,0 +1,568 @@ +/* +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 amcl + +//import "fmt" + +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(1) + E.INF=true + return E +} + +/* Test this=O? */ +func (E *ECP2) is_infinity() bool { + return E.INF +} +/* 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.zero() + E.z.zero() +} + +/* set this=-this */ +func (E *ECP2) neg() { + if E.is_infinity() {return} + E.y.neg(); E.y.reduce() +} + +/* 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} + + zs2:=NewFP2copy(E.z); zs2.sqr() + zo2:=NewFP2copy(Q.z); zo2.sqr() + zs3:=NewFP2copy(zs2); zs3.mul(E.z) + zo3:=NewFP2copy(zo2); zo3.mul(Q.z) + zs2.mul(Q.x) + zo2.mul(E.x) + if !zs2.equals(zo2) {return false} + zs3.mul(Q.y) + zo3.mul(E.y) + if !zs3.equals(zo3) {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) {return} + E.z.inverse() + + z2:=NewFP2copy(E.z); + z2.sqr() + E.x.mul(z2); E.x.reduce() + E.y.mul(z2) + E.y.mul(E.z); E.y.reduce() + E.z.copy(one) +} + +/* extract affine x as FP2 */ +func (E *ECP2) getX() *FP2 { + E.affine() + return E.x +} +/* extract affine y as FP2 */ +func (E *ECP2) getY() *FP2 { + E.affine(); + return E.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) + + E.affine() + E.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 +} + +/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */ +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) + + multiaffine2(8,W[:]) + +/* 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 +} + diff --git a/vendor/github.com/manudrijvers/amcl/go/FF.go b/vendor/github.com/manudrijvers/amcl/go/FF.go new file mode 100644 index 00000000000..5cfbbdba23c --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/FF.go @@ -0,0 +1,877 @@ +/* +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. +*/ + +package amcl + +//import "fmt" +//import "os" + +//var debug bool = false + +type FF struct { + length int + v []*BIG +} + +/* Constructors */ +func NewFFint(n int) *FF { + F:=new(FF) + for i:=0;i>n */ +func (F *FF) sducopy(b *FF) { + for i:=0;i=0;i-- { + j:=comp(a.v[i],b.v[i]) + if j!=0 {return j} + } + return 0 +} + +/* recursive add */ +func (F *FF) radd(vp int,x *FF,xp int,y *FF,yp int,n int) { + for i:=0;i0;i-- { + carry:=F.v[i].fshr(1) + F.v[i-1].xortop(Chunk(carry)<=0;i-- { + s+=F.v[i].toString() + } + return s +} + +/* Convert FFs to/from byte arrays */ +func (F *FF) toBytes(b []byte) { + for i:=0;i=0 { + c.shl() + k++ + } + + for k>0 { + c.shr() + if ff_comp(F,c)>=0 { + F.sub(c) + F.norm() + } + k-- + } +} + +/* z=x^2 */ +func ff_sqr(x *FF) *FF { + n:=x.length + z:=NewFFint(2*n) + t:=NewFFint(2*n) + z.karsqr(0,x,0,t,0,n) + return z +} + +/* return This mod modulus, N is modulus, ND is Montgomery Constant */ +func (F *FF) reduce(N *FF,ND *FF) *FF { /* fast karatsuba Montgomery reduction */ + n:=N.length + t:=NewFFint(2*n) + r:=NewFFint(n) + m:=NewFFint(n) + + r.sducopy(F) + m.karmul_lower(0,F,0,ND,0,t,0,n) + + F.karmul_upper(N,m,t,n) + + m.sducopy(F) + r.add(N) + r.sub(m) + r.norm() + + return r + +} + +/* Set r=this mod b */ +/* this is of length - 2*n */ +/* r,b is of length - n */ +func (F *FF) dmod(b *FF) *FF { + n:=b.length + m:=NewFFint(2*n) + x:=NewFFint(2*n) + r:=NewFFint(n) + + x.copy(F) + x.norm() + m.dsucopy(b); k:=BIGBITS*n + + for k>0 { + m.shr() + + if ff_comp(x,m)>=0 { + x.sub(m) + x.norm() + } + k-- + } + + r.copy(x) + r.mod(b) + return r +} + +/* Set return=1/this mod p. Binary method - a

=0 { + u.sub(v) + u.norm() + if ff_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 ff_comp(x2,x1)>=0 { + x2.sub(x1) + } else { + t.copy(p) + t.sub(x1) + x2.add(t) + } + x2.norm() + } + } + if ff_comp(u,one)==0 { + F.copy(x1) + } else { + F.copy(x2) + } +} + +/* nresidue mod m */ +func (F *FF) nres(m *FF) { + n:=m.length + d:=NewFFint(2*n) + d.dsucopy(F) + F.copy(d.dmod(m)) +} + +func (F *FF) redc(m *FF,ND *FF) { + n:=m.length + d:=NewFFint(2*n) + F.mod(m) + d.dscopy(F) + F.copy(d.reduce(m,ND)) + F.mod(m) +} + +func (F *FF) mod2m(m int) { + for i:=m;i=0;i-- { + b:=int(e.v[i/BIGBITS].bit(i%BIGBITS)) + F.copy(R0) + F.modmul(R1,p,ND) + + ff_cswap(R0,R1,b) + R0.modsqr(p,ND) + + R1.copy(F) + ff_cswap(R0,R1,b) + } + F.copy(R0) + F.redc(p,ND) +} + +/* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */ +func (F *FF) skpows(e *BIG,p *FF) { + n:=p.length + R0:=NewFFint(n) + R1:=NewFFint(n) + ND:=p.invmod2m() + + F.mod(p) + R0.one() + R1.copy(F) + R0.nres(p) + R1.nres(p) + + for i:=int(8*MODBYTES)-1;i>=0;i-- { + b:=int(e.bit(i)) + F.copy(R0) + F.modmul(R1,p,ND) + + ff_cswap(R0,R1,b) + R0.modsqr(p,ND) + + R1.copy(F) + ff_cswap(R0,R1,b) + } + F.copy(R0) + F.redc(p,ND) +} + +/* raise to an integer power - right-to-left method */ +func (F *FF) power(e int,p *FF) { + n:=p.length + w:=NewFFint(n) + ND:=p.invmod2m() + f:=true + + w.copy(F) + w.nres(p) +//i:=0; + if e==2 { + F.copy(w) + F.modsqr(p,ND) + } else { + for (true) { + if e%2==1 { + if f { + F.copy(w) + } else {F.modmul(w,p,ND)} + f=false + + } + e>>=1 + if e==0 {break} +//fmt.Printf("wb= "+w.toString()+"\n"); +//debug=true; + w.modsqr(p,ND) +//debug=false; +//fmt.Printf("wa= "+w.toString()+"\n"); +//i+=1; +//os.Exit(0); + } + } + + F.redc(p,ND) + +} + +/* this=this^e mod p, faster but not side channel resistant */ +func (F *FF) pow(e *FF,p *FF) { + n:=p.length + w:=NewFFint(n) + ND:=p.invmod2m() +//fmt.Printf("ND= "+ND.toString() +"\n"); + w.copy(F) + F.one() + F.nres(p) + w.nres(p) + for i:=int(8*MODBYTES)*n-1;i>=0;i-- { + F.modsqr(p,ND) + b:=e.v[i/BIGBITS].bit(i%BIGBITS) + if b==1 {F.modmul(w,p,ND)} + } + F.redc(p,ND) +} + +/* double exponentiation r=x^e.y^f mod p */ +func (F *FF) pow2(e *BIG,y *FF,f *BIG,p *FF) { + n:=p.length + xn:=NewFFint(n) + yn:=NewFFint(n) + xy:=NewFFint(n) + ND:=p.invmod2m() + + xn.copy(F) + yn.copy(y) + xn.nres(p) + yn.nres(p) + xy.copy(xn); xy.modmul(yn,p,ND) + F.one() + F.nres(p) + + for i:=int(8*MODBYTES)-1;i>=0;i-- { + eb:=e.bit(i) + fb:=f.bit(i) + F.modsqr(p,ND) + if eb==1 { + if fb==1 { + F.modmul(xy,p,ND) + } else {F.modmul(xn,p,ND)} + } else { + if fb==1 {F.modmul(yn,p,ND)} + } + } + F.redc(p,ND) +} + +func igcd(x int,y int) int { /* integer GCD, returns GCD of x and y */ + var r int + if y==0 {return x} + for true { + r=x%y + if r==0 {break} + x=y;y=r + } + return y +} + +/* quick and dirty check for common factor with n */ +func (F *FF) cfactor(s int) bool { + n:=F.length + + x:=NewFFint(n) + y:=NewFFint(n) + + y.set(s) + x.copy(F) + x.norm() + + x.sub(y) + x.norm() + + for (!x.iszilch() && x.parity()==0) {x.shr()} + + for (ff_comp(x,y)>0) { + x.sub(y) + x.norm() + for (!x.iszilch() && x.parity()==0) {x.shr()} + } + + g:=int(x.v[0].get(0)) + r:=igcd(s,g) + if r>1 {return true} + return false +} + +/* Miller-Rabin test for primality. Slow. */ +func prime(p *FF,rng *RAND) bool { + s:=0 + n:=p.length + d:=NewFFint(n) + x:=NewFFint(n) + unity:=NewFFint(n) + nm1:=NewFFint(n) + + sf:=4849845 /* 3*5*.. *19 */ + p.norm() + + if p.cfactor(sf) {return false} + unity.one() + nm1.copy(p) + nm1.sub(unity) + nm1.norm() + d.copy(nm1) + + for d.parity()==0 { + d.shr() + s++ + } + if s==0 {return false} + + for i:=0;i<10;i++ { + x.randomnum(p,rng) + x.pow(d,p) + + if (ff_comp(x,unity)==0 || ff_comp(x,nm1)==0) {continue} + loop:=false + for j:=1;j> 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+1) +} + +/* this = -this mod Modulus */ +func (F *FP) neg() { + p:=NewBIGints(Modulus) + m:=NewBIGcopy(p) + F.norm() + sb:=logb2(uint32(EXCESS(F.x))) + +// ov:=EXCESS(F.x); +// sb:=uint(1); for ov!=0 {sb++;ov>>=1} + + m.fshl(sb) + F.x.rsub(m) + + if EXCESS(F.x)>=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 + } + afx:=(EXCESS(F.x)+1)*(Chunk(c)+1)+1; + if (c=FEXCESS) {F.reduce()} +} + +/* this-=b */ +func (F *FP) sub(b *FP) { + n:=NewFPcopy(b) + n.neg() + F.add(n) +} + +/* 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() +} + +/* return TRUE if this==a */ +func (F *FP) equals(a *FP) bool { + a.reduce() + F.reduce() + if (comp(a.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.x.norm() + m:=NewFPcopy(F) + for true { + bt:=e.parity(); + e.fshr(1); + if bt==1 {r.mul(m)} + if e.iszilch() {break} + m.sqr(); + } + p:=NewBIGints(Modulus); + r.x.mod(p); + 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/manudrijvers/amcl/go/FP12-additions.go b/vendor/github.com/manudrijvers/amcl/go/FP12-additions.go new file mode 100644 index 00000000000..59cf34896f5 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/FP12-additions.go @@ -0,0 +1,81 @@ +/* +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. +*/ + +/* AMCL Fp^12 functions */ +/* FP12 elements are of the form a+i.b+i^2.c */ + +package amcl + +//import "fmt" + +func (F *FP12) Geta() *FP4 { + return F.geta() +} + +func (F *FP12) Getb() *FP4 { + return F.getb() +} + +func (F *FP12) Getc() *FP4 { + return F.getc() +} + +func (F *FP12) Copy(x *FP12) { + F.copy(x) +} + +func (F *FP12) One() { + F.one() +} + +func (F *FP12) ToString() string { + return F.toString() +} + +func (F *FP12) Equals(x *FP12) bool { + return F.equals(x) +} + +func (F *FP12) Mul(y *FP12) { + F.mul(y) +} + +func (F *FP12) Inverse() { + F.inverse() +} +func (F *FP12) Isunity() bool { + return F.isunity() +} + +func (F *FP12) ToBytes(w []byte) { + F.toBytes(w) +} + +func (F *FP12) Pow(e *BIG) *FP12 { + return F.pow(e) +} + +func Pow4(q []*FP12,u []*BIG) *FP12 { + return pow4(q, u) +} + +func (F *FP12) Pinpow(e int,bts int) { + F.pinpow(e, bts) +} + diff --git a/vendor/github.com/manudrijvers/amcl/go/FP12.go b/vendor/github.com/manudrijvers/amcl/go/FP12.go new file mode 100644 index 00000000000..36d52963e3f --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/FP12.go @@ -0,0 +1,551 @@ +/* +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 amcl + +//import "fmt" + +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()) +} +/* 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) + C.sqr() + D.mul(F.b) + D.add(D) + + F.c.add(F.a) + F.c.add(F.b) + 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) + t1.add(y.b) + + z1.copy(t0); z1.mul(t1) + t0.copy(F.b); t0.add(F.c) + + t1.copy(y.b); t1.add(y.c) + 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) + t1.copy(y.a); t1.add(y.c) + t0.mul(t1) + z2.add(t0) + + t0.copy(F.c); t0.mul(y.c) + t1.copy(t0); t1.neg() + + z2.norm(); + z3.norm(); + F.b.norm(); + + F.c.copy(z2); F.c.add(t1) + z3.add(t1) + t0.times_i() + F.b.add(t0) + + 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) { + 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()) + + F.b.mul(t1) + z3.add(F.c); + 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) + z2.add(t0) + + t0.copy(F.a); t0.add(F.c) + t0.mul(y.a) + F.c.copy(z2); F.c.add(t0) + + 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) + + f1.copy(F.c); f1.sqr() + f1.times_i() + f2.mul(F.b) + f1.sub(f2) + + f2.copy(F.b); f2.sqr() + f3.copy(F.a); f3.mul(F.c) + f2.sub(f3) + + 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.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=0;i-- { + b:=(e>>uint(i))&1 + R[1-b].mul(R[b]) + R[b].usqr() + } + F.copy(R[0]) +} + +/* p=q0^u0.q1^u1.q2^u2.q3^u3 */ +/* Timing attack secure, but not cache attack secure */ + + 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/manudrijvers/amcl/go/FP2-additions.go b/vendor/github.com/manudrijvers/amcl/go/FP2-additions.go new file mode 100644 index 00000000000..cdece73a8a7 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/FP2-additions.go @@ -0,0 +1,78 @@ +/* +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 amcl + +func (F *FP2) Isunity() bool { + return F.isunity() +} + +func (F *FP2) Equals(x *FP2) bool { + return F.equals(x) +} + +func (F *FP2) GetA() *BIG { + return F.getA() +} + +func (F *FP2) GetB() *BIG { + return F.getB() +} + +func (F *FP2) Copy(x *FP2) { + F.copy(x) +} + +func (F *FP2) Zero() { + F.zero() +} + +func (F *FP2) One() { + F.one() +} + +func (F *FP2) Neg() { + F.neg() +} + +func (F *FP2) Add(x *FP2) { + F.add(x) +} + +func (F *FP2) Sub(x *FP2) { + F.sub(x) +} + +func (F *FP2) Mul(y *FP2) { + F.mul(y) +} + +func (F *FP2) ToString() string { + return F.toString() +} + +func (F *FP2) Inverse() { + F.inverse() +} + + diff --git a/vendor/github.com/manudrijvers/amcl/go/FP2.go b/vendor/github.com/manudrijvers/amcl/go/FP2.go new file mode 100644 index 00000000000..3de27cd782d --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/FP2.go @@ -0,0 +1,300 @@ +/* +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 amcl + +//import "fmt" + +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() +} + +/* 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*=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() { + F.norm() + w1:=NewFPcopy(F.a) + w3:=NewFPcopy(F.a) + mb:=NewFPcopy(F.b) + + w3.mul(F.b) + w1.add(F.b) + mb.neg() + F.a.add(mb) + F.a.mul(w1) + F.b.copy(w3); F.b.add(w3) + + F.norm() +} + +/* this*=y */ +func (F *FP2) mul(y *FP2) { + F.norm(); /* This is needed here as {a,b} is not normed before additions */ + + w1:=NewFPcopy(F.a) + w2:=NewFPcopy(F.b) + w5:=NewFPcopy(F.a) + mw:=NewFPint(0) + + w1.mul(y.a) // w1=a*y.a - this norms w1 and y.a, NOT a + w2.mul(y.b) // w2=b*y.b - this norms w2 and y.b, NOT b + w5.add(F.b) // w5=a+b + F.b.copy(y.a); F.b.add(y.b) // b=y.a+y.b + + F.b.mul(w5); + mw.copy(w1); mw.add(w2); mw.neg() + + F.b.add(mw); mw.add(w1) + F.a.copy(w1); F.a.add(mw) + + F.norm() +} + +/* 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.div2() + if w2.jacobi()!=1 { + w2.copy(F.a); w2.sub(w1); 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() + 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() +} + +/* 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.div2() +} diff --git a/vendor/github.com/manudrijvers/amcl/go/FP4.go b/vendor/github.com/manudrijvers/amcl/go/FP4.go new file mode 100644 index 00000000000..1f99c6cb9e9 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/FP4.go @@ -0,0 +1,479 @@ +/* +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 amcl + +//import "fmt" + +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() +} + +/* 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() { + 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) +} + +/* this=conjugate(this) */ +func (F *FP4) conj() { + F.b.neg(); F.b.norm() +} + +/* this=-conjugate(this) */ +func (F *FP4) nconj() { + F.a.neg(); F.a.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*=s where s is FP2 */ +func (F *FP4) pmul(s *FP2) { + F.a.mul(s) + F.b.mul(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) + F.a.copy(t1) + + F.a.mul(t2) + + t2.copy(t3) + t2.mul_ip() + t2.add(t3) + 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) + + t4.mul(t3) + t4.sub(t1) + t4.norm(); + + F.b.copy(t4) + F.b.sub(t2) + 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() + t1.sub(t2) + t1.inverse() + F.a.mul(t1) + t1.neg() + 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) +} + +/* 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) + r.sub(y); + r.pmul(F.a) + t.add(y) + 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) + 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>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 32-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;iRM { + 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 +} + +/* 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 MPIN_INVALID_POINT} + h:=hashitmpin(sha,0,CID) + R:=mapit(h) + + R=R.pinmul(int32(pin)%MPIN_MAXPIN,MPIN_PBLEN) + P.sub(R) + + P.toBytes(TOKEN) + + 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 MPIN_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) + //G1mul(P,px).toBytes(SEC) + return 0 +} + +/* Implement step 1 on client side of MPin protocol */ +func MPIN_CLIENT_1(sha int,date int,CLIENT_ID []byte,rng *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:=hashitmpin(sha,0,CLIENT_ID) + P:=mapit(h) + + T:=ECP_fromBytes(TOKEN) + if T.is_infinity() {return MPIN_INVALID_POINT} + + W:=P.pinmul(int32(pin)%MPIN_MAXPIN,MPIN_PBLEN) + T.add(W) + if date!=0 { + W=ECP_fromBytes(PERMIT) + if W.is_infinity() {return MPIN_INVALID_POINT} + T.add(W) + h=hashitmpin(sha,int32(date),h) + W=mapit(h) + if xID!=nil { + P=G1mul(P,x) + P.toBytes(xID) + W=G1mul(W,x) + P.add(W) + } else { + P.add(W) + P=G1mul(P,x) + } + if xCID!=nil {P.toBytes(xCID)} + } else { + if xID!=nil { + P=G1mul(P,x) + P.toBytes(xID) + } + } + + + T.toBytes(SEC) + 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:=NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa),NewBIGints(CURVE_Pxb)),NewFP2bigs(NewBIGints(CURVE_Pya),NewBIGints(CURVE_Pyb))) + + 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 *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 MPIN_INVALID_POINT} + } else {P=mapit(G)} + + G1mul(P,x).toBytes(W) + 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:=hashitmpin(sha,int32(date),CID) + P:=mapit(h) + + s:=fromBytes(S) + G1mul(P,s).toBytes(CTT) + 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:=hashitmpin(sha,0,CID) + P:=mapit(h) + + P.toBytes(HID); + if date!=0 { + // if HID!=nil {P.toBytes(HID)} + h=hashitmpin(sha,int32(date),h) + R:=mapit(h) + P.add(R) + P.toBytes(HTID) + } //else {P.toBytes(HID)} +} + +/* 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:=NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa),NewBIGints(CURVE_Pxb)),NewFP2bigs(NewBIGints(CURVE_Pya),NewBIGints(CURVE_Pyb))) + + sQ:=ECP2_fromBytes(SST) + if sQ.is_infinity() {return MPIN_INVALID_POINT} + + var R *ECP + if date!=0 { + R=ECP_fromBytes(xCID) + } else { + if xID==nil {return MPIN_BAD_PARAMS} + R=ECP_fromBytes(xID) + } + if R.is_infinity() {return MPIN_INVALID_POINT} + + y:=fromBytes(Y) + var P *ECP + if date!=0 { + P=ECP_fromBytes(HTID) + } else { + if HID==nil {return MPIN_BAD_PARAMS} + P=ECP_fromBytes(HID) + } + + if P.is_infinity() {return MPIN_INVALID_POINT} + + P=G1mul(P,y) + P.add(R) + R=ECP_fromBytes(mSEC) + if R.is_infinity() {return MPIN_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 MPIN_INVALID_POINT} + R=ECP_fromBytes(xID) + if R.is_infinity() {return MPIN_INVALID_POINT} + + P=G1mul(P,y) + P.add(R) + } + g=ate(Q,P) + g=fexp(g) + g.toBytes(F) + } + return MPIN_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 [MPIN_TS]int + t:=NewFP12copy(gf) + + var table []*FP12 + var i int + s:=1 + for m:=0;m4*MPIN_TRAP {break} + i=ge.geta().geta().getA().lastbits(20)%MPIN_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*MPIN_TRAP || dm-dn>=int(MPIN_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 MPIN_INVALID_POINT} + + P=mapit(CID) + + Q:=NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa),NewBIGints(CURVE_Pxb)),NewFP2bigs(NewBIGints(CURVE_Pya),NewBIGints(CURVE_Pyb))) + + 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 *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/manudrijvers/amcl/go/PAIR-additions.go b/vendor/github.com/manudrijvers/amcl/go/PAIR-additions.go new file mode 100644 index 00000000000..11764f41d75 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/PAIR-additions.go @@ -0,0 +1,33 @@ +/* +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. +*/ + +/* AMCL BN Curve Pairing functions */ + +package amcl + + +func Ate(P *ECP2, Q *ECP) *FP12 { + return ate(P, Q) +} +func Ate2(P *ECP2, Q *ECP, R *ECP2, S *ECP) *FP12 { + return ate2(P, Q, R, S) +} +func Fexp(m *FP12) *FP12 { + return fexp(m) +} diff --git a/vendor/github.com/manudrijvers/amcl/go/PAIR.go b/vendor/github.com/manudrijvers/amcl/go/PAIR.go new file mode 100644 index 00000000000..b6b88f82978 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/PAIR.go @@ -0,0 +1,641 @@ +/* +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 amcl + +//import "fmt" + +/* Line function */ +func line(A *ECP2,B *ECP2,Qx *FP,Qy *FP) *FP12 { + P:=NewECP2() + + P.copy(A); + ZZ:=NewFP2copy(P.getz()) + ZZ.sqr() + var D int + if A==B { + D=A.dbl() + } else {D=A.add(B)} + + if D<0 {return NewFP12int(1)} + + Z3:=NewFP2copy(A.getz()) + + var a *FP4 + var b *FP4 + c:=NewFP4int(0) + + if (D==0) { /* Addition */ + X:=NewFP2copy(B.getx()) + Y:=NewFP2copy(B.gety()) + T:=NewFP2copy(P.getz()) + T.mul(Y) + ZZ.mul(T) + + NY:=NewFP2copy(P.gety()); NY.neg() + ZZ.add(NY) + Z3.pmul(Qy) + T.mul(P.getx()); + X.mul(NY); + T.add(X); + a=NewFP4fp2s(Z3,T) + ZZ.neg(); + ZZ.pmul(Qx) + b=NewFP4fp2(ZZ) + } else { /* Doubling */ + X:=NewFP2copy(P.getx()) + Y:=NewFP2copy(P.gety()) + T:=NewFP2copy(P.getx()) + T.sqr() + T.imul(3) + + Y.sqr() + Y.add(Y) + Z3.mul(ZZ) + Z3.pmul(Qy) + + X.mul(T) + X.sub(Y) + a=NewFP4fp2s(Z3,X) + T.neg() + ZZ.mul(T) + ZZ.pmul(Qx) + b=NewFP4fp2(ZZ) + } + return NewFP12fp4s(a,b,c) +} + +/* Optimal R-ate pairing */ +func ate(P *ECP2,Q *ECP) *FP12 { + f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_Frb)) + x:=NewBIGints(CURVE_Bnx) + n:=NewBIGcopy(x) + K:=NewECP2() + var lv *FP12 + + if CURVE_PAIRING_TYPE == BN_CURVE { + n.pmul(6); n.dec(2) + } else {n.copy(x)} + + n.norm() + P.affine() + Q.affine() + Qx:=NewFPcopy(Q.getx()) + Qy:=NewFPcopy(Q.gety()) + + A:=NewECP2() + r:=NewFP12int(1) + + A.copy(P) + nb:=n.nbits() + + for i:=nb-2;i>=1;i-- { + lv=line(A,A,Qx,Qy) + r.smul(lv) + if n.bit(i)==1 { + + lv=line(A,P,Qx,Qy) + + r.smul(lv) + } + r.sqr() + } + + lv=line(A,A,Qx,Qy) + r.smul(lv) + + if n.parity()==1 { + lv=line(A,P,Qx,Qy) + r.smul(lv) + } + +/* R-ate fixup required for BN curves */ + + if CURVE_PAIRING_TYPE == BN_CURVE { + r.conj() + K.copy(P) + K.frob(f) + A.neg() + lv=line(A,K,Qx,Qy) + r.smul(lv) + K.frob(f) + K.neg() + lv=line(A,K,Qx,Qy) + r.smul(lv) + } + + return r +} + +/* Optimal R-ate double pairing e(P,Q).e(R,S) */ +func ate2(P *ECP2,Q *ECP,R *ECP2,S *ECP) *FP12 { + f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_Frb)) + x:=NewBIGints(CURVE_Bnx) + n:=NewBIGcopy(x) + K:=NewECP2() + var lv *FP12 + + if CURVE_PAIRING_TYPE == BN_CURVE { + n.pmul(6); n.dec(2) + } else {n.copy(x)} + + n.norm() + P.affine() + Q.affine() + R.affine() + 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) + nb:=n.nbits() + + for i:=nb-2;i>=1;i-- { + lv=line(A,A,Qx,Qy) + r.smul(lv) + lv=line(B,B,Sx,Sy) + r.smul(lv) + + if n.bit(i)==1 { + lv=line(A,P,Qx,Qy) + r.smul(lv) + lv=line(B,R,Sx,Sy) + r.smul(lv) + } + r.sqr() + } + + lv=line(A,A,Qx,Qy) + r.smul(lv) + lv=line(B,B,Sx,Sy) + r.smul(lv) + if n.parity()==1 { + lv=line(A,P,Qx,Qy) + r.smul(lv) + lv=line(B,R,Sx,Sy) + r.smul(lv) + } + +/* R-ate fixup */ + if CURVE_PAIRING_TYPE == BN_CURVE { + r.conj() + K.copy(P) + K.frob(f) + A.neg() + lv=line(A,K,Qx,Qy) + r.smul(lv) + K.frob(f) + K.neg() + lv=line(A,K,Qx,Qy) + r.smul(lv) + + K.copy(R) + K.frob(f) + B.neg() + lv=line(B,K,Sx,Sy) + r.smul(lv) + K.frob(f) + K.neg() + lv=line(B,K,Sx,Sy) + r.smul(lv) + } + + return r +} + +/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */ +func fexp(m *FP12) *FP12 { + f:=NewFP2bigs(NewBIGints(CURVE_Fra),NewBIGints(CURVE_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_CURVE { + 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) + + x3:=NewFP12copy(x4) + x3.frob(f) + + x2:=x4.pow(x) + + x5:=NewFP12copy(x2); x5.conj() + lv=x2.pow(x) + + 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) + x.fshr(1); y2:=y1.pow(x); x.fshl(1) + y3:=NewFP12copy(r); y3.conj() + y1.mul(y3) + + y1.conj() + y1.mul(y2) + + y2=y1.pow(x) + + y3=y2.pow(x) + 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) + 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_CURVE { + 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_CURVE { + 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 { + x:=NewBIGints(CURVE_Bnx) + w:=NewBIGcopy(e) + for i:=0;i<4;i++ { + u=append(u,NewBIGcopy(w)) + u[i].mod(x) + w.div(x) + } + } + 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:=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 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 + +//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;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/manudrijvers/amcl/go/ROM32.txt b/vendor/github.com/manudrijvers/amcl/go/ROM32.txt new file mode 100644 index 00000000000..2bbb36a57f7 --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/ROM32.txt @@ -0,0 +1,826 @@ +/* +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. +*/ + +/* Fixed Data in ROM - Field and Curve parameters */ + +package amcl + +type Chunk int32 +type DChunk int64 + +/* 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 */ + +func pexceed(a *BIG,b *BIG) bool { + ea:=EXCESS(a) + eb:=EXCESS(b) + if DChunk(ea+1)*DChunk(eb+1)>DChunk(FEXCESS) {return true} + return false +} + +func sexceed(a *BIG) bool { + ea:=EXCESS(a) + if DChunk(ea+1)*DChunk(ea+1)>DChunk(FEXCESS) {return true} + return false +} + +func ff_pexceed(a *BIG,b *BIG) bool { + ea:=FF_EXCESS(a) + eb:=FF_EXCESS(b) + if DChunk(ea+1)*DChunk(eb+1)>DChunk(P_FEXCESS) {return true} + return false +} + +func ff_sexceed(a *BIG) bool { + ea:=FF_EXCESS(a) + if DChunk(ea+1)*DChunk(ea+1)>DChunk(P_FEXCESS) {return true} + return false +} + +/* return a*b as DBIG */ +func mul(a *BIG,b *BIG) *DBIG { + c:=NewDBIG() + var d [NLEN]DChunk + + for i:=0;i>BASEBITS + + for k:=1;k=1+k/2;i-- {t+=DChunk(a.w[i]-a.w[k-i])*DChunk(b.w[k-i]-b.w[i])}; c.w[k]=Chunk(t)&BMASK; co=t>>BASEBITS + } + + for k:=NLEN;k<2*NLEN-1;k++ { + s-=d[k-NLEN]; t=co+s; for i:=NLEN-1;i>=1+k/2;i-- {t+=DChunk(a.w[i]-a.w[k-i])*DChunk(b.w[k-i]-b.w[i])}; c.w[k]=Chunk(t)&BMASK; co=t>>BASEBITS + } + c.w[2*NLEN-1]=Chunk(co) + + return c +} + +/* return a^2 as DBIG */ +func sqr(a *BIG) *DBIG { + var j int + c:=NewDBIG() + + t:=DChunk(a.w[0])*DChunk(a.w[0]) + c.w[0]=Chunk(t)&BMASK; co:=t>>BASEBITS; + + t=DChunk(a.w[1])*DChunk(a.w[0]); t+=t; t+=co + c.w[1]=Chunk(t)&BMASK; co=t>>BASEBITS + + last:=NLEN-(NLEN%2) + for j=2;j>BASEBITS + t=DChunk(a.w[j+1])*DChunk(a.w[0]); for i:=1;i<(j+2)/2;i++ {t+=DChunk(a.w[j+1-i])*DChunk(a.w[i])}; t+=t; t+=co + c.w[j+1]=Chunk(t)&BMASK; co=t>>BASEBITS + } + j=last; + if (NLEN%2)==1 { + t=DChunk(a.w[j])*DChunk(a.w[0]); for i:=1;i<(j+1)/2;i++ {t+=DChunk(a.w[j-i])*DChunk(a.w[i])}; t+=t; t+=co; t+=DChunk(a.w[j/2])*DChunk(a.w[j/2]) + c.w[j]=Chunk(t)&BMASK; co=t>>BASEBITS; j+=1 + t=DChunk(a.w[NLEN-1])*DChunk(a.w[j-NLEN+1]); for i:=j-NLEN+2;i<(j+1)/2;i++ {t+=DChunk(a.w[j-i])*DChunk(a.w[i])}; t+=t; t+=co + c.w[j]=Chunk(t)&BMASK; co=t>>BASEBITS; j+=1 + } + for ;j>BASEBITS + t=DChunk(a.w[NLEN-1])*DChunk(a.w[j-NLEN+2]); for i:=j-NLEN+3;i<(j+2)/2;i++ {t+=DChunk(a.w[j+1-i])*DChunk(a.w[i])}; t+=t; t+=co + c.w[j+1]=Chunk(t)&BMASK; co=t>>BASEBITS + } + + t=DChunk(a.w[NLEN-1])*DChunk(a.w[NLEN-1])+co + c.w[DNLEN-2]=Chunk(t)&BMASK; co=t>>BASEBITS + c.w[DNLEN-1]=Chunk(co) + + return c +} + +func monty(d *DBIG) *BIG { + var dd [NLEN]DChunk + + var v [NLEN]Chunk + var m=NewBIGints(Modulus) + b:=NewBIG() + + t:=DChunk(d.w[0]); v[0]=(Chunk(t)*MConst)&BMASK; t+=DChunk(v[0])*DChunk(m.w[0]); c:=(t>>BASEBITS)+DChunk(d.w[1]); s:=DChunk(0) + + for k:=1;kk/2;i-- {t+=DChunk(v[k-i]-v[i])*DChunk(m.w[i]-m.w[k-i])} + v[k]=(Chunk(t)*MConst)&BMASK; t+=DChunk(v[k])*DChunk(m.w[0]); c=(t>>BASEBITS)+DChunk(d.w[k+1]) + dd[k]=DChunk(v[k])*DChunk(m.w[k]); s+=dd[k] + } + for k:=NLEN;k<2*NLEN-1;k++ { + t=c+s; + for i:=NLEN-1;i>=1+k/2;i-- {t+=DChunk(v[k-i]-v[i])*DChunk(m.w[i]-m.w[k-i])} + b.w[k-NLEN]=Chunk(t)&BMASK; c=(t>>BASEBITS)+DChunk(d.w[k+1]); s-=dd[k-NLEN+1] + } + b.w[NLEN-1]=Chunk(c)&BMASK; + 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) { + var prod=DChunk(a)*DChunk(b)+DChunk(c)+DChunk(r); + bot:=Chunk(prod)&BMASK; + top:=Chunk(prod>>BASEBITS); + return top,bot +} + + +/********************************************/ + +/* Set Curve */ +/* Don't Modify from here... */ + +const CHUNK int=32 /* Set word size */ + +const NOT_SPECIAL int=0 +const PSEUDO_MERSENNE int=1 +const MONTGOMERY_FRIENDLY int=2 +const GENERALISED_MERSENNE int=3 +const WEIERSTRASS int=0 +const EDWARDS int=1 +const MONTGOMERY int=2 +const BN_CURVE int=0 +const BLS_CURVE int=1 + +/* ...to here */ + + +/*** Enter Some Field details here ***/ +// Curve 25519 +// const MODBITS uint=255 +// const MOD8 uint=5 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// NIST256 or Brainpool +// const MODBITS uint=256 +// const MOD8 uint=7 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// MF254 +// const MODBITS uint=254 +// const MOD8 uint=7 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// MS255 +// const MODBITS uint= 255 +// const MOD8 uint= 3 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// MF256 +// const MODBITS uint=256 +// const MOD8 uint=7 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// MS256 +// const MODBITS uint= 256 +// const MOD8 uint= 3 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// ANSSI +// const MODBITS uint= 256 +// const MOD8 uint= 3 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// BN254 Curve +// const MODBITS uint=254 /* Number of bits in Modulus */ +// const MOD8 uint=3 /* Modulus mod 8 */ +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// BN454 Curve +//const MODBITS uint=454 /* Number of bits in Modulus */ +//const MOD8 uint=3 /* Modulus mod 8 */ +//const BASEBITS uint=29 +//const AES_S uint= 128 + +// BLS383 Curve +const MODBITS uint=383 /* Number of bits in Modulus */ +const MOD8 uint=3 /* Modulus mod 8 */ +const BASEBITS uint=28 +const AES_S uint= 0 + +// BLS455 Curve +//const MODBITS uint=455 /* Number of bits in Modulus */ +//const MOD8 uint=3 /* Modulus mod 8 */ +//const BASEBITS uint=29 +//const AES_S uint= 128 + +// HIFIVE Curve +// const MODBITS uint=336 +// const MOD8 uint=5 +// const BASEBITS uint=29 +// const AES_S uint= 128 + +// GOLDILOCKS +// const MODBITS uint=448 +// const MOD8 uint=7 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// NIST384 +// const MODBITS uint=384 +// const MOD8 uint=7 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// C41417 +// const MODBITS uint=414 +// const MOD8 uint=7 +// const BASEBITS uint=29 +// const AES_S uint= 0 + +// NIST521 +// const MODBITS uint=521 +// const MOD8 uint=7 +// const BASEBITS uint=28 +// const AES_S uint= 0 + +// BN646 Curve +// const MODBITS uint=646 +// const MOD8 uint=3 +// const BASEBITS uint=29 +// const AES_S uint= 192 + +/* RSA/DH modulus length as multiple of BIGBITS */ +const FFLEN int=4 + +/* Don't Modify from here... */ +const NLEN int=int((1+((MODBITS-1)/BASEBITS))) +const DNLEN int=2*NLEN +const BMASK Chunk= ((Chunk(1)<FEXCESS/(eb+1) {return true} + return false +} + +func sexceed(a *BIG) bool { + ea:=EXCESS(a) + if (ea+1)>FEXCESS/(ea+1) {return true} + return false +} + +func ff_pexceed(a *BIG,b *BIG) bool { + ea:=FF_EXCESS(a) + eb:=FF_EXCESS(b) + if (ea+1)>P_FEXCESS/(eb+1) {return true} + return false +} + +func ff_sexceed(a *BIG) bool { + ea:=FF_EXCESS(a) + if (ea+1)>P_FEXCESS/(ea+1) {return true} + return false +} + +/* return a*b as DBIG */ +func mul(a *BIG,b *BIG) *DBIG { + c:=NewDBIG() + carry:= Chunk(0) +// a.norm() +// b.norm() + + 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 +} + + +/********************************************/ + +/* Set Curve */ +/* Don't Modify from here... */ + +const CHUNK int=64 /* Set word size */ + +const NOT_SPECIAL int=0 +const PSEUDO_MERSENNE int=1 +const MONTGOMERY_FRIENDLY int=2 +const GENERALISED_MERSENNE int=3 +const WEIERSTRASS int=0 +const EDWARDS int=1 +const MONTGOMERY int=2 +const BN_CURVE int=0 +const BLS_CURVE int=1 + +/* ...to here */ + + +/*** Enter Some Field details here ***/ +// Curve 25519 +// const MODBITS uint=255 +// const MOD8 uint=5 +// const BASEBITS uint=56 +// const AES_S uint= 0 + +// NIST256 or Brainpool +// const MODBITS uint=256 +// const MOD8 uint=7 +// const BASEBITS uint=56 +// const AES_S uint= 0 + +// MF254 +// const MODBITS uint=254 +// const MOD8 uint=7 +// const BASEBITS uint=56 +// const AES_S uint= 0 + +// MS255 +// const MODBITS uint= 255 +// const MOD8 uint= 3 +// const BASEBITS uint=56 +// const AES_S uint= 0 + +// MF256 +// const MODBITS uint=256 +// const MOD8 uint=7 +// const BASEBITS uint=56 +// const AES_S uint= 0 + +// MS256 +// const MODBITS uint= 256 +// const MOD8 uint= 3 +// const BASEBITS uint=56 +// const AES_S uint= 0 + +// ANSSI +// const MODBITS uint= 256 +// const MOD8 uint= 3 +// const BASEBITS uint=56 +// const AES_S uint= 0 + +// BN254 Curve +const MODBITS uint=254 /* Number of bits in Modulus */ +const MOD8 uint=3 /* Modulus mod 8 */ +const BASEBITS uint=56 +const AES_S uint= 0 + +// BN454 Curve +//const MODBITS uint=454 /* Number of bits in Modulus */ +//const MOD8 uint=3 /* Modulus mod 8 */ +//const BASEBITS uint=60 +//const AES_S uint= 128 + +// BLS383 Curve +//const MODBITS uint=383 /* Number of bits in Modulus */ +//const MOD8 uint=3 /* Modulus mod 8 */ +//const BASEBITS uint=56 +//const AES_S uint= 0 + +// BLS455 Curve +//const MODBITS uint=455 /* Number of bits in Modulus */ +//const MOD8 uint=3 /* Modulus mod 8 */ +//const BASEBITS uint=60 +//const AES_S uint= 128 + +// HIFIVE Curve +// const MODBITS uint=336 +// const MOD8 uint=5 +// const BASEBITS uint=60 +// const AES_S uint= 128 + +// GOLDILOCKS +// const MODBITS uint=448 +// const MOD8 uint=7 +// const BASEBITS uint=60 +// const AES_S uint= 0 + +// NIST384 +// const MODBITS uint=384 +// const MOD8 uint=7 +// const BASEBITS uint=60 +// const AES_S uint= 0 + +// C41417 +// const MODBITS uint=414 +// const MOD8 uint=7 +// const BASEBITS uint=60 +// const AES_S uint= 0 + +// NIST521 +// const MODBITS uint=521 +// const MOD8 uint=7 +// const BASEBITS uint=60 +// const AES_S uint= 0 + +// BN646 Curve +// const MODBITS uint=646 +// const MOD8 uint=3 +// const BASEBITS uint=60 +// const AES_S uint= 192 + +/* RSA/DH modulus length as multiple of BIGBITS */ +const FFLEN int=4 + +/* Don't Modify from here... */ +const NLEN int=int((1+((MODBITS-1)/BASEBITS))) +const DNLEN int=2*NLEN +const BMASK Chunk= ((Chunk(1)<=0 {H.Process_num(int32(n))} + R=H.Hash() + } + if sha==RSA_SHA384 { + H:=NewHASH384() + if A!=nil {H.Process_array(A)} + if n>=0 {H.Process_num(int32(n))} + R=H.Hash() + } + if sha==RSA_SHA512 { + H:=NewHASH512() + if A!=nil {H.Process_array(A)} + if n>=0 {H.Process_num(int32(n))} + R=H.Hash() + } + return R +} + +func RSA_KEY_PAIR(rng *RAND,e int,PRIV *rsa_private_key,PUB *rsa_public_key) { /* IEEE1363 A16.11/A16.12 more or less */ + n:=PUB.n.getlen()/2 + t:=NewFFint(n) + p1:=NewFFint(n) + q1:=NewFFint(n) + + for true { + PRIV.p.random(rng) + for PRIV.p.lastbits(2)!=3 {PRIV.p.inc(1)} + for !prime(PRIV.p,rng) { + PRIV.p.inc(4) + } + + p1.copy(PRIV.p) + p1.dec(1) + + if p1.cfactor(e) {continue} + break; + } + + for true { + PRIV.q.random(rng); + for PRIV.q.lastbits(2)!=3 {PRIV.q.inc(1)} + for !prime(PRIV.q,rng) { + PRIV.q.inc(4) + } + + q1.copy(PRIV.q); + q1.dec(1); + + if q1.cfactor(e) {continue} + + break; + } + + PUB.n=ff_mul(PRIV.p,PRIV.q); + PUB.e=e; + + t.copy(p1) + t.shr() + PRIV.dp.set(e) + PRIV.dp.invmodp(t) + if PRIV.dp.parity()==0 {PRIV.dp.add(t)} + PRIV.dp.norm(); + + t.copy(q1) + t.shr() + PRIV.dq.set(e) + PRIV.dq.invmodp(t) + if PRIV.dq.parity()==0 {PRIV.dq.add(t)} + PRIV.dq.norm() + + PRIV.c.copy(PRIV.p) + PRIV.c.invmodp(PRIV.q) + +} + +/* Mask Generation Function */ + +func RSA_MGF1(sha int,Z []byte,olen int,K []byte) { + hlen:=sha + + var k int=0 + for i:=0;iolen) { + for i:=0;iolen-hlen-seedlen-1) {return nil} + + DBMASK:=make([]byte,olen-seedlen) + + h:=hashitrsa(sha,p,-1); + + for i:=0;i=d;i-- { + f[i]=f[i-d] + } + for i:=d-1;i>=0;i-- { + f[i]=0 + } + return f[:] +} + +/* OAEP Message Decoding for Decryption */ +func RSA_OAEP_DECODE(sha int,p []byte,f []byte) [] byte { + olen:=RSA_RFS-1 + + hlen:=sha + SEED:=make([]byte,hlen) + seedlen:=hlen; + CHASH:=make([]byte,hlen) + + if olen=d;i-- { + f[i]=f[i-d] + } + for i:=d-1;i>=0;i-- { + f[i]=0 + } + } + + h:=hashitrsa(sha,p,-1) + for i:=0;i=olen-seedlen-hlen {return nil} + if DBMASK[k]!=0 {break} + } + + t:=DBMASK[k] + if (!comp || x!=0 || t!=0x01) { + for i:=0;i0 {jq.add(PRIV.q)} + jq.sub(jp) + jq.norm() + + t:=ff_mul(PRIV.c,jq) + jq=t.dmod(PRIV.q) + + t=ff_mul(jq,PRIV.p) + g.add(t) + g.norm() + + g.toBytes(F) +} + diff --git a/vendor/github.com/manudrijvers/amcl/go/readme.txt b/vendor/github.com/manudrijvers/amcl/go/readme.txt new file mode 100644 index 00000000000..39d69b6803f --- /dev/null +++ b/vendor/github.com/manudrijvers/amcl/go/readme.txt @@ -0,0 +1,13 @@ +AMCL is very simple to build for Go. + +This version supports both 32-bit and 64-bit builds. +If your processor and operating system are both 64-bit, a 64-bit build +will probably be best. Otherwise use a 32-bit build. +64-bit is default, you can switch by renaming ROM32.txt to ROM32.go, +and renaming ROM64.go to ROM64.txt. + +Next - decide the modulus and curve type you want to use. Edit ROM32.go +or ROM64.go where indicated. You will probably want to use one of the curves whose +details are already in there. + +To install, simply run go install github.com/manudrijvers/amcl/go. \ No newline at end of file diff --git a/vendor/vendor.json b/vendor/vendor.json index 1f548330b54..21b46542a0a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -281,6 +281,12 @@ "revision": "337395e44efb4affc8bf11971e22acbd4e27a32d", "revisionTime": "2015-07-31T22:42:12+02:00" }, + { + "checksumSHA1": "rdXfB1cKQi3dvOggO/w9QgPK01w=", + "path": "github.com/manudrijvers/amcl/go", + "revision": "765b9c1a68e0d5b22dc09dc7fa7bb46b69b700a8", + "revisionTime": "2017-01-30T13:11:20Z" + }, { "path": "github.com/mattn/go-sqlite3", "revision": "5651a9d9d49ec25811d08220ee972080378d52ea",