curve25519_compat.go (2321B)
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 }