podman
105 строк · 2.3 Кб
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
7package curve255198
9import (10"crypto/subtle"11"errors"12"strconv"13
14"golang.org/x/crypto/curve25519/internal/field"15)
16
17func scalarMult(dst, scalar, point *[32]byte) {18var e [32]byte19
20copy(e[:], scalar[:])21e[0] &= 24822e[31] &= 12723e[31] |= 6424
25var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element26x1.SetBytes(point[:])27x2.One()28x3.Set(&x1)29z3.One()30
31swap := 032for pos := 254; pos >= 0; pos-- {33b := e[pos/8] >> uint(pos&7)34b &= 135swap ^= int(b)36x2.Swap(&x3, swap)37z2.Swap(&z3, swap)38swap = int(b)39
40tmp0.Subtract(&x3, &z3)41tmp1.Subtract(&x2, &z2)42x2.Add(&x2, &z2)43z2.Add(&x3, &z3)44z3.Multiply(&tmp0, &x2)45z2.Multiply(&z2, &tmp1)46tmp0.Square(&tmp1)47tmp1.Square(&x2)48x3.Add(&z3, &z2)49z2.Subtract(&z3, &z2)50x2.Multiply(&tmp1, &tmp0)51tmp1.Subtract(&tmp1, &tmp0)52z2.Square(&z2)53
54z3.Mult32(&tmp1, 121666)55x3.Square(&x3)56tmp0.Add(&tmp0, &z3)57z3.Multiply(&x1, &z2)58z2.Multiply(&tmp1, &tmp0)59}60
61x2.Swap(&x3, swap)62z2.Swap(&z3, swap)63
64z2.Invert(&z2)65x2.Multiply(&x2, &z2)66copy(dst[:], x2.Bytes())67}
68
69func scalarBaseMult(dst, scalar *[32]byte) {70checkBasepoint()71scalarMult(dst, scalar, &basePoint)72}
73
74func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {75var in [32]byte76if l := len(scalar); l != 32 {77return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")78}79if l := len(point); l != 32 {80return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")81}82copy(in[:], scalar)83if &point[0] == &Basepoint[0] {84scalarBaseMult(dst, &in)85} else {86var base, zero [32]byte87copy(base[:], point)88scalarMult(dst, &in, &base)89if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {90return nil, errors.New("bad input point: low order point")91}92}93return dst[:], nil94}
95
96func checkBasepoint() {97if subtle.ConstantTimeCompare(Basepoint, []byte{980x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,1010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,102}) != 1 {103panic("curve25519: global Basepoint value was modified")104}105}
106