// 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.//go:build (amd64 || arm64) && !puregopackage nistecimport// Montgomery multiplication modulo org(G). Sets res = in1 * in2 * R⁻¹.////go:noescapefunc p256OrdMul(, , *p256OrdElement)// Montgomery square modulo org(G), repeated n times (n >= 1).////go:noescapefunc p256OrdSqr(, *p256OrdElement, int)func ( []byte) ([]byte, error) {iflen() != 32 {returnnil, errors.New("invalid scalar length") } := new(p256OrdElement)p256OrdBigToLittle(, (*[32]byte)())p256OrdReduce()// 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 := new(p256OrdElement) := new(p256OrdElement) := new(p256OrdElement) := new(p256OrdElement) := new(p256OrdElement) := new(p256OrdElement) := new(p256OrdElement) := new(p256OrdElement)// This code operates in the Montgomery domain where R = 2²⁵⁶ mod n and n is // the order of the scalar field. Elements in the Montgomery domain take the // form a×R and p256OrdMul calculates (a × b × R⁻¹) mod n. RR is R in the // domain, or R×R mod n, thus p256OrdMul(x, RR) gives x×R, i.e. converts x // into the Montgomery domain. := &p256OrdElement{0x83244c95be79eea2, 0x4699799c49bd6fa6,0x2845b2392b6bec59, 0x66e12d94f3d95620}p256OrdMul(, , ) // _1p256OrdSqr(, , 1) // _10p256OrdMul(, , ) // _11p256OrdMul(, , ) // _101p256OrdMul(, , ) // _111p256OrdSqr(, , 1) // _1010p256OrdMul(, , ) // _1111p256OrdSqr(, , 1) // _10100p256OrdMul(, , ) // _10101p256OrdSqr(, , 1) // _101010p256OrdMul(, , ) // _101111p256OrdMul(, , ) // _111111 = x6p256OrdSqr(, , 2) // _11111100p256OrdMul(, , ) // _11111111 = x8p256OrdSqr(, , 8) // _ff00p256OrdMul(, , ) // _ffff = x16p256OrdSqr(, , 16) // _ffff0000p256OrdMul(, , ) // _ffffffff = x32p256OrdSqr(, , 64)p256OrdMul(, , )p256OrdSqr(, , 32)p256OrdMul(, , ) := []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} := []*p256OrdElement{ , , , , , , , , , , , , , , , , , , , , , , , , , }for , := range {p256OrdSqr(, , )p256OrdMul(, , []) }// Montgomery multiplication by R⁻¹, or 1 outside the domain as R⁻¹×R = 1, // converts a Montgomery value out of the domain. := &p256OrdElement{1}p256OrdMul(, , )var [32]bytep256OrdLittleToBig(&, )return [:], nil}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.