mirror of
https://github.com/golang/go.git
synced 2025-05-30 19:52:53 +00:00
crypto/internal/edwards25519: replace scalar field with fiat-crypto
This was the last piece of ref10 code, including the infamous "Christmas tree" in scMulAdd, that approximately all Ed25519 implementations inherited. Replace the whole scalar field implementation with a fiat-crypto generated one, like those in crypto/internal/nistec/fiat. The only complexity is the wide reduction (both for the 64-byte one and for the clamped input). For that we do a limbed reduction suggested by Frank Denis. Some minor housekeeping and test changes from filippo.io/edwards25519 are included, as part of syncing with downstream. Ignoring the autogenerated file, the diff is 268 insertions(+), 893 deletions(-) George Tankersley signed the Individual CLA and authorized me to submit this change on his behalf at the time he contributed it to filippo.io/edwards25519. Co-authored-by: George Tankersley <george.tankersley@gmail.com> Change-Id: I4084b4d3813f36e16b3d8839df75da1b4fd7846b Reviewed-on: https://go-review.googlesource.com/c/go/+/420454 Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Filippo Valsorda <filippo@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
parent
3fc8ed2543
commit
eca7754148
@ -300,3 +300,14 @@ func decodeHex(s string) []byte {
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func BenchmarkEncodingDecoding(b *testing.B) {
|
||||
p := new(Point).Set(dalekScalarBasepoint)
|
||||
for i := 0; i < b.N; i++ {
|
||||
buf := p.Bytes()
|
||||
_, err := p.SetBytes(buf)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
module asm
|
||||
|
||||
go 1.16
|
||||
go 1.19
|
||||
|
||||
require github.com/mmcloughlin/avo v0.2.0
|
||||
require github.com/mmcloughlin/avo v0.4.0
|
||||
|
||||
require (
|
||||
golang.org/x/mod v0.4.2 // indirect
|
||||
golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 // indirect
|
||||
golang.org/x/tools v0.1.7 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
)
|
||||
|
@ -1,29 +1,30 @@
|
||||
github.com/mmcloughlin/avo v0.2.0 h1:6vhoSaKtxb6f4RiH+LK2qL6GSMpFzhEwJYTTSZNy09w=
|
||||
github.com/mmcloughlin/avo v0.2.0/go.mod h1:5tidO2Z9Z7N6X7UMcGg+1KTj51O8OxYDCMHxCZTVpEA=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/arch v0.0.0-20210405154355-08b684f594a5/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
|
||||
github.com/mmcloughlin/avo v0.4.0 h1:jeHDRktVD+578ULxWpQHkilor6pkdLF7u7EiTzDbfcU=
|
||||
github.com/mmcloughlin/avo v0.4.0/go.mod h1:RW9BfYA3TgO9uCdNrKU2h6J8cPD8ZLznvfgHAeszb1s=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 h1:giLT+HuUP/gXYrG2Plg9WTjj4qhfgaW424ZIFog3rlk=
|
||||
golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
|
||||
|
||||
// +build amd64,gc,!purego
|
||||
//go:build amd64 && gc && !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
@ -7,30 +7,43 @@ package field
|
||||
import "testing"
|
||||
|
||||
func BenchmarkAdd(b *testing.B) {
|
||||
var x, y Element
|
||||
x.One()
|
||||
y.Add(feOne, feOne)
|
||||
x := new(Element).One()
|
||||
y := new(Element).Add(x, x)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
x.Add(&x, &y)
|
||||
x.Add(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMultiply(b *testing.B) {
|
||||
var x, y Element
|
||||
x.One()
|
||||
y.Add(feOne, feOne)
|
||||
x := new(Element).One()
|
||||
y := new(Element).Add(x, x)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
x.Multiply(&x, &y)
|
||||
x.Multiply(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSquare(b *testing.B) {
|
||||
x := new(Element).Add(feOne, feOne)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
x.Square(x)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInvert(b *testing.B) {
|
||||
x := new(Element).Add(feOne, feOne)
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
x.Invert(x)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMult32(b *testing.B) {
|
||||
var x Element
|
||||
x.One()
|
||||
x := new(Element).One()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
x.Mult32(&x, 0xaa42aa42)
|
||||
x.Mult32(x, 0xaa42aa42)
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,12 +14,12 @@ func TestScalarAliasing(t *testing.T) {
|
||||
x1, v1 := x, x
|
||||
|
||||
// Calculate a reference f(x) without aliasing.
|
||||
if out := f(&v, &x); out != &v || !isReduced(out) {
|
||||
if out := f(&v, &x); out != &v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Test aliasing the argument and the receiver.
|
||||
if out := f(&v1, &v1); out != &v1 || v1 != v || !isReduced(out) {
|
||||
if out := f(&v1, &v1); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -31,39 +31,39 @@ func TestScalarAliasing(t *testing.T) {
|
||||
x1, y1, v1 := x, y, Scalar{}
|
||||
|
||||
// Calculate a reference f(x, y) without aliasing.
|
||||
if out := f(&v, &x, &y); out != &v || !isReduced(out) {
|
||||
if out := f(&v, &x, &y); out != &v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Test aliasing the first argument and the receiver.
|
||||
v1 = x
|
||||
if out := f(&v1, &v1, &y); out != &v1 || v1 != v || !isReduced(out) {
|
||||
if out := f(&v1, &v1, &y); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
// Test aliasing the second argument and the receiver.
|
||||
v1 = y
|
||||
if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out) {
|
||||
if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Calculate a reference f(x, x) without aliasing.
|
||||
if out := f(&v, &x, &x); out != &v || !isReduced(out) {
|
||||
if out := f(&v, &x, &x); out != &v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Test aliasing the first argument and the receiver.
|
||||
v1 = x
|
||||
if out := f(&v1, &v1, &x); out != &v1 || v1 != v || !isReduced(out) {
|
||||
if out := f(&v1, &v1, &x); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
// Test aliasing the second argument and the receiver.
|
||||
v1 = x
|
||||
if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out) {
|
||||
if out := f(&v1, &x, &v1); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
// Test aliasing both arguments and the receiver.
|
||||
v1 = x
|
||||
if out := f(&v1, &v1, &v1); out != &v1 || v1 != v || !isReduced(out) {
|
||||
if out := f(&v1, &v1, &v1); out != &v1 || v1 != v || !isReduced(out.Bytes()) {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ func TestScalarAliasing(t *testing.T) {
|
||||
return x == x1 && y == y1
|
||||
}
|
||||
|
||||
for name, f := range map[string]any{
|
||||
for name, f := range map[string]interface{}{
|
||||
"Negate": func(v, x Scalar) bool {
|
||||
return checkAliasingOneArg((*Scalar).Negate, v, x)
|
||||
},
|
||||
@ -84,6 +84,21 @@ func TestScalarAliasing(t *testing.T) {
|
||||
"Subtract": func(v, x, y Scalar) bool {
|
||||
return checkAliasingTwoArgs((*Scalar).Subtract, v, x, y)
|
||||
},
|
||||
"MultiplyAdd1": func(v, x, y, fixed Scalar) bool {
|
||||
return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
|
||||
return v.MultiplyAdd(&fixed, x, y)
|
||||
}, v, x, y)
|
||||
},
|
||||
"MultiplyAdd2": func(v, x, y, fixed Scalar) bool {
|
||||
return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
|
||||
return v.MultiplyAdd(x, &fixed, y)
|
||||
}, v, x, y)
|
||||
},
|
||||
"MultiplyAdd3": func(v, x, y, fixed Scalar) bool {
|
||||
return checkAliasingTwoArgs(func(v, x, y *Scalar) *Scalar {
|
||||
return v.MultiplyAdd(x, y, &fixed)
|
||||
}, v, x, y)
|
||||
},
|
||||
} {
|
||||
err := quick.Check(f, &quick.Config{MaxCountScale: 1 << 5})
|
||||
if err != nil {
|
||||
|
1147
src/crypto/internal/edwards25519/scalar_fiat.go
Normal file
1147
src/crypto/internal/edwards25519/scalar_fiat.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -14,34 +14,43 @@ import (
|
||||
"testing/quick"
|
||||
)
|
||||
|
||||
var scOneBytes = [32]byte{1}
|
||||
var scOne, _ = new(Scalar).SetCanonicalBytes(scOneBytes[:])
|
||||
var scMinusOne, _ = new(Scalar).SetCanonicalBytes(scalarMinusOneBytes[:])
|
||||
|
||||
// Generate returns a valid (reduced modulo l) Scalar with a distribution
|
||||
// weighted towards high, low, and edge values.
|
||||
func (Scalar) Generate(rand *mathrand.Rand, size int) reflect.Value {
|
||||
s := scZero
|
||||
var s [32]byte
|
||||
diceRoll := rand.Intn(100)
|
||||
switch {
|
||||
case diceRoll == 0:
|
||||
case diceRoll == 1:
|
||||
s = scOne
|
||||
s = scOneBytes
|
||||
case diceRoll == 2:
|
||||
s = scMinusOne
|
||||
s = scalarMinusOneBytes
|
||||
case diceRoll < 5:
|
||||
// Generate a low scalar in [0, 2^125).
|
||||
rand.Read(s.s[:16])
|
||||
s.s[15] &= (1 << 5) - 1
|
||||
rand.Read(s[:16])
|
||||
s[15] &= (1 << 5) - 1
|
||||
case diceRoll < 10:
|
||||
// Generate a high scalar in [2^252, 2^252 + 2^124).
|
||||
s.s[31] = 1 << 4
|
||||
rand.Read(s.s[:16])
|
||||
s.s[15] &= (1 << 4) - 1
|
||||
s[31] = 1 << 4
|
||||
rand.Read(s[:16])
|
||||
s[15] &= (1 << 4) - 1
|
||||
default:
|
||||
// Generate a valid scalar in [0, l) by returning [0, 2^252) which has a
|
||||
// negligibly different distribution (the former has a 2^-127.6 chance
|
||||
// of being out of the latter range).
|
||||
rand.Read(s.s[:])
|
||||
s.s[31] &= (1 << 4) - 1
|
||||
rand.Read(s[:])
|
||||
s[31] &= (1 << 4) - 1
|
||||
}
|
||||
return reflect.ValueOf(s)
|
||||
|
||||
val := Scalar{}
|
||||
fiatScalarFromBytes((*[4]uint64)(&val.s), &s)
|
||||
fiatScalarToMontgomery(&val.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&val.s))
|
||||
|
||||
return reflect.ValueOf(val)
|
||||
}
|
||||
|
||||
// quickCheckConfig1024 will make each quickcheck test run (1024 * -quickchecks)
|
||||
@ -50,7 +59,7 @@ var quickCheckConfig1024 = &quick.Config{MaxCountScale: 1 << 10}
|
||||
|
||||
func TestScalarGenerate(t *testing.T) {
|
||||
f := func(sc Scalar) bool {
|
||||
return isReduced(&sc)
|
||||
return isReduced(sc.Bytes())
|
||||
}
|
||||
if err := quick.Check(f, quickCheckConfig1024); err != nil {
|
||||
t.Errorf("generated unreduced scalar: %v", err)
|
||||
@ -64,7 +73,8 @@ func TestScalarSetCanonicalBytes(t *testing.T) {
|
||||
if _, err := sc.SetCanonicalBytes(in[:]); err != nil {
|
||||
return false
|
||||
}
|
||||
return bytes.Equal(in[:], sc.Bytes()) && isReduced(&sc)
|
||||
repr := sc.Bytes()
|
||||
return bytes.Equal(in[:], repr) && isReduced(repr)
|
||||
}
|
||||
if err := quick.Check(f1, quickCheckConfig1024); err != nil {
|
||||
t.Errorf("failed bytes->scalar->bytes round-trip: %v", err)
|
||||
@ -80,7 +90,7 @@ func TestScalarSetCanonicalBytes(t *testing.T) {
|
||||
t.Errorf("failed scalar->bytes->scalar round-trip: %v", err)
|
||||
}
|
||||
|
||||
b := scMinusOne.s
|
||||
b := scalarMinusOneBytes
|
||||
b[31] += 1
|
||||
s := scOne
|
||||
if out, err := s.SetCanonicalBytes(b[:]); err == nil {
|
||||
@ -97,10 +107,11 @@ func TestScalarSetUniformBytes(t *testing.T) {
|
||||
mod.Add(mod, new(big.Int).Lsh(big.NewInt(1), 252))
|
||||
f := func(in [64]byte, sc Scalar) bool {
|
||||
sc.SetUniformBytes(in[:])
|
||||
if !isReduced(&sc) {
|
||||
repr := sc.Bytes()
|
||||
if !isReduced(repr) {
|
||||
return false
|
||||
}
|
||||
scBig := bigIntFromLittleEndianBytes(sc.s[:])
|
||||
scBig := bigIntFromLittleEndianBytes(repr[:])
|
||||
inBig := bigIntFromLittleEndianBytes(in[:])
|
||||
return inBig.Mod(inBig, mod).Cmp(scBig) == 0
|
||||
}
|
||||
@ -159,7 +170,9 @@ func TestScalarMultiplyDistributesOverAdd(t *testing.T) {
|
||||
t3.Multiply(&y, &z)
|
||||
t2.Add(&t2, &t3)
|
||||
|
||||
return t1 == t2 && isReduced(&t1) && isReduced(&t3)
|
||||
reprT1, reprT2 := t1.Bytes(), t2.Bytes()
|
||||
|
||||
return t1 == t2 && isReduced(reprT1) && isReduced(reprT2)
|
||||
}
|
||||
|
||||
if err := quick.Check(multiplyDistributesOverAdd, quickCheckConfig1024); err != nil {
|
||||
@ -178,7 +191,7 @@ func TestScalarAddLikeSubNeg(t *testing.T) {
|
||||
t2.Negate(&y)
|
||||
t2.Add(&t2, &x)
|
||||
|
||||
return t1 == t2 && isReduced(&t1)
|
||||
return t1 == t2 && isReduced(t1.Bytes())
|
||||
}
|
||||
|
||||
if err := quick.Check(addLikeSubNeg, quickCheckConfig1024); err != nil {
|
||||
@ -187,12 +200,13 @@ func TestScalarAddLikeSubNeg(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScalarNonAdjacentForm(t *testing.T) {
|
||||
s := Scalar{[32]byte{
|
||||
s, _ := (&Scalar{}).SetCanonicalBytes([]byte{
|
||||
0x1a, 0x0e, 0x97, 0x8a, 0x90, 0xf6, 0x62, 0x2d,
|
||||
0x37, 0x47, 0x02, 0x3f, 0x8a, 0xd8, 0x26, 0x4d,
|
||||
0xa7, 0x58, 0xaa, 0x1b, 0x88, 0xe0, 0x40, 0xd1,
|
||||
0x58, 0x9e, 0x7b, 0x7f, 0x23, 0x76, 0xef, 0x09,
|
||||
}}
|
||||
})
|
||||
|
||||
expectedNaf := [256]int8{
|
||||
0, 13, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, -9, 0, 0, 0, 0, -11, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 9, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 11, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0,
|
||||
@ -217,17 +231,19 @@ type notZeroScalar Scalar
|
||||
|
||||
func (notZeroScalar) Generate(rand *mathrand.Rand, size int) reflect.Value {
|
||||
var s Scalar
|
||||
for s == scZero {
|
||||
var isNonZero uint64
|
||||
for isNonZero == 0 {
|
||||
s = Scalar{}.Generate(rand, size).Interface().(Scalar)
|
||||
fiatScalarNonzero(&isNonZero, (*[4]uint64)(&s.s))
|
||||
}
|
||||
return reflect.ValueOf(notZeroScalar(s))
|
||||
}
|
||||
|
||||
func TestScalarEqual(t *testing.T) {
|
||||
if scOne.Equal(&scMinusOne) == 1 {
|
||||
if scOne.Equal(scMinusOne) == 1 {
|
||||
t.Errorf("scOne.Equal(&scMinusOne) is true")
|
||||
}
|
||||
if scMinusOne.Equal(&scMinusOne) == 0 {
|
||||
if scMinusOne.Equal(scMinusOne) == 0 {
|
||||
t.Errorf("scMinusOne.Equal(&scMinusOne) is false")
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ var (
|
||||
quickCheckConfig32 = &quick.Config{MaxCountScale: 1 << 5}
|
||||
|
||||
// a random scalar generated using dalek.
|
||||
dalekScalar = Scalar{[32]byte{219, 106, 114, 9, 174, 249, 155, 89, 69, 203, 201, 93, 92, 116, 234, 187, 78, 115, 103, 172, 182, 98, 62, 103, 187, 136, 13, 100, 248, 110, 12, 4}}
|
||||
dalekScalar, _ = (&Scalar{}).SetCanonicalBytes([]byte{219, 106, 114, 9, 174, 249, 155, 89, 69, 203, 201, 93, 92, 116, 234, 187, 78, 115, 103, 172, 182, 98, 62, 103, 187, 136, 13, 100, 248, 110, 12, 4})
|
||||
// the above, times the edwards25519 basepoint.
|
||||
dalekScalarBasepoint, _ = new(Point).SetBytes([]byte{0xf4, 0xef, 0x7c, 0xa, 0x34, 0x55, 0x7b, 0x9f, 0x72, 0x3b, 0xb6, 0x1e, 0xf9, 0x46, 0x9, 0x91, 0x1c, 0xb9, 0xc0, 0x6c, 0x17, 0x28, 0x2d, 0x8b, 0x43, 0x2b, 0x5, 0x18, 0x6a, 0x54, 0x3e, 0x48})
|
||||
)
|
||||
@ -29,8 +29,8 @@ func TestScalarMultSmallScalars(t *testing.T) {
|
||||
}
|
||||
checkOnCurve(t, &p)
|
||||
|
||||
z = Scalar{[32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
p.ScalarMult(&z, B)
|
||||
scEight, _ := (&Scalar{}).SetCanonicalBytes([]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
|
||||
p.ScalarMult(scEight, B)
|
||||
if B.Equal(&p) != 1 {
|
||||
t.Error("1*B != 1")
|
||||
}
|
||||
@ -39,7 +39,7 @@ func TestScalarMultSmallScalars(t *testing.T) {
|
||||
|
||||
func TestScalarMultVsDalek(t *testing.T) {
|
||||
var p Point
|
||||
p.ScalarMult(&dalekScalar, B)
|
||||
p.ScalarMult(dalekScalar, B)
|
||||
if dalekScalarBasepoint.Equal(&p) != 1 {
|
||||
t.Error("Scalar mul does not match dalek")
|
||||
}
|
||||
@ -48,7 +48,7 @@ func TestScalarMultVsDalek(t *testing.T) {
|
||||
|
||||
func TestBaseMultVsDalek(t *testing.T) {
|
||||
var p Point
|
||||
p.ScalarBaseMult(&dalekScalar)
|
||||
p.ScalarBaseMult(dalekScalar)
|
||||
if dalekScalarBasepoint.Equal(&p) != 1 {
|
||||
t.Error("Scalar mul does not match dalek")
|
||||
}
|
||||
@ -58,12 +58,12 @@ func TestBaseMultVsDalek(t *testing.T) {
|
||||
func TestVarTimeDoubleBaseMultVsDalek(t *testing.T) {
|
||||
var p Point
|
||||
var z Scalar
|
||||
p.VarTimeDoubleScalarBaseMult(&dalekScalar, B, &z)
|
||||
p.VarTimeDoubleScalarBaseMult(dalekScalar, B, &z)
|
||||
if dalekScalarBasepoint.Equal(&p) != 1 {
|
||||
t.Error("VarTimeDoubleScalarBaseMult fails with b=0")
|
||||
}
|
||||
checkOnCurve(t, &p)
|
||||
p.VarTimeDoubleScalarBaseMult(&z, B, &dalekScalar)
|
||||
p.VarTimeDoubleScalarBaseMult(&z, B, dalekScalar)
|
||||
if dalekScalarBasepoint.Equal(&p) != 1 {
|
||||
t.Error("VarTimeDoubleScalarBaseMult fails with a=0")
|
||||
}
|
||||
@ -188,7 +188,7 @@ func BenchmarkScalarBaseMult(b *testing.B) {
|
||||
var p Point
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
p.ScalarBaseMult(&dalekScalar)
|
||||
p.ScalarBaseMult(dalekScalar)
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,7 +196,7 @@ func BenchmarkScalarMult(b *testing.B) {
|
||||
var p Point
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
p.ScalarMult(&dalekScalar, B)
|
||||
p.ScalarMult(dalekScalar, B)
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,6 +204,6 @@ func BenchmarkVarTimeDoubleScalarBaseMult(b *testing.B) {
|
||||
var p Point
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
p.VarTimeDoubleScalarBaseMult(&dalekScalar, B, &dalekScalar)
|
||||
p.VarTimeDoubleScalarBaseMult(dalekScalar, B, dalekScalar)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user