-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
curve25519: use crypto/ecdh on Go 1.20
For golang/go#52221 Change-Id: I27e867d4cc89cd52c8d510f0dbab4e89b7cd4763 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/451115 Auto-Submit: Filippo Valsorda <[email protected]> Reviewed-by: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Filippo Valsorda <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]>
- Loading branch information
1 parent
c6a20f9
commit 9cd0187
Showing
5 changed files
with
173 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// Copyright 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. | ||
|
||
//go:build !go1.20 | ||
|
||
package curve25519 | ||
|
||
import ( | ||
"crypto/subtle" | ||
"errors" | ||
"strconv" | ||
|
||
"golang.org/x/crypto/curve25519/internal/field" | ||
) | ||
|
||
func scalarMult(dst, scalar, point *[32]byte) { | ||
var e [32]byte | ||
|
||
copy(e[:], scalar[:]) | ||
e[0] &= 248 | ||
e[31] &= 127 | ||
e[31] |= 64 | ||
|
||
var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element | ||
x1.SetBytes(point[:]) | ||
x2.One() | ||
x3.Set(&x1) | ||
z3.One() | ||
|
||
swap := 0 | ||
for pos := 254; pos >= 0; pos-- { | ||
b := e[pos/8] >> uint(pos&7) | ||
b &= 1 | ||
swap ^= int(b) | ||
x2.Swap(&x3, swap) | ||
z2.Swap(&z3, swap) | ||
swap = int(b) | ||
|
||
tmp0.Subtract(&x3, &z3) | ||
tmp1.Subtract(&x2, &z2) | ||
x2.Add(&x2, &z2) | ||
z2.Add(&x3, &z3) | ||
z3.Multiply(&tmp0, &x2) | ||
z2.Multiply(&z2, &tmp1) | ||
tmp0.Square(&tmp1) | ||
tmp1.Square(&x2) | ||
x3.Add(&z3, &z2) | ||
z2.Subtract(&z3, &z2) | ||
x2.Multiply(&tmp1, &tmp0) | ||
tmp1.Subtract(&tmp1, &tmp0) | ||
z2.Square(&z2) | ||
|
||
z3.Mult32(&tmp1, 121666) | ||
x3.Square(&x3) | ||
tmp0.Add(&tmp0, &z3) | ||
z3.Multiply(&x1, &z2) | ||
z2.Multiply(&tmp1, &tmp0) | ||
} | ||
|
||
x2.Swap(&x3, swap) | ||
z2.Swap(&z3, swap) | ||
|
||
z2.Invert(&z2) | ||
x2.Multiply(&x2, &z2) | ||
copy(dst[:], x2.Bytes()) | ||
} | ||
|
||
func scalarBaseMult(dst, scalar *[32]byte) { | ||
checkBasepoint() | ||
scalarMult(dst, scalar, &basePoint) | ||
} | ||
|
||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { | ||
var in [32]byte | ||
if l := len(scalar); l != 32 { | ||
return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32") | ||
} | ||
if l := len(point); l != 32 { | ||
return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32") | ||
} | ||
copy(in[:], scalar) | ||
if &point[0] == &Basepoint[0] { | ||
scalarBaseMult(dst, &in) | ||
} else { | ||
var base, zero [32]byte | ||
copy(base[:], point) | ||
scalarMult(dst, &in, &base) | ||
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 { | ||
return nil, errors.New("bad input point: low order point") | ||
} | ||
} | ||
return dst[:], nil | ||
} | ||
|
||
func checkBasepoint() { | ||
if subtle.ConstantTimeCompare(Basepoint, []byte{ | ||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
}) != 1 { | ||
panic("curve25519: global Basepoint value was modified") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// 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 go1.20 | ||
|
||
package curve25519 | ||
|
||
import "crypto/ecdh" | ||
|
||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) { | ||
curve := ecdh.X25519() | ||
pub, err := curve.NewPublicKey(point) | ||
if err != nil { | ||
return nil, err | ||
} | ||
priv, err := curve.NewPrivateKey(scalar) | ||
if err != nil { | ||
return nil, err | ||
} | ||
out, err := priv.ECDH(pub) | ||
if err != nil { | ||
return nil, err | ||
} | ||
copy(dst[:], out) | ||
return dst[:], nil | ||
} | ||
|
||
func scalarMult(dst, scalar, point *[32]byte) { | ||
if _, err := x25519(dst, scalar[:], point[:]); err != nil { | ||
// The only error condition for x25519 when the inputs are 32 bytes long | ||
// is if the output would have been the all-zero value. | ||
for i := range dst { | ||
dst[i] = 0 | ||
} | ||
} | ||
} | ||
|
||
func scalarBaseMult(dst, scalar *[32]byte) { | ||
curve := ecdh.X25519() | ||
priv, err := curve.NewPrivateKey(scalar[:]) | ||
if err != nil { | ||
panic("curve25519: internal error: scalarBaseMult was not 32 bytes") | ||
} | ||
copy(dst[:], priv.PublicKey().Bytes()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.