edwards25519: sync with upstream

Minor doc, names, go:build directive changes.
This commit is contained in:
Filippo Valsorda 2022-05-24 17:20:51 +02:00
parent 7873dc1956
commit 383e08737b
13 changed files with 61 additions and 40 deletions

View file

@ -2,10 +2,16 @@ name: Go tests
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
test: test:
name: Go ${{ matrix.go }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
go: [ '1.16', '1.x' ]
steps: steps:
- uses: actions/setup-go@v2 - uses: actions/setup-go@v2
with: { go-version: 1.x } with: { go-version: "${{ matrix.go }}" }
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: go test -quickchecks 1 - run: go test -quickchecks 1 ./...
- run: go test -quickchecks 1 -tags purego ./...
- run: GOARCH=arm64 go test -c - run: GOARCH=arm64 go test -c
- run: GOARCH=arm go test -c

View file

@ -9,6 +9,6 @@ Read the docs at [pkg.go.dev/filippo.io/edwards25519](https://pkg.go.dev/filippo
The code is originally derived from Adam Langley's internal implementation in the Go standard library, and includes George Tankersley's [performance improvements](https://golang.org/cl/71950). It was then further developed by Henry de Valence for use in ristretto255, and was finally [merged back into the Go standard library](https://golang.org/cl/276272) as of Go 1.17. It now tracks the upstream codebase and extends it with additional functionality. The code is originally derived from Adam Langley's internal implementation in the Go standard library, and includes George Tankersley's [performance improvements](https://golang.org/cl/71950). It was then further developed by Henry de Valence for use in ristretto255, and was finally [merged back into the Go standard library](https://golang.org/cl/276272) as of Go 1.17. It now tracks the upstream codebase and extends it with additional functionality.
Most users don't need this package, and should instead use `crypto/ed25519` for signatures, `golang.org/x/crypto/curve25519` for Diffie-Hellman, or `github.com/gtank/ristretto255` for prime order group logic. However, for anyone currently using a fork of `crypto/ed25519/internal/edwards25519` or `github.com/agl/edwards25519`, this package should be a safer, faster, and more powerful alternative. Most users don't need this package, and should instead use `crypto/ed25519` for signatures, `golang.org/x/crypto/curve25519` for Diffie-Hellman, or `github.com/gtank/ristretto255` for prime order group logic. However, for anyone currently using a fork of `crypto/internal/edwards25519`/`crypto/ed25519/internal/edwards25519` or `github.com/agl/edwards25519`, this package should be a safer, faster, and more powerful alternative.
Since this package is meant to curb proliferation of edwards25519 implementations in the Go ecosystem, it welcomes requests for new APIs or reviewable performance improvements. Since this package is meant to curb proliferation of edwards25519 implementations in the Go ecosystem, it welcomes requests for new APIs or reviewable performance improvements.

4
doc.go
View file

@ -4,7 +4,7 @@
// Package edwards25519 implements group logic for the twisted Edwards curve // Package edwards25519 implements group logic for the twisted Edwards curve
// //
// -x^2 + y^2 = 1 + -(121665/121666)*x^2*y^2 // -x^2 + y^2 = 1 + -(121665/121666)*x^2*y^2
// //
// This is better known as the Edwards curve equivalent to Curve25519, and is // This is better known as the Edwards curve equivalent to Curve25519, and is
// the curve used by the Ed25519 signature scheme. // the curve used by the Ed25519 signature scheme.
@ -15,6 +15,6 @@
// //
// However, developers who do need to interact with low-level edwards25519 // However, developers who do need to interact with low-level edwards25519
// operations can use this package, which is an extended version of // operations can use this package, which is an extended version of
// crypto/ed25519/internal/edwards25519 from the standard library repackaged as // crypto/internal/edwards25519 from the standard library repackaged as
// an importable module. // an importable module.
package edwards25519 package edwards25519

View file

@ -148,9 +148,8 @@ func (v *Point) SetBytes(x []byte) (*Point, error) {
// (*field.Element).SetBytes docs) and // (*field.Element).SetBytes docs) and
// 2) the ones where the x-coordinate is zero and the sign bit is set. // 2) the ones where the x-coordinate is zero and the sign bit is set.
// //
// This is consistent with crypto/ed25519/internal/edwards25519. Read more // Read more at https://hdevalence.ca/blog/2020-10-04-its-25519am,
// at https://hdevalence.ca/blog/2020-10-04-its-25519am, specifically the // specifically the "Canonical A, R" section.
// "Canonical A, R" section.
y, err := new(field.Element).SetBytes(x) y, err := new(field.Element).SetBytes(x)
if err != nil { if err != nil {

View file

@ -5,7 +5,7 @@
package edwards25519 package edwards25519
// This file contains additional functionality that is not included in the // This file contains additional functionality that is not included in the
// upstream crypto/ed25519/internal/edwards25519 package. // upstream crypto/internal/edwards25519 package.
import ( import (
"errors" "errors"

View file

@ -1,10 +1,17 @@
module asm module asm
go 1.16 go 1.18
require ( require (
filippo.io/edwards25519 v0.0.0 filippo.io/edwards25519 v0.0.0
github.com/mmcloughlin/avo v0.2.0 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
) )
replace filippo.io/edwards25519 v0.0.0 => ../.. replace filippo.io/edwards25519 v0.0.0 => ../..

View file

@ -1,29 +1,30 @@
github.com/mmcloughlin/avo v0.2.0 h1:6vhoSaKtxb6f4RiH+LK2qL6GSMpFzhEwJYTTSZNy09w= github.com/mmcloughlin/avo v0.4.0 h1:jeHDRktVD+578ULxWpQHkilor6pkdLF7u7EiTzDbfcU=
github.com/mmcloughlin/avo v0.2.0/go.mod h1:5tidO2Z9Z7N6X7UMcGg+1KTj51O8OxYDCMHxCZTVpEA= github.com/mmcloughlin/avo v0.4.0/go.mod h1:RW9BfYA3TgO9uCdNrKU2h6J8cPD8ZLznvfgHAeszb1s=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/arch v0.0.0-20210405154355-08b684f594a5/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4= 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-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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/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-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-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-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-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-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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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.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-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.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.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 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-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=

View file

@ -77,11 +77,11 @@ func checkAliasingTwoArgs(f func(v, x, y *Element) *Element) func(v, x, y Elemen
// TestAliasing checks that receivers and arguments can alias each other without // TestAliasing checks that receivers and arguments can alias each other without
// leading to incorrect results. That is, it ensures that it's safe to write // leading to incorrect results. That is, it ensures that it's safe to write
// //
// v.Invert(v) // v.Invert(v)
// //
// or // or
// //
// v.Add(v, v) // v.Add(v, v)
// //
// without any of the inputs getting clobbered by the output being written. // without any of the inputs getting clobbered by the output being written.
func TestAliasing(t *testing.T) { func TestAliasing(t *testing.T) {

View file

@ -1,13 +1,16 @@
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. // Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego // +build amd64,gc,!purego
package field package field
// feMul sets out = a * b. It works like feMulGeneric. // feMul sets out = a * b. It works like feMulGeneric.
//
//go:noescape //go:noescape
func feMul(out *Element, a *Element, b *Element) func feMul(out *Element, a *Element, b *Element)
// feSquare sets out = a * a. It works like feSquareGeneric. // feSquare sets out = a * a. It works like feSquareGeneric.
//
//go:noescape //go:noescape
func feSquare(out *Element, a *Element) func feSquare(out *Element, a *Element)

View file

@ -1,5 +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. // Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
//go:build amd64 && gc && !purego
// +build amd64,gc,!purego // +build amd64,gc,!purego
#include "textflag.h" #include "textflag.h"

View file

@ -7,7 +7,7 @@ package field
import "errors" import "errors"
// This file contains additional functionality that is not included in the // This file contains additional functionality that is not included in the
// upstream crypto/ed25519/internal/edwards25519/field package. // upstream crypto/ed25519/edwards25519/field package.
// SetWideBytes sets v to x, where x is a 64-byte little-endian encoding, which // SetWideBytes sets v to x, where x is a 64-byte little-endian encoding, which
// is reduced modulo the field order. If x is not of the right length, // is reduced modulo the field order. If x is not of the right length,

View file

@ -12,7 +12,7 @@ import (
// A Scalar is an integer modulo // A Scalar is an integer modulo
// //
// l = 2^252 + 27742317777372353535851937790883648493 // l = 2^252 + 27742317777372353535851937790883648493
// //
// which is the prime order of the edwards25519 group. // which is the prime order of the edwards25519 group.
// //
@ -183,13 +183,15 @@ func load4(in []byte) int64 {
} }
// Input: // Input:
// a[0]+256*a[1]+...+256^31*a[31] = a //
// b[0]+256*b[1]+...+256^31*b[31] = b // a[0]+256*a[1]+...+256^31*a[31] = a
// c[0]+256*c[1]+...+256^31*c[31] = c // b[0]+256*b[1]+...+256^31*b[31] = b
// c[0]+256*c[1]+...+256^31*c[31] = c
// //
// Output: // Output:
// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l //
// where l = 2^252 + 27742317777372353535851937790883648493. // s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
// where l = 2^252 + 27742317777372353535851937790883648493.
func scMulAdd(s, a, b, c *[32]byte) { func scMulAdd(s, a, b, c *[32]byte) {
a0 := 2097151 & load3(a[:]) a0 := 2097151 & load3(a[:])
a1 := 2097151 & (load4(a[2:]) >> 5) a1 := 2097151 & (load4(a[2:]) >> 5)
@ -616,11 +618,13 @@ func scMulAdd(s, a, b, c *[32]byte) {
} }
// Input: // Input:
// s[0]+256*s[1]+...+256^63*s[63] = s //
// s[0]+256*s[1]+...+256^63*s[63] = s
// //
// Output: // Output:
// s[0]+256*s[1]+...+256^31*s[31] = s mod l //
// where l = 2^252 + 27742317777372353535851937790883648493. // s[0]+256*s[1]+...+256^31*s[31] = s mod l
// where l = 2^252 + 27742317777372353535851937790883648493.
func scReduce(out *[32]byte, s *[64]byte) { func scReduce(out *[32]byte, s *[64]byte) {
s0 := 2097151 & load3(s[:]) s0 := 2097151 & load3(s[:])
s1 := 2097151 & (load4(s[2:]) >> 5) s1 := 2097151 & (load4(s[2:]) >> 5)

View file

@ -40,7 +40,7 @@ func (v *projLookupTable) FromP3(q *Point) {
for i := 0; i < 7; i++ { for i := 0; i < 7; i++ {
// Compute (i+1)*Q as Q + i*Q and convert to a ProjCached // Compute (i+1)*Q as Q + i*Q and convert to a ProjCached
// This is needlessly complicated because the API has explicit // This is needlessly complicated because the API has explicit
// recievers instead of creating stack objects and relying on RVO // receivers instead of creating stack objects and relying on RVO
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i]))) v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i])))
} }
} }