aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/ed25519/internal/edwards25519/field/fe_amd64.go
AgeCommit message (Collapse)Author
2021-07-31all: gofmtJosh Bleecher Snyder
Change-Id: Icfafcfb62a389d9fd2e7a4d17809486ed91f15c3 Reviewed-on: https://go-review.googlesource.com/c/go/+/338629 Trust: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2021-05-05crypto/ed25519: replace internal/edwards25519 with filippo.io/edwards25519Filippo Valsorda
This change replaces the crypto/ed25519/internal/edwards25519 package with code from filippo.io/edwards25519, a significantly faster, safer, well tested (over 1600 lines of new tests, 99% test coverage), and better documented (600 lines of new comments) implementation. Some highlights: * an unsaturated 51-bit limb field implementation optimized for 64-bit architectures and math/bits.Mul64 intrinsics * more efficient variable time scalar multiplication using multi-width non-adjacent form with a larger lookup table for fixed-base * a safe math/big.Int-like API for the Scalar, Point, and field.Element types with fully abstracted reduction invariants * a test suite including a testing/quick fuzzer that explores edge case values that would be impossible to hit randomly, and systematic tests for arguments and receiver aliasing * point decoding rules that strictly match the original logic of crypto/ed25519/internal/edwards25519, to avoid consensus issues * AssemblyPolicy-compliant assembly cores for arm64 and amd64, the former under 20 lines, and the latter generated by a program based on github.com/mmcloughlin/avo that can be reviewed line-by-line against the generic implementation Intel(R) Core(TM) i5-7400 CPU @ 3.00GHz name old time/op new time/op delta KeyGeneration-4 59.5µs ± 1% 26.1µs ± 1% -56.20% (p=0.000 n=10+10) NewKeyFromSeed-4 59.3µs ± 1% 25.8µs ± 1% -56.48% (p=0.000 n=9+10) Signing-4 60.4µs ± 1% 31.4µs ± 1% -48.05% (p=0.000 n=10+10) Verification-4 169µs ± 1% 73µs ± 2% -56.55% (p=0.000 n=10+10) Apple M1 name old time/op new time/op delta KeyGeneration-8 35.1µs ± 0% 20.2µs ± 2% -42.46% (p=0.000 n=8+10) NewKeyFromSeed-8 35.1µs ± 0% 20.0µs ± 1% -42.93% (p=0.000 n=8+9) Signing-8 36.2µs ± 0% 25.6µs ± 1% -29.25% (p=0.000 n=8+9) Verification-8 96.1µs ± 0% 57.6µs ± 1% -40.14% (p=0.000 n=10+10) The code in this CL is a copy of the filippo.io/edwards25519 module at version v1.0.0-beta.3.0.20210405211453-c6be47d67779 with only the following functions removed as irrelevant to crypto/ed25519: - (*Point).BytesMontgomery() - (*Point).MultByCofactor() - (*Scalar).Invert() - (*Point).MultiScalarMult() - (*Point).VarTimeMultiScalarMult() This codebase took a long journey outside the standard library before making its way back here. Its oldest parts started as a faster field implementation rewrite by George Tankersley almost four years ago, eventually submitted as CL 71950 but never merged. That code was then merged into github.com/gtank/ristretto255, which also started as an internal/edwards25519 fork. There it was worked on by me, George, and Henry de Valence as a backend for our Go ristretto255 implementation. Finally, I extracted the edwards25519 code into a reusable package as filippo.io/edwards25519. Now, we're ready for the standard library to become the source of truth for this code again, while filippo.io/edwards25519 will become a re-packaged and extended version for external use, since we don't want to expose unsafe curve operations in x/crypto or the standard library. Submitted under the Google CLA on behalf of: - Henry de Valence https://github.com/gtank/ristretto255/issues/34 - George Tankersley https://golang.org/cl/71950 https://github.com/gtank/ristretto255-private/issues/28 - Luke Champine https://github.com/FiloSottile/edwards25519/pull/7 - Adrian Hamelink https://github.com/FiloSottile/edwards25519/pull/12 Changes 32506b5 and 18c803c are trivial and don't require a CLA. The full history of this code since diverging from internal/edwards25519 is available at https://github.com/FiloSottile/edwards25519, and summarized below. + c6be47d - edwards25519: update TestScalarSetBytesWithClamping <Filippo Valsorda> + c882e8e - edwards25519: rewrite amd64 assembly with avo <Filippo Valsorda> + 8eb02eb - edwards25519: refactor feMulGeneric and feSquareGeneric <Filippo Valsorda> + 8afd860 - edwards25519: remove Go 1.12 compatibility hack <Filippo Valsorda> + 1765c13 - edwards25519: don't clobber BP in amd64 assembly <Filippo Valsorda> + b73a7c8 - edwards25519: fix ScalarMult when receiver is not the identity (FiloSottile/edwards25519#12) <Adrian Hamelink> + 32a46d7 - edwards25519: document why this can't implement X25519 <Filippo Valsorda> + c547797 - edwards25519: make SqrtRatio slightly more efficient <Filippo Valsorda> + 700f4f4 - edwards25519: panic if an uninitialized Point is used <Filippo Valsorda> + d791cf8 - edwards25519: use testing.AllocsPerRun for TestAllocations <Filippo Valsorda> + 8cc8037 - edwards25519: smooth a couple test coverage rough edges <Filippo Valsorda> + 9063a14 - edwards25519: test that operations cause zero heap allocations <Filippo Valsorda> + 6944ac7 - edwards25519: relax the limb schedule slightly <Filippo Valsorda> + 21ebdac - edwards25519: rewrite carryPropagate in arm64 assembly <Filippo Valsorda> + a260082 - edwards25519: merge carryPropagate[12] <Filippo Valsorda> + dbe1792 - edwards25519: add TestScalarSetBytesWithClamping <Filippo Valsorda> + c1fe95a - edwards25519: add MultByCofactor <Filippo Valsorda> + 132d95c - edwards25519: sprinkle on-curve checks around tests <Filippo Valsorda> + ffb3e31 - edwards25519: specify the behavior of Invert(0) and I.BytesMontgomery() <Filippo Valsorda> + 9e6a931 - edwards25519: add (*Scalar).MultiplyAdd <lukechampine> + 3b045f3 - edwards25519: outline (*Point).Bytes (FiloSottile/edwards25519#6) <Luke Champine> + ec6f8a6 - edwards25519: make (*Scalar).SetCanonicalBytes return the receiver <Filippo Valsorda> + 77d7b31 - edwards25519: add (*Point).BytesMontgomery <Filippo Valsorda> + 6e8d645 - edwards25519: implement (*Point).Bytes and (*Point).SetBytes <Filippo Valsorda> + 1c833da - edwards25519: clarify ScalarBaseMult docs <Filippo Valsorda> + 3a13cf1 - edwards25519: apply gc build tag <Filippo Valsorda> + 90c35a7 - edwards25519: hide FieldElement and (*Point).ExtendedCoords <Filippo Valsorda> + 498fb1e - edwards25519: replace FillBytes with Bytes, again <Filippo Valsorda> + 9c7303a - edwards25519: remove (*Point).Identity and (*Point).Generator <Filippo Valsorda> + 2e52ce2 - edwards25519: drop unused (*Scalar).Zero <Filippo Valsorda> + 7c14a36 - edwards25519: rename FromBytes to SetBytes <Filippo Valsorda> + e3d0e45 - edwards25519: ensure only test files import math/big <Filippo Valsorda> + daa2507 - edwards25519: minor doc and string touch-ups <Filippo Valsorda> + e8698cd - edwards25519: implement (*Scalar).FromBytesWithClamping <Filippo Valsorda> + f28d75a - edwards25519: change constructors <Filippo Valsorda> + 36d8598 - edwards25519: test the invariant that Scalars are always reduced <Filippo Valsorda> + feed48c - edwards25519: cleanup the FieldElement API <Filippo Valsorda> + f6ee187 - edwards25519: make Point opaque <Filippo Valsorda> + 176388b - edwards25519: cleanup Scalar API to match ristretto255 <Filippo Valsorda> + c5c2e9e - edwards25519: rename ProjP3 to Point and unexport other point types <Filippo Valsorda> + 8542076 - edwards25519: add Scalar aliasing test <Filippo Valsorda> + 1a86a9c - edwards25519: make Scalar opaque <Filippo Valsorda> + 07a7683 - edwards25519: hide some more exposed symbols <Filippo Valsorda> + d3569cb - all: flatten the package and make FieldElement opaque <Filippo Valsorda> + 6f5f582 - all: expose edwards25519, base, and scalar packages <Filippo Valsorda> + 7ab4a68 - all: ensure compatibility with older Go versions <Filippo Valsorda> + e9b8baa - internal/radix51: implement (*FieldElement).Mul32 <Filippo Valsorda> + eac4de5 - internal/radix51: restructure according to golang.org/wiki/TargetSpecific <Filippo Valsorda> + 32506b5 - internal/radix51: fix !amd64 build (lightReduce -> carryPropagate) (gtank/ristretto255#29) <Sunny Aggarwal> + d64d989 - internal/scalar: fix FromUniformBytes <Filippo Valsorda> + 044bb44 - internal/scalar: address review comments <Filippo Valsorda> + 7dba54f - all: apply suggestions from code review <Filippo Valsorda> + 94bd1d9 - ristretto255: expose scalar multiplication APIs <Filippo Valsorda> + 5bd5476 - internal/edwards25519: fix shadowing of B in TestAddSubNegOnBasePoint <Filippo Valsorda> + 66bf647 - internal/scalar: replace FromBytes/IsCanonical with FromUniformBytes/FromCanonicalBytes <Filippo Valsorda> + 024f3f7 - internal/edwards25519,internal/scalar: apply some Go style touches <Filippo Valsorda> + 5e0c5c6 - internal/scalar: add scalar inversion <Henry de Valence> + 74fd625 - internal/ed25519: rearrange VartimeDoubleBaseMul args <Henry de Valence> + 81ae7ea - internal/ed25519: add benchmarks for scalar mul <Henry de Valence> + 9f1f939 - internal/ed25519: add variable-time multiscalar mul <Henry de Valence> + 7a96974 - internal/ed25519: add vartime double-base scmul <Henry de Valence> + 2bc256c - internal/ed25519: add precomputed NAF table for basepoint <Henry de Valence> + a0f0b96 - internal/ed25519: lower quickcheck size for point ops <Henry de Valence> + 2f385a1 - internal/ed25519: implement MultiscalarMul <Henry de Valence> + 8ae211b - internal/ed25519: implement BasepointMul <Henry de Valence> + 7b4858d - internal/ed25519: extract common test variables <Henry de Valence> + 16e7c48 - internal/ed25519: add a basepoint multiple table. <Henry de Valence> + 988e521 - internal/ed25519: add constant-time variable-base scmul. <Henry de Valence> + b695f6b - internal/ed25519: move basepoint constant & correct it <Henry de Valence> + ddd014e - internal/scalar: fix high bit check <Henry de Valence> + c88ea89 - internal/scalar: make casts clearer <Henry de Valence> + b75f989 - internal/scalar: add invariant checks on Scalar digits <Henry de Valence> + 36216ca - internal/scalar: use one scMulAdd for Sub <Henry de Valence> + 8bf40f3 - internal/scalar: fix constant-time signed radix 16 implementation <Henry de Valence> + e6d9ef6 - Update internal/radix51/fe_test.go <Filippo Valsorda> + 3aa63de - Update internal/radix51/fe_test.go <Filippo Valsorda> + 3e66ff0 - Update internal/radix51/fe_test.go <Filippo Valsorda> + 94e6c15 - internal/ed25519: add TODO note and doc ref <Henry de Valence> + 3647548 - internal/ed25519: rename twoD to D2 <Henry de Valence> + 1cf853c - internal/ed25519: add lookup tables for scalar mul. <Henry de Valence> + 3af304a - internal/radix51: add a conditional swap <Henry de Valence> + 4673217 - ristretto255: use multi-model arithmetic <Henry de Valence> + cca757a - internal/ed25519: remove single-model code <Henry de Valence> + d26e77b - internal/ed25519: add addition for Edwards points <Henry de Valence> + e0fbb35 - internal/ed25519: use twoD <Henry de Valence> + fd9b37b - internal/ed25519: add tests for multi-model point types. <Henry de Valence> + dacabb0 - internal/ed25519: add multi-model point types. <Henry de Valence> + dddc72e - internal/scalar: add constant-time signed radix 16 <Henry de Valence> + 92cdb35 - internal/scalar: add non-adjacent form <Henry de Valence> + d147963 - internal/scalar: don't zero memory that is about to be copied over <George Tankersley> + 8da186c - internal/scalar: add scalar field implementation <George Tankersley> + f38e583 - internal/radix51: add a "weird" testing/quick generation strategy <Filippo Valsorda> + 6454f61 - Move comment inside function <Henry de Valence> + 1983365 - implement Add, Sub, Neg for ed25519 and ristretto255 points. <Henry de Valence> + 9f25562 - internal/group: rename to internal/edwards25519 <Filippo Valsorda> + 48e66d3 - internal/group: restore ScalarMult code <Filippo Valsorda> + 0078d66 - internal/radix51: rename lightReduce to carryPropagate and touch up docs <Filippo Valsorda> + 05f4107 - internal/radix51: add benchmarks <Filippo Valsorda> + fd36334 - internal/radix51: test that operations don't exceed bounds <Filippo Valsorda> + 703421d - internal/radix51: make Generate produce random light-reduced elements <Filippo Valsorda> + f8d8297 - internal/radix51: simplify lightReduce <Filippo Valsorda> + 413120f - internal/radix51: minor tests cleanup <Filippo Valsorda> + abc8c5a - internal/radix51: make reduction an invariant and unexport Reduce <Filippo Valsorda> + 4fd198d - internal/radix51: actually apply go:noescape <Filippo Valsorda> + 18c803c - all: fix typos <Dimitris Apostolou> + bbfe059 - internal/radix51: test field encoding roundtrip with fixed vectors <George Tankersley> + c428b18 - internal/radix51: rename AppendBytes to Bytes <Filippo Valsorda> + c59bc1a - internal/radix51: rewrite FromBytes and AppendBytes with encoding/binary <Filippo Valsorda> + 57c0cd5 - internal/radix51: add docs and some light readability refactors <Filippo Valsorda> + cb1b734 - internal/radix51: remove unused (and a bit broken) SetInt <Filippo Valsorda> + beb8abd - internal/radix51: refactor ToBig and FromBig <Filippo Valsorda> + 87c0a53 - internal/radix51: replace ToBytes with AppendBytes <Filippo Valsorda> + b7e1e45 - internal/radix51: fix aliasing bug in CondNeg (gtank/ristretto255#21) <George Tankersley> + ed3748d - internal/radix51: actually, uhm, check the result of TestAliasing <Filippo Valsorda> + ec0e293 - radix51: change API of FromBytes and ToBytes to use slices <George Tankersley> + 29f6815 - internal/radix51: test all combinations of argument and receiver aliasing <Filippo Valsorda> + cd53d90 - internal/radix51: add property-based tests that multiplication distributes over addition <Henry de Valence> + c3bc45f - radix51: use go1.12 intrinsics for 128-bit multiplications <George Tankersley> + 7e7043e - internal/radix51: define a mask64Bits constant <Filippo Valsorda> + 4fdd06d - internal/group: set Z to 1, not 0 in FromAffine <Filippo Valsorda> + ffa7be7 - internal/group: fix typo <Filippo Valsorda> + 1f452ac - internal/group: derive twoD from D <Filippo Valsorda> + 2424c78 - internal/radix51: add MinusOne <Filippo Valsorda> + 76978fc - internal/group: make conversion APIs caller-allocated <Filippo Valsorda> + d17d202 - internal/group: rewrite DoubleZ1 because stack is cheaper than mental state <Filippo Valsorda> + 72b97c1 - internal: make all APIs chainable <Filippo Valsorda> + 993d979 - internal/radix51: make all APIs not consider the receiver an input <Filippo Valsorda> + b2a1d7d - all: refactor field API to be methods based <Filippo Valsorda> + cdf9b90 - internal/radix51: add constant time field operations <Filippo Valsorda> + e490a48 - internal/radix51: remove FeEqual <Filippo Valsorda> + 2de114c - internal/radix51: remove FeCSwap <Filippo Valsorda> + 08b80c1 - make things more generally presentable <George Tankersley> + 2178536 - Cache the field representation of d <George Tankersley> + 4135059 - Remove 32-bit code and update license. <George Tankersley> + 5d95cb3 - Use Bits() for FeToBig. <George Tankersley> + 146e33c - Implement ScalarMult using Montgomery pattern and dedicated extended-coordinates doubling. This will be slow. <George Tankersley> + 12a673a - use faster FeFromBig & a horrible assortment of other random changes <George Tankersley> + 901f40c - group logic WIP <George Tankersley> + a9c89cd - add equality for field elements <George Tankersley> + 214873b - Add radix51 FieldElement implementation <George Tankersley> + 8fd5cae - Implement an elliptic.Curve for ed25519 <George Tankersley> Change-Id: Ifbcdd13e8b6304f9906c0ef2b73f1fdc493a7dfa Co-authored-by: George Tankersley <george.tankersley@gmail.com> Co-authored-by: Henry de Valence <hdevalence@hdevalence.ca> Reviewed-on: https://go-review.googlesource.com/c/go/+/276272 Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Filippo Valsorda <filippo@golang.org> Trust: Katie Hockman <katie@golang.org> Reviewed-by: Katie Hockman <katie@golang.org>