// Copyright (c) 2019 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 edwards25519import ()// A dynamic lookup table for variable-base, constant-time scalar muls.type projLookupTable struct { points [8]projCached}// A precomputed lookup table for fixed-base, constant-time scalar muls.type affineLookupTable struct { points [8]affineCached}// A dynamic lookup table for variable-base, variable-time scalar muls.type nafLookupTable5 struct { points [8]projCached}// A precomputed lookup table for fixed-base, variable-time scalar muls.type nafLookupTable8 struct { points [64]affineCached}// Constructors.// Builds a lookup table at runtime. Fast.func ( *projLookupTable) ( *Point) {// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q // This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q .points[0].FromP3() := Point{} := projP1xP1{}for := 0; < 7; ++ {// Compute (i+1)*Q as Q + i*Q and convert to a projCached // This is needlessly complicated because the API has explicit // receivers instead of creating stack objects and relying on RVO .points[+1].FromP3(.fromP1xP1(.Add(, &.points[]))) }}// This is not optimised for speed; fixed-base tables should be precomputed.func ( *affineLookupTable) ( *Point) {// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q // This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q .points[0].FromP3() := Point{} := projP1xP1{}for := 0; < 7; ++ {// Compute (i+1)*Q as Q + i*Q and convert to affineCached .points[+1].FromP3(.fromP1xP1(.AddAffine(, &.points[]))) }}// Builds a lookup table at runtime. Fast.func ( *nafLookupTable5) ( *Point) {// Goal: v.points[i] = (2*i+1)*Q, i.e., Q, 3Q, 5Q, ..., 15Q // This allows lookup of -15Q, ..., -3Q, -Q, 0, Q, 3Q, ..., 15Q .points[0].FromP3() := Point{} .Add(, ) := Point{} := projP1xP1{}for := 0; < 7; ++ { .points[+1].FromP3(.fromP1xP1(.Add(&, &.points[]))) }}// This is not optimised for speed; fixed-base tables should be precomputed.func ( *nafLookupTable8) ( *Point) { .points[0].FromP3() := Point{} .Add(, ) := Point{} := projP1xP1{}for := 0; < 63; ++ { .points[+1].FromP3(.fromP1xP1(.AddAffine(&, &.points[]))) }}// Selectors.// Set dest to x*Q, where -8 <= x <= 8, in constant time.func ( *projLookupTable) ( *projCached, int8) {// Compute xabs = |x| := >> 7 := uint8(( + ) ^ ) .Zero()for := 1; <= 8; ++ {// Set dest = j*Q if |x| = j := subtle.ConstantTimeByteEq(, uint8()) .Select(&.points[-1], , ) }// Now dest = |x|*Q, conditionally negate to get x*Q .CondNeg(int( & 1))}// Set dest to x*Q, where -8 <= x <= 8, in constant time.func ( *affineLookupTable) ( *affineCached, int8) {// Compute xabs = |x| := >> 7 := uint8(( + ) ^ ) .Zero()for := 1; <= 8; ++ {// Set dest = j*Q if |x| = j := subtle.ConstantTimeByteEq(, uint8()) .Select(&.points[-1], , ) }// Now dest = |x|*Q, conditionally negate to get x*Q .CondNeg(int( & 1))}// Given odd x with 0 < x < 2^4, return x*Q (in variable time).func ( *nafLookupTable5) ( *projCached, int8) { * = .points[/2]}// Given odd x with 0 < x < 2^7, return x*Q (in variable time).func ( *nafLookupTable8) ( *affineCached, int8) { * = .points[/2]}
The pages are generated with Goldsv0.7.3-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.