mirror of https://github.com/golang/go.git
crypto/internal/edwards25519: move to crypto/internal/fips/edwards25519
Left most of the tests in for now as they are almost all internal and hard to externalize. String initialization in the FIPS module has some issues, so switched field.TestSqrtRatio to storing decoded byte slices instead. For #69536 Change-Id: If9e4a2bb780a37a8d102a22ffd13c5293d11a8a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/628776 Reviewed-by: Russ Cox <rsc@golang.org> TryBot-Bypass: Filippo Valsorda <filippo@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
parent
7e1af3bf74
commit
7eb10ca691
|
|
@ -6,7 +6,7 @@ package ecdh
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/internal/edwards25519/field"
|
||||
"crypto/internal/fips/edwards25519/field"
|
||||
"crypto/internal/randutil"
|
||||
"errors"
|
||||
"io"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package ed25519
|
|||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/internal/edwards25519"
|
||||
"crypto/internal/fips/edwards25519"
|
||||
cryptorand "crypto/rand"
|
||||
"crypto/sha512"
|
||||
"crypto/subtle"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
package edwards25519
|
||||
|
||||
import (
|
||||
"crypto/internal/edwards25519/field"
|
||||
"crypto/internal/fips/edwards25519/field"
|
||||
"errors"
|
||||
)
|
||||
|
||||
|
|
@ -5,8 +5,7 @@
|
|||
package edwards25519
|
||||
|
||||
import (
|
||||
"crypto/internal/cryptotest"
|
||||
"crypto/internal/edwards25519/field"
|
||||
"crypto/internal/fips/edwards25519/field"
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
|
@ -277,21 +276,6 @@ func TestNonCanonicalPoints(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
var testAllocationsSink byte
|
||||
|
||||
func TestAllocations(t *testing.T) {
|
||||
cryptotest.SkipTestAllocations(t)
|
||||
if allocs := testing.AllocsPerRun(100, func() {
|
||||
p := NewIdentityPoint()
|
||||
p.Add(p, NewGeneratorPoint())
|
||||
s := NewScalar()
|
||||
testAllocationsSink ^= s.Bytes()[0]
|
||||
testAllocationsSink ^= p.Bytes()[0]
|
||||
}); allocs > 0 {
|
||||
t.Errorf("expected zero allocations, got %0.1v", allocs)
|
||||
}
|
||||
}
|
||||
|
||||
func decodeHex(s string) []byte {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
|
|
@ -16,7 +16,7 @@ import (
|
|||
//go:generate go run . -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field
|
||||
|
||||
func main() {
|
||||
Package("crypto/internal/edwards25519/field")
|
||||
Package("crypto/internal/fips/edwards25519/field")
|
||||
ConstraintExpr("!purego")
|
||||
feMul()
|
||||
feSquare()
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
module std/crypto/internal/edwards25519/field/_asm
|
||||
module std/crypto/internal/fips/edwards25519/field/_asm
|
||||
|
||||
go 1.19
|
||||
|
||||
|
|
@ -6,9 +6,9 @@
|
|||
package field
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"crypto/internal/fips/subtle"
|
||||
"crypto/internal/fipsdeps/byteorder"
|
||||
"errors"
|
||||
"internal/byteorder"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
|
|
@ -201,20 +201,20 @@ func (v *Element) SetBytes(x []byte) (*Element, error) {
|
|||
}
|
||||
|
||||
// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
|
||||
v.l0 = byteorder.LeUint64(x[0:8])
|
||||
v.l0 = byteorder.LEUint64(x[0:8])
|
||||
v.l0 &= maskLow51Bits
|
||||
// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
|
||||
v.l1 = byteorder.LeUint64(x[6:14]) >> 3
|
||||
v.l1 = byteorder.LEUint64(x[6:14]) >> 3
|
||||
v.l1 &= maskLow51Bits
|
||||
// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
|
||||
v.l2 = byteorder.LeUint64(x[12:20]) >> 6
|
||||
v.l2 = byteorder.LEUint64(x[12:20]) >> 6
|
||||
v.l2 &= maskLow51Bits
|
||||
// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
|
||||
v.l3 = byteorder.LeUint64(x[19:27]) >> 1
|
||||
v.l3 = byteorder.LEUint64(x[19:27]) >> 1
|
||||
v.l3 &= maskLow51Bits
|
||||
// Bits 204:255 (bytes 24:32, bits 192:256, shift 12, mask 51).
|
||||
// Note: not bytes 25:33, shift 4, to avoid overread.
|
||||
v.l4 = byteorder.LeUint64(x[24:32]) >> 12
|
||||
v.l4 = byteorder.LEUint64(x[24:32]) >> 12
|
||||
v.l4 &= maskLow51Bits
|
||||
|
||||
return v, nil
|
||||
|
|
@ -235,7 +235,7 @@ func (v *Element) bytes(out *[32]byte) []byte {
|
|||
var buf [8]byte
|
||||
for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
|
||||
bitsOffset := i * 51
|
||||
byteorder.LePutUint64(buf[:], l<<uint(bitsOffset%8))
|
||||
byteorder.LEPutUint64(buf[:], l<<uint(bitsOffset%8))
|
||||
for i, bb := range buf {
|
||||
off := bitsOffset/8 + i
|
||||
if off >= len(out) {
|
||||
|
|
@ -433,55 +433,55 @@ func TestMult32(t *testing.T) {
|
|||
func TestSqrtRatio(t *testing.T) {
|
||||
// From draft-irtf-cfrg-ristretto255-decaf448-00, Appendix A.4.
|
||||
type test struct {
|
||||
u, v string
|
||||
u, v []byte
|
||||
wasSquare int
|
||||
r string
|
||||
r []byte
|
||||
}
|
||||
var tests = []test{
|
||||
// If u is 0, the function is defined to return (0, TRUE), even if v
|
||||
// is zero. Note that where used in this package, the denominator v
|
||||
// is never zero.
|
||||
{
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
1, "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
1, decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
},
|
||||
// 0/1 == 0²
|
||||
{
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
1, "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
decodeHex("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||
1, decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
},
|
||||
// If u is non-zero and v is zero, defined to return (0, FALSE).
|
||||
{
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
0, "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
decodeHex("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||
decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
0, decodeHex("0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
},
|
||||
// 2/1 is not square in this field.
|
||||
{
|
||||
"0200000000000000000000000000000000000000000000000000000000000000",
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
0, "3c5ff1b5d8e4113b871bd052f9e7bcd0582804c266ffb2d4f4203eb07fdb7c54",
|
||||
decodeHex("0200000000000000000000000000000000000000000000000000000000000000"),
|
||||
decodeHex("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||
0, decodeHex("3c5ff1b5d8e4113b871bd052f9e7bcd0582804c266ffb2d4f4203eb07fdb7c54"),
|
||||
},
|
||||
// 4/1 == 2²
|
||||
{
|
||||
"0400000000000000000000000000000000000000000000000000000000000000",
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
1, "0200000000000000000000000000000000000000000000000000000000000000",
|
||||
decodeHex("0400000000000000000000000000000000000000000000000000000000000000"),
|
||||
decodeHex("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||
1, decodeHex("0200000000000000000000000000000000000000000000000000000000000000"),
|
||||
},
|
||||
// 1/4 == (2⁻¹)² == (2^(p-2))² per Euler's theorem
|
||||
{
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"0400000000000000000000000000000000000000000000000000000000000000",
|
||||
1, "f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f",
|
||||
decodeHex("0100000000000000000000000000000000000000000000000000000000000000"),
|
||||
decodeHex("0400000000000000000000000000000000000000000000000000000000000000"),
|
||||
1, decodeHex("f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f"),
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
u, _ := new(Element).SetBytes(decodeHex(tt.u))
|
||||
v, _ := new(Element).SetBytes(decodeHex(tt.v))
|
||||
want, _ := new(Element).SetBytes(decodeHex(tt.r))
|
||||
u, _ := new(Element).SetBytes(tt.u)
|
||||
v, _ := new(Element).SetBytes(tt.v)
|
||||
want, _ := new(Element).SetBytes(tt.r)
|
||||
got, wasSquare := new(Element).SqrtRatio(u, v)
|
||||
if got.Equal(want) == 0 || wasSquare != tt.wasSquare {
|
||||
t.Errorf("%d: got (%v, %v), want (%v, %v)", i, got, wasSquare, want, tt.wasSquare)
|
||||
|
|
@ -5,8 +5,8 @@
|
|||
package edwards25519
|
||||
|
||||
import (
|
||||
"crypto/internal/fipsdeps/byteorder"
|
||||
"errors"
|
||||
"internal/byteorder"
|
||||
)
|
||||
|
||||
// A Scalar is an integer modulo
|
||||
|
|
@ -271,7 +271,7 @@ func (s *Scalar) nonAdjacentForm(w uint) [256]int8 {
|
|||
var digits [5]uint64
|
||||
|
||||
for i := 0; i < 4; i++ {
|
||||
digits[i] = byteorder.LeUint64(b[i*8:])
|
||||
digits[i] = byteorder.LEUint64(b[i*8:])
|
||||
}
|
||||
|
||||
width := uint64(1 << w)
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
package edwards25519
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"crypto/internal/fips/subtle"
|
||||
)
|
||||
|
||||
// A dynamic lookup table for variable-base, constant-time scalar muls.
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2024 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 fipstest
|
||||
|
||||
import (
|
||||
"crypto/internal/cryptotest"
|
||||
. "crypto/internal/fips/edwards25519"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testAllocationsSink byte
|
||||
|
||||
func TestEdwards25519Allocations(t *testing.T) {
|
||||
cryptotest.SkipTestAllocations(t)
|
||||
if allocs := testing.AllocsPerRun(100, func() {
|
||||
p := NewIdentityPoint()
|
||||
p.Add(p, NewGeneratorPoint())
|
||||
s := NewScalar()
|
||||
testAllocationsSink ^= s.Bytes()[0]
|
||||
testAllocationsSink ^= p.Bytes()[0]
|
||||
}); allocs > 0 {
|
||||
t.Errorf("expected zero allocations, got %0.1v", allocs)
|
||||
}
|
||||
}
|
||||
|
|
@ -480,6 +480,8 @@ var depsRules = `
|
|||
< crypto/internal/fips/nistec
|
||||
< crypto/internal/fips/ecdh
|
||||
< crypto/internal/fips/ecdsa
|
||||
< crypto/internal/fips/edwards25519/field
|
||||
< crypto/internal/fips/edwards25519
|
||||
< FIPS;
|
||||
|
||||
FIPS < crypto/internal/fips/check/checktest;
|
||||
|
|
@ -503,16 +505,11 @@ var depsRules = `
|
|||
< crypto/internal/boring
|
||||
< crypto/boring;
|
||||
|
||||
crypto/internal/fips/alias,
|
||||
crypto/subtle, embed
|
||||
< crypto/internal/edwards25519/field
|
||||
< crypto/internal/edwards25519;
|
||||
|
||||
crypto/boring
|
||||
< crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
|
||||
crypto/sha1, crypto/sha256, crypto/sha512;
|
||||
|
||||
crypto/boring, crypto/internal/edwards25519/field
|
||||
crypto/boring, crypto/internal/fips/edwards25519/field
|
||||
< crypto/ecdh;
|
||||
|
||||
# Unfortunately, stuck with reflect via encoding/binary.
|
||||
|
|
@ -522,7 +519,6 @@ var depsRules = `
|
|||
crypto/des,
|
||||
crypto/ecdh,
|
||||
crypto/hmac,
|
||||
crypto/internal/edwards25519,
|
||||
crypto/md5,
|
||||
crypto/rc4,
|
||||
crypto/sha1,
|
||||
|
|
|
|||
Loading…
Reference in New Issue