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:
Filippo Valsorda 2024-11-17 15:18:25 +01:00 committed by Gopher Robot
parent 7e1af3bf74
commit 7eb10ca691
29 changed files with 69 additions and 63 deletions

View File

@ -6,7 +6,7 @@ package ecdh
import (
"bytes"
"crypto/internal/edwards25519/field"
"crypto/internal/fips/edwards25519/field"
"crypto/internal/randutil"
"errors"
"io"

View File

@ -18,7 +18,7 @@ package ed25519
import (
"bytes"
"crypto"
"crypto/internal/edwards25519"
"crypto/internal/fips/edwards25519"
cryptorand "crypto/rand"
"crypto/sha512"
"crypto/subtle"

View File

@ -5,7 +5,7 @@
package edwards25519
import (
"crypto/internal/edwards25519/field"
"crypto/internal/fips/edwards25519/field"
"errors"
)

View File

@ -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 {

View File

@ -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()

View File

@ -1,4 +1,4 @@
module std/crypto/internal/edwards25519/field/_asm
module std/crypto/internal/fips/edwards25519/field/_asm
go 1.19

View File

@ -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) {

View File

@ -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)

View File

@ -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)

View File

@ -5,7 +5,7 @@
package edwards25519
import (
"crypto/subtle"
"crypto/internal/fips/subtle"
)
// A dynamic lookup table for variable-base, constant-time scalar muls.

View File

@ -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)
}
}

View File

@ -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,