// Copyright 2022 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package nistec import "math/bits" // P256OrdInverse sets k to the inverse of k modulo ord(G). k is encoded as four // uint64 limbs in little-endian order, and must be reduced. If k is zero, the // result is zero. func P256OrdInverse(k *[4]uint64) { // Inversion is implemented as exponentiation by n - 2, per Fermat's little theorem. // // The sequence of 38 multiplications and 254 squarings is derived from // https://briansmith.org/ecc-inversion-addition-chains-01#p256_scalar_inversion _1 := new(p256OrdMontElement) _11 := new(p256OrdMontElement) _101 := new(p256OrdMontElement) _111 := new(p256OrdMontElement) _1111 := new(p256OrdMontElement) _10101 := new(p256OrdMontElement) _101111 := new(p256OrdMontElement) x := new(p256OrdMontElement) t := new(p256OrdMontElement) j := (*p256OrdElement)(k) p256OrdToMontgomery(_1, j) // _1 p256OrdSqr(x, _1, 1) // _10 p256OrdMul(_11, x, _1) // _11 p256OrdMul(_101, x, _11) // _101 p256OrdMul(_111, x, _101) // _111 p256OrdSqr(x, _101, 1) // _1010 p256OrdMul(_1111, _101, x) // _1111 p256OrdSqr(t, x, 1) // _10100 p256OrdMul(_10101, t, _1) // _10101 p256OrdSqr(x, _10101, 1) // _101010 p256OrdMul(_101111, _101, x) // _101111 p256OrdMul(x, _10101, x) // _111111 = x6 p256OrdSqr(t, x, 2) // _11111100 p256OrdMul(t, t, _11) // _11111111 = x8 p256OrdSqr(x, t, 8) // _ff00 p256OrdMul(x, x, t) // _ffff = x16 p256OrdSqr(t, x, 16) // _ffff0000 p256OrdMul(t, t, x) // _ffffffff = x32 p256OrdSqr(x, t, 64) p256OrdMul(x, x, t) p256OrdSqr(x, x, 32) p256OrdMul(x, x, t) sqrs := []int{ 6, 5, 4, 5, 5, 4, 3, 3, 5, 9, 6, 2, 5, 6, 5, 4, 5, 5, 3, 10, 2, 5, 5, 3, 7, 6} muls := []*p256OrdMontElement{ _101111, _111, _11, _1111, _10101, _101, _101, _101, _111, _101111, _1111, _1, _1, _1111, _111, _111, _111, _101, _11, _101111, _11, _11, _11, _1, _10101, _1111} for i, s := range sqrs { p256OrdSqr(x, x, s) p256OrdMul(x, x, muls[i]) } p256OrdFromMontgomery(j, x) } // The code below was generated by Fiat Cryptography v0.1.6-63-g92ee794c2, and // then manually formatted and optimized. // // word-by-word-montgomery --lang Go --no-wide-int // --relax-primitive-carry-to-bitwidth 32,64 --cmovznz-by-mul --static // --package-case flatcase --private-function-case camelCase --private-type-case // camelCase --no-prefix-fiat --package-name nistec p256Ord 64 // 2^256-2^224+2^192-89188191075325690597107910205041859247 // mul square from_montgomery to_montgomery // // https://mit-plv.github.io/fiat-crypto/ // // Copyright (c) 2015-2020 the fiat-crypto authors (see the AUTHORS file) // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, // Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // p256OrdMontElement is a scalar field element in the Montgomery domain, as // four uint64 limbs in little-endian order. It must be strictly less than // ord(G) and in Montgomery form (with R 2²⁵⁶). type p256OrdMontElement [4]uint64 // p256OrdMul multiplies two field elements in the Montgomery domain. func p256OrdMul(out1 *p256OrdMontElement, arg1 *p256OrdMontElement, arg2 *p256OrdMontElement) { x1 := arg1[1] x2 := arg1[2] x3 := arg1[3] x4 := arg1[0] x6, x5 := bits.Mul64(x4, arg2[3]) x8, x7 := bits.Mul64(x4, arg2[2]) x10, x9 := bits.Mul64(x4, arg2[1]) x12, x11 := bits.Mul64(x4, arg2[0]) x13, x14 := bits.Add64(x12, x9, 0) x15, x16 := bits.Add64(x10, x7, x14) x17, x18 := bits.Add64(x8, x5, x16) x19 := x18 + x6 _, x20 := bits.Mul64(x11, 0xccd1c8aaee00bc4f) // x20 * 0xffffffff00000000 = x20 * (2^64 - 2^32) x22, b22 := bits.Sub64(0, x20<<32, 0) x23 := x20 - (x20 >> 32) - b22 // x20 * 0xffffffffffffffff = x20 * (2^64 - 1) x24, b24 := bits.Sub64(0, x20, 0) x25 := x20 - b24 x27, x26 := bits.Mul64(x20, 0xbce6faada7179e84) x29, x28 := bits.Mul64(x20, 0xf3b9cac2fc632551) x30, x31 := bits.Add64(x29, x26, 0) x32, x33 := bits.Add64(x27, x24, x31) x34, x35 := bits.Add64(x25, x22, x33) x36 := x35 + x23 _, x38 := bits.Add64(x11, x28, 0) x39, x40 := bits.Add64(x13, x30, x38) x41, x42 := bits.Add64(x15, x32, x40) x43, x44 := bits.Add64(x17, x34, x42) x45, x46 := bits.Add64(x19, x36, x44) x48, x47 := bits.Mul64(x1, arg2[3]) x50, x49 := bits.Mul64(x1, arg2[2]) x52, x51 := bits.Mul64(x1, arg2[1]) x54, x53 := bits.Mul64(x1, arg2[0]) x55, x56 := bits.Add64(x54, x51, 0) x57, x58 := bits.Add64(x52, x49, x56) x59, x60 := bits.Add64(x50, x47, x58) x61 := x60 + x48 x62, x63 := bits.Add64(x39, x53, 0) x64, x65 := bits.Add64(x41, x55, x63) x66, x67 := bits.Add64(x43, x57, x65) x68, x69 := bits.Add64(x45, x59, x67) x70, x71 := bits.Add64(x46, x61, x69) _, x72 := bits.Mul64(x62, 0xccd1c8aaee00bc4f) x74, b74 := bits.Sub64(0, x72<<32, 0) x75 := x72 - (x72 >> 32) - b74 x76, b76 := bits.Sub64(0, x72, 0) x77 := x72 - b76 x79, x78 := bits.Mul64(x72, 0xbce6faada7179e84) x81, x80 := bits.Mul64(x72, 0xf3b9cac2fc632551) x82, x83 := bits.Add64(x81, x78, 0) x84, x85 := bits.Add64(x79, x76, x83) x86, x87 := bits.Add64(x77, x74, x85) x88 := x87 + x75 _, x90 := bits.Add64(x62, x80, 0) x91, x92 := bits.Add64(x64, x82, x90) x93, x94 := bits.Add64(x66, x84, x92) x95, x96 := bits.Add64(x68, x86, x94) x97, x98 := bits.Add64(x70, x88, x96) x99 := x98 + x71 x101, x100 := bits.Mul64(x2, arg2[3]) x103, x102 := bits.Mul64(x2, arg2[2]) x105, x104 := bits.Mul64(x2, arg2[1]) x107, x106 := bits.Mul64(x2, arg2[0]) x108, x109 := bits.Add64(x107, x104, 0) x110, x111 := bits.Add64(x105, x102, x109) x112, x113 := bits.Add64(x103, x100, x111) x114 := x113 + x101 x115, x116 := bits.Add64(x91, x106, 0) x117, x118 := bits.Add64(x93, x108, x116) x119, x120 := bits.Add64(x95, x110, x118) x121, x122 := bits.Add64(x97, x112, x120) x123, x124 := bits.Add64(x99, x114, x122) _, x125 := bits.Mul64(x115, 0xccd1c8aaee00bc4f) x127, b127 := bits.Sub64(0, x125<<32, 0) x128 := x125 - (x125 >> 32) - b127 x129, b129 := bits.Sub64(0, x125, 0) x130 := x125 - b129 x132, x131 := bits.Mul64(x125, 0xbce6faada7179e84) x134, x133 := bits.Mul64(x125, 0xf3b9cac2fc632551) x135, x136 := bits.Add64(x134, x131, 0) x137, x138 := bits.Add64(x132, x129, x136) x139, x140 := bits.Add64(x130, x127, x138) x141 := x140 + x128 _, x143 := bits.Add64(x115, x133, 0) x144, x145 := bits.Add64(x117, x135, x143) x146, x147 := bits.Add64(x119, x137, x145) x148, x149 := bits.Add64(x121, x139, x147) x150, x151 := bits.Add64(x123, x141, x149) x152 := x151 + x124 x154, x153 := bits.Mul64(x3, arg2[3]) x156, x155 := bits.Mul64(x3, arg2[2]) x158, x157 := bits.Mul64(x3, arg2[1]) x160, x159 := bits.Mul64(x3, arg2[0]) x161, x162 := bits.Add64(x160, x157, 0) x163, x164 := bits.Add64(x158, x155, x162) x165, x166 := bits.Add64(x156, x153, x164) x167 := x166 + x154 x168, x169 := bits.Add64(x144, x159, 0) x170, x171 := bits.Add64(x146, x161, x169) x172, x173 := bits.Add64(x148, x163, x171) x174, x175 := bits.Add64(x150, x165, x173) x176, x177 := bits.Add64(x152, x167, x175) _, x178 := bits.Mul64(x168, 0xccd1c8aaee00bc4f) x180, b180 := bits.Sub64(0, x178<<32, 0) x181 := x178 - (x178 >> 32) - b180 x182, b182 := bits.Sub64(0, x178, 0) x183 := x178 - b182 x185, x184 := bits.Mul64(x178, 0xbce6faada7179e84) x187, x186 := bits.Mul64(x178, 0xf3b9cac2fc632551) x188, x189 := bits.Add64(x187, x184, 0) x190, x191 := bits.Add64(x185, x182, x189) x192, x193 := bits.Add64(x183, x180, x191) x194 := x193 + x181 _, x196 := bits.Add64(x168, x186, 0) x197, x198 := bits.Add64(x170, x188, x196) x199, x200 := bits.Add64(x172, x190, x198) x201, x202 := bits.Add64(x174, x192, x200) x203, x204 := bits.Add64(x176, x194, x202) x205 := x204 + x177 x206, x207 := bits.Sub64(x197, 0xf3b9cac2fc632551, 0) x208, x209 := bits.Sub64(x199, 0xbce6faada7179e84, x207) x210, x211 := bits.Sub64(x201, 0xffffffffffffffff, x209) x212, x213 := bits.Sub64(x203, 0xffffffff00000000, x211) _, x215 := bits.Sub64(x205, 0, x213) mask, _ := bits.Sub64(0, 0, x215) out1[0] = x206&^mask | x197&mask out1[1] = x208&^mask | x199&mask out1[2] = x210&^mask | x201&mask out1[3] = x212&^mask | x203&mask } // p256OrdSqr squares n times a field element in the Montgomery domain. func p256OrdSqr(out1 *p256OrdMontElement, arg1 *p256OrdMontElement, n int) { x1 := arg1[1] x2 := arg1[2] x3 := arg1[3] x4 := arg1[0] for range n { x6, x5 := bits.Mul64(x4, x3) x8, x7 := bits.Mul64(x4, x2) x10, x9 := bits.Mul64(x4, x1) x12, x11 := bits.Mul64(x4, x4) x13, x14 := bits.Add64(x12, x9, 0) x15, x16 := bits.Add64(x10, x7, x14) x17, x18 := bits.Add64(x8, x5, x16) x19 := x18 + x6 _, x20 := bits.Mul64(x11, 0xccd1c8aaee00bc4f) x22, b22 := bits.Sub64(0, x20<<32, 0) x23 := x20 - (x20 >> 32) - b22 x24, b24 := bits.Sub64(0, x20, 0) x25 := x20 - b24 x27, x26 := bits.Mul64(x20, 0xbce6faada7179e84) x29, x28 := bits.Mul64(x20, 0xf3b9cac2fc632551) x30, x31 := bits.Add64(x29, x26, 0) x32, x33 := bits.Add64(x27, x24, x31) x34, x35 := bits.Add64(x25, x22, x33) x36 := x35 + x23 _, x38 := bits.Add64(x11, x28, 0) x39, x40 := bits.Add64(x13, x30, x38) x41, x42 := bits.Add64(x15, x32, x40) x43, x44 := bits.Add64(x17, x34, x42) x45, x46 := bits.Add64(x19, x36, x44) x48, x47 := bits.Mul64(x1, x3) x50, x49 := bits.Mul64(x1, x2) x52, x51 := bits.Mul64(x1, x1) x54, x53 := bits.Mul64(x1, x4) x55, x56 := bits.Add64(x54, x51, 0) x57, x58 := bits.Add64(x52, x49, x56) x59, x60 := bits.Add64(x50, x47, x58) x61 := x60 + x48 x62, x63 := bits.Add64(x39, x53, 0) x64, x65 := bits.Add64(x41, x55, x63) x66, x67 := bits.Add64(x43, x57, x65) x68, x69 := bits.Add64(x45, x59, x67) x70, x71 := bits.Add64(x46, x61, x69) _, x72 := bits.Mul64(x62, 0xccd1c8aaee00bc4f) x74, b74 := bits.Sub64(0, x72<<32, 0) x75 := x72 - (x72 >> 32) - b74 x76, b76 := bits.Sub64(0, x72, 0) x77 := x72 - b76 x79, x78 := bits.Mul64(x72, 0xbce6faada7179e84) x81, x80 := bits.Mul64(x72, 0xf3b9cac2fc632551) x82, x83 := bits.Add64(x81, x78, 0) x84, x85 := bits.Add64(x79, x76, x83) x86, x87 := bits.Add64(x77, x74, x85) x88 := x87 + x75 _, x90 := bits.Add64(x62, x80, 0) x91, x92 := bits.Add64(x64, x82, x90) x93, x94 := bits.Add64(x66, x84, x92) x95, x96 := bits.Add64(x68, x86, x94) x97, x98 := bits.Add64(x70, x88, x96) x99 := x98 + x71 x101, x100 := bits.Mul64(x2, x3) x103, x102 := bits.Mul64(x2, x2) x105, x104 := bits.Mul64(x2, x1) x107, x106 := bits.Mul64(x2, x4) x108, x109 := bits.Add64(x107, x104, 0) x110, x111 := bits.Add64(x105, x102, x109) x112, x113 := bits.Add64(x103, x100, x111) x114 := x113 + x101 x115, x116 := bits.Add64(x91, x106, 0) x117, x118 := bits.Add64(x93, x108, x116) x119, x120 := bits.Add64(x95, x110, x118) x121, x122 := bits.Add64(x97, x112, x120) x123, x124 := bits.Add64(x99, x114, x122) _, x125 := bits.Mul64(x115, 0xccd1c8aaee00bc4f) x127, b127 := bits.Sub64(0, x125<<32, 0) x128 := x125 - (x125 >> 32) - b127 x129, b129 := bits.Sub64(0, x125, 0) x130 := x125 - b129 x132, x131 := bits.Mul64(x125, 0xbce6faada7179e84) x134, x133 := bits.Mul64(x125, 0xf3b9cac2fc632551) x135, x136 := bits.Add64(x134, x131, 0) x137, x138 := bits.Add64(x132, x129, x136) x139, x140 := bits.Add64(x130, x127, x138) x141 := x140 + x128 _, x143 := bits.Add64(x115, x133, 0) x144, x145 := bits.Add64(x117, x135, x143) x146, x147 := bits.Add64(x119, x137, x145) x148, x149 := bits.Add64(x121, x139, x147) x150, x151 := bits.Add64(x123, x141, x149) x152 := x151 + x124 x154, x153 := bits.Mul64(x3, x3) x156, x155 := bits.Mul64(x3, x2) x158, x157 := bits.Mul64(x3, x1) x160, x159 := bits.Mul64(x3, x4) x161, x162 := bits.Add64(x160, x157, 0) x163, x164 := bits.Add64(x158, x155, x162) x165, x166 := bits.Add64(x156, x153, x164) x167 := x166 + x154 x168, x169 := bits.Add64(x144, x159, 0) x170, x171 := bits.Add64(x146, x161, x169) x172, x173 := bits.Add64(x148, x163, x171) x174, x175 := bits.Add64(x150, x165, x173) x176, x177 := bits.Add64(x152, x167, x175) _, x178 := bits.Mul64(x168, 0xccd1c8aaee00bc4f) x180, b180 := bits.Sub64(0, x178<<32, 0) x181 := x178 - (x178 >> 32) - b180 x182, b182 := bits.Sub64(0, x178, 0) x183 := x178 - b182 x185, x184 := bits.Mul64(x178, 0xbce6faada7179e84) x187, x186 := bits.Mul64(x178, 0xf3b9cac2fc632551) x188, x189 := bits.Add64(x187, x184, 0) x190, x191 := bits.Add64(x185, x182, x189) x192, x193 := bits.Add64(x183, x180, x191) x194 := x193 + x181 _, x196 := bits.Add64(x168, x186, 0) x197, x198 := bits.Add64(x170, x188, x196) x199, x200 := bits.Add64(x172, x190, x198) x201, x202 := bits.Add64(x174, x192, x200) x203, x204 := bits.Add64(x176, x194, x202) x205 := x204 + x177 x206, x207 := bits.Sub64(x197, 0xf3b9cac2fc632551, 0) x208, x209 := bits.Sub64(x199, 0xbce6faada7179e84, x207) x210, x211 := bits.Sub64(x201, 0xffffffffffffffff, x209) x212, x213 := bits.Sub64(x203, 0xffffffff00000000, x211) _, x215 := bits.Sub64(x205, 0, x213) mask, _ := bits.Sub64(0, 0, x215) x4 = x206&^mask | x197&mask x1 = x208&^mask | x199&mask x2 = x210&^mask | x201&mask x3 = x212&^mask | x203&mask } out1[0] = x4 out1[1] = x1 out1[2] = x2 out1[3] = x3 } // p256OrdFromMontgomery translates a field element out of the Montgomery domain. func p256OrdFromMontgomery(out1 *p256OrdElement, arg1 *p256OrdMontElement) { x1 := arg1[0] _, x2 := bits.Mul64(x1, 0xccd1c8aaee00bc4f) x5, x4 := bits.Mul64(x2, 0xffffffff00000000) x7, x6 := bits.Mul64(x2, 0xffffffffffffffff) x9, x8 := bits.Mul64(x2, 0xbce6faada7179e84) x11, x10 := bits.Mul64(x2, 0xf3b9cac2fc632551) x12, x13 := bits.Add64(x11, x8, 0) x14, x15 := bits.Add64(x9, x6, x13) x16, x17 := bits.Add64(x7, x4, x15) _, x19 := bits.Add64(x1, x10, 0) x20, x21 := bits.Add64(0, x12, x19) x22, x23 := bits.Add64(0, x14, x21) x24, x25 := bits.Add64(0, x16, x23) x26, x27 := bits.Add64(x20, arg1[1], 0) x28, x29 := bits.Add64(x22, 0, x27) x30, x31 := bits.Add64(x24, 0, x29) _, x32 := bits.Mul64(x26, 0xccd1c8aaee00bc4f) x35, x34 := bits.Mul64(x32, 0xffffffff00000000) x37, x36 := bits.Mul64(x32, 0xffffffffffffffff) x39, x38 := bits.Mul64(x32, 0xbce6faada7179e84) x41, x40 := bits.Mul64(x32, 0xf3b9cac2fc632551) x42, x43 := bits.Add64(x41, x38, 0) x44, x45 := bits.Add64(x39, x36, x43) x46, x47 := bits.Add64(x37, x34, x45) _, x49 := bits.Add64(x26, x40, 0) x50, x51 := bits.Add64(x28, x42, x49) x52, x53 := bits.Add64(x30, x44, x51) x54, x55 := bits.Add64(x31+(x25+(x17+x5)), x46, x53) x56, x57 := bits.Add64(x50, arg1[2], 0) x58, x59 := bits.Add64(x52, 0, x57) x60, x61 := bits.Add64(x54, 0, x59) _, x62 := bits.Mul64(x56, 0xccd1c8aaee00bc4f) x65, x64 := bits.Mul64(x62, 0xffffffff00000000) x67, x66 := bits.Mul64(x62, 0xffffffffffffffff) x69, x68 := bits.Mul64(x62, 0xbce6faada7179e84) x71, x70 := bits.Mul64(x62, 0xf3b9cac2fc632551) x72, x73 := bits.Add64(x71, x68, 0) x74, x75 := bits.Add64(x69, x66, x73) x76, x77 := bits.Add64(x67, x64, x75) _, x79 := bits.Add64(x56, x70, 0) x80, x81 := bits.Add64(x58, x72, x79) x82, x83 := bits.Add64(x60, x74, x81) x84, x85 := bits.Add64(x61+(x55+(x47+x35)), x76, x83) x86, x87 := bits.Add64(x80, arg1[3], 0) x88, x89 := bits.Add64(x82, 0, x87) x90, x91 := bits.Add64(x84, 0, x89) _, x92 := bits.Mul64(x86, 0xccd1c8aaee00bc4f) x95, x94 := bits.Mul64(x92, 0xffffffff00000000) x97, x96 := bits.Mul64(x92, 0xffffffffffffffff) x99, x98 := bits.Mul64(x92, 0xbce6faada7179e84) x101, x100 := bits.Mul64(x92, 0xf3b9cac2fc632551) x102, x103 := bits.Add64(x101, x98, 0) x104, x105 := bits.Add64(x99, x96, x103) x106, x107 := bits.Add64(x97, x94, x105) _, x109 := bits.Add64(x86, x100, 0) x110, x111 := bits.Add64(x88, x102, x109) x112, x113 := bits.Add64(x90, x104, x111) x114, x115 := bits.Add64(x91+(x85+(x77+x65)), x106, x113) x116 := x115 + (x107 + x95) x117, x118 := bits.Sub64(x110, 0xf3b9cac2fc632551, 0) x119, x120 := bits.Sub64(x112, 0xbce6faada7179e84, x118) x121, x122 := bits.Sub64(x114, 0xffffffffffffffff, x120) x123, x124 := bits.Sub64(x116, 0xffffffff00000000, x122) mask, _ := bits.Sub64(0, 0, x124) out1[0] = x117&^mask | x110&mask out1[1] = x119&^mask | x112&mask out1[2] = x121&^mask | x114&mask out1[3] = x123&^mask | x116&mask } // p256OrdToMontgomery translates a field element into the Montgomery domain. func p256OrdToMontgomery(out1 *p256OrdMontElement, arg1 *p256OrdElement) { x1 := arg1[1] x2 := arg1[2] x3 := arg1[3] x4 := arg1[0] x6, x5 := bits.Mul64(x4, 0x66e12d94f3d95620) x8, x7 := bits.Mul64(x4, 0x2845b2392b6bec59) x10, x9 := bits.Mul64(x4, 0x4699799c49bd6fa6) x12, x11 := bits.Mul64(x4, 0x83244c95be79eea2) x13, x14 := bits.Add64(x12, x9, 0) x15, x16 := bits.Add64(x10, x7, x14) x17, x18 := bits.Add64(x8, x5, x16) _, x19 := bits.Mul64(x11, 0xccd1c8aaee00bc4f) x22, x21 := bits.Mul64(x19, 0xffffffff00000000) x24, x23 := bits.Mul64(x19, 0xffffffffffffffff) x26, x25 := bits.Mul64(x19, 0xbce6faada7179e84) x28, x27 := bits.Mul64(x19, 0xf3b9cac2fc632551) x29, x30 := bits.Add64(x28, x25, 0) x31, x32 := bits.Add64(x26, x23, x30) x33, x34 := bits.Add64(x24, x21, x32) _, x36 := bits.Add64(x11, x27, 0) x37, x38 := bits.Add64(x13, x29, x36) x39, x40 := bits.Add64(x15, x31, x38) x41, x42 := bits.Add64(x17, x33, x40) x43, x44 := bits.Add64(x18+x6, x34+x22, x42) x46, x45 := bits.Mul64(x1, 0x66e12d94f3d95620) x48, x47 := bits.Mul64(x1, 0x2845b2392b6bec59) x50, x49 := bits.Mul64(x1, 0x4699799c49bd6fa6) x52, x51 := bits.Mul64(x1, 0x83244c95be79eea2) x53, x54 := bits.Add64(x52, x49, 0) x55, x56 := bits.Add64(x50, x47, x54) x57, x58 := bits.Add64(x48, x45, x56) x59, x60 := bits.Add64(x37, x51, 0) x61, x62 := bits.Add64(x39, x53, x60) x63, x64 := bits.Add64(x41, x55, x62) x65, x66 := bits.Add64(x43, x57, x64) _, x67 := bits.Mul64(x59, 0xccd1c8aaee00bc4f) x70, x69 := bits.Mul64(x67, 0xffffffff00000000) x72, x71 := bits.Mul64(x67, 0xffffffffffffffff) x74, x73 := bits.Mul64(x67, 0xbce6faada7179e84) x76, x75 := bits.Mul64(x67, 0xf3b9cac2fc632551) x77, x78 := bits.Add64(x76, x73, 0) x79, x80 := bits.Add64(x74, x71, x78) x81, x82 := bits.Add64(x72, x69, x80) _, x84 := bits.Add64(x59, x75, 0) x85, x86 := bits.Add64(x61, x77, x84) x87, x88 := bits.Add64(x63, x79, x86) x89, x90 := bits.Add64(x65, x81, x88) x91, x92 := bits.Add64(x66+x44+(x58+x46), x82+x70, x90) x94, x93 := bits.Mul64(x2, 0x66e12d94f3d95620) x96, x95 := bits.Mul64(x2, 0x2845b2392b6bec59) x98, x97 := bits.Mul64(x2, 0x4699799c49bd6fa6) x100, x99 := bits.Mul64(x2, 0x83244c95be79eea2) x101, x102 := bits.Add64(x100, x97, 0) x103, x104 := bits.Add64(x98, x95, x102) x105, x106 := bits.Add64(x96, x93, x104) x107, x108 := bits.Add64(x85, x99, 0) x109, x110 := bits.Add64(x87, x101, x108) x111, x112 := bits.Add64(x89, x103, x110) x113, x114 := bits.Add64(x91, x105, x112) _, x115 := bits.Mul64(x107, 0xccd1c8aaee00bc4f) x118, x117 := bits.Mul64(x115, 0xffffffff00000000) x120, x119 := bits.Mul64(x115, 0xffffffffffffffff) x122, x121 := bits.Mul64(x115, 0xbce6faada7179e84) x124, x123 := bits.Mul64(x115, 0xf3b9cac2fc632551) x125, x126 := bits.Add64(x124, x121, 0) x127, x128 := bits.Add64(x122, x119, x126) x129, x130 := bits.Add64(x120, x117, x128) _, x132 := bits.Add64(x107, x123, 0) x133, x134 := bits.Add64(x109, x125, x132) x135, x136 := bits.Add64(x111, x127, x134) x137, x138 := bits.Add64(x113, x129, x136) x139, x140 := bits.Add64(x114+x92+(x106+x94), x130+x118, x138) x142, x141 := bits.Mul64(x3, 0x66e12d94f3d95620) x144, x143 := bits.Mul64(x3, 0x2845b2392b6bec59) x146, x145 := bits.Mul64(x3, 0x4699799c49bd6fa6) x148, x147 := bits.Mul64(x3, 0x83244c95be79eea2) x149, x150 := bits.Add64(x148, x145, 0) x151, x152 := bits.Add64(x146, x143, x150) x153, x154 := bits.Add64(x144, x141, x152) x155, x156 := bits.Add64(x133, x147, 0) x157, x158 := bits.Add64(x135, x149, x156) x159, x160 := bits.Add64(x137, x151, x158) x161, x162 := bits.Add64(x139, x153, x160) _, x163 := bits.Mul64(x155, 0xccd1c8aaee00bc4f) x166, x165 := bits.Mul64(x163, 0xffffffff00000000) x168, x167 := bits.Mul64(x163, 0xffffffffffffffff) x170, x169 := bits.Mul64(x163, 0xbce6faada7179e84) x172, x171 := bits.Mul64(x163, 0xf3b9cac2fc632551) x173, x174 := bits.Add64(x172, x169, 0) x175, x176 := bits.Add64(x170, x167, x174) x177, x178 := bits.Add64(x168, x165, x176) _, x180 := bits.Add64(x155, x171, 0) x181, x182 := bits.Add64(x157, x173, x180) x183, x184 := bits.Add64(x159, x175, x182) x185, x186 := bits.Add64(x161, x177, x184) x187, x188 := bits.Add64(x162+x140+(x154+x142), x178+x166, x186) x189, x190 := bits.Sub64(x181, 0xf3b9cac2fc632551, 0) x191, x192 := bits.Sub64(x183, 0xbce6faada7179e84, x190) x193, x194 := bits.Sub64(x185, 0xffffffffffffffff, x192) x195, x196 := bits.Sub64(x187, 0xffffffff00000000, x194) _, x198 := bits.Sub64(x188, 0, x196) mask, _ := bits.Sub64(0, 0, x198) out1[0] = x189&^mask | x181&mask out1[1] = x191&^mask | x183&mask out1[2] = x193&^mask | x185&mask out1[3] = x195&^mask | x187&mask }