...

Source file src/golang.org/x/crypto/curve25519/curve25519_compat.go

Documentation: golang.org/x/crypto/curve25519

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !go1.20
     6  
     7  package curve25519
     8  
     9  import (
    10  	"crypto/subtle"
    11  	"errors"
    12  	"strconv"
    13  
    14  	"golang.org/x/crypto/curve25519/internal/field"
    15  )
    16  
    17  func scalarMult(dst, scalar, point *[32]byte) {
    18  	var e [32]byte
    19  
    20  	copy(e[:], scalar[:])
    21  	e[0] &= 248
    22  	e[31] &= 127
    23  	e[31] |= 64
    24  
    25  	var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
    26  	x1.SetBytes(point[:])
    27  	x2.One()
    28  	x3.Set(&x1)
    29  	z3.One()
    30  
    31  	swap := 0
    32  	for pos := 254; pos >= 0; pos-- {
    33  		b := e[pos/8] >> uint(pos&7)
    34  		b &= 1
    35  		swap ^= int(b)
    36  		x2.Swap(&x3, swap)
    37  		z2.Swap(&z3, swap)
    38  		swap = int(b)
    39  
    40  		tmp0.Subtract(&x3, &z3)
    41  		tmp1.Subtract(&x2, &z2)
    42  		x2.Add(&x2, &z2)
    43  		z2.Add(&x3, &z3)
    44  		z3.Multiply(&tmp0, &x2)
    45  		z2.Multiply(&z2, &tmp1)
    46  		tmp0.Square(&tmp1)
    47  		tmp1.Square(&x2)
    48  		x3.Add(&z3, &z2)
    49  		z2.Subtract(&z3, &z2)
    50  		x2.Multiply(&tmp1, &tmp0)
    51  		tmp1.Subtract(&tmp1, &tmp0)
    52  		z2.Square(&z2)
    53  
    54  		z3.Mult32(&tmp1, 121666)
    55  		x3.Square(&x3)
    56  		tmp0.Add(&tmp0, &z3)
    57  		z3.Multiply(&x1, &z2)
    58  		z2.Multiply(&tmp1, &tmp0)
    59  	}
    60  
    61  	x2.Swap(&x3, swap)
    62  	z2.Swap(&z3, swap)
    63  
    64  	z2.Invert(&z2)
    65  	x2.Multiply(&x2, &z2)
    66  	copy(dst[:], x2.Bytes())
    67  }
    68  
    69  func scalarBaseMult(dst, scalar *[32]byte) {
    70  	checkBasepoint()
    71  	scalarMult(dst, scalar, &basePoint)
    72  }
    73  
    74  func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
    75  	var in [32]byte
    76  	if l := len(scalar); l != 32 {
    77  		return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
    78  	}
    79  	if l := len(point); l != 32 {
    80  		return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
    81  	}
    82  	copy(in[:], scalar)
    83  	if &point[0] == &Basepoint[0] {
    84  		scalarBaseMult(dst, &in)
    85  	} else {
    86  		var base, zero [32]byte
    87  		copy(base[:], point)
    88  		scalarMult(dst, &in, &base)
    89  		if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
    90  			return nil, errors.New("bad input point: low order point")
    91  		}
    92  	}
    93  	return dst[:], nil
    94  }
    95  
    96  func checkBasepoint() {
    97  	if subtle.ConstantTimeCompare(Basepoint, []byte{
    98  		0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    99  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   100  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   101  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   102  	}) != 1 {
   103  		panic("curve25519: global Basepoint value was modified")
   104  	}
   105  }
   106  

View as plain text