Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DO NOT MERGE: internal/field fiat-crypto playground #80

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ fault of the curve25519-voi developers alone.

* The majority of curve25519-voi is derived from curve25519-dalek.

* fiat-crypto is used for the field arithmetic.

* The Ed25519 batch verification started off as a port of the
implementation present in ed25519-dalek, but was later switched
to be based off ed25519consensus.
Expand All @@ -110,10 +112,6 @@ fault of the curve25519-voi developers alone.
additional inspiration taken from Thomas Pornin's paper and
curve9767 implementation.

* The assembly optimized field element multiplications were taken
(with minor modifications) from George Tankersley's ristretto255
package.

* The Elligator 2 mapping was taken from Loup Vaillant's Monocypher
package.

Expand Down
3 changes: 0 additions & 3 deletions curve/constants_u32.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,6 @@ var constINVSQRT_A_MINUS_D = field.NewElement2625(
6111466, 4156064, 39310137, 12243467, 41204824, 120896, 20826367, 26493656, 6093567, 31568420,
)

// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.)
var constAPLUS2_OVER_FOUR = field.NewElement2625(121666, 0, 0, 0, 0, 0, 0, 0, 0, 0)

// `[2^128]B`
var constB_SHL_128 = newEdwardsPoint(
field.NewElement2625(
Expand Down
3 changes: 0 additions & 3 deletions curve/constants_u64.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,6 @@ var constINVSQRT_A_MINUS_D = field.NewElement51(
2118520810568447,
)

// `APLUS2_OVER_FOUR` is (A+2)/4. (This is used internally within the Montgomery ladder.)
var constAPLUS2_OVER_FOUR = field.NewElement51(121666, 0, 0, 0, 0)

// `[2^128]B`
var constB_SHL_128 = newEdwardsPoint(
field.NewElement51(
Expand Down
11 changes: 11 additions & 0 deletions curve/edwards_vector_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ type extendedPoint struct {

func (p *EdwardsPoint) setExtended(ep *extendedPoint) *EdwardsPoint {
ep.inner.Split(&p.inner.X, &p.inner.Y, &p.inner.Z, &p.inner.T)

// Ensure that X, Y, Z, T are fully reduced.
//
// In practice this is probably not required, but there is a
// difference between extendedPoint (b < 0.007) and TightFieldElement
// ([0x0 ~> 0x8000000000000])'s bounds.
p.inner.X.StrictReduce()
p.inner.Y.StrictReduce()
p.inner.Z.StrictReduce()
p.inner.T.StrictReduce()

return p
}

Expand Down
29 changes: 10 additions & 19 deletions curve/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ func (p *completedPoint) Double(pp *projectivePoint) *completedPoint {
XX.Square(&pp.X)
YY.Square(&pp.Y)
ZZ2.Square2(&pp.Z)
X_plus_Y_sq.Add(&pp.X, &pp.Y) // X+Y
X_plus_Y_sq.Square(&X_plus_Y_sq) // (X+Y)^2
X_plus_Y_sq.SquareAdd(&pp.X, &pp.Y)

p.Y.Add(&YY, &XX)
p.X.Sub(&X_plus_Y_sq, &p.Y)
Expand All @@ -192,10 +191,8 @@ func (p *completedPoint) Double(pp *projectivePoint) *completedPoint {

func (p *completedPoint) AddEdwardsProjectiveNiels(a *EdwardsPoint, b *projectiveNielsPoint) *completedPoint {
var PP, MM, TT2d, ZZ, ZZ2 field.Element
PP.Add(&a.inner.Y, &a.inner.X) // a.Y + a.X
PP.Mul(&PP, &b.Y_plus_X) // (a.Y + a.X) * b.Y_plus_X
MM.Sub(&a.inner.Y, &a.inner.X) // a.Y - a.X
MM.Mul(&MM, &b.Y_minus_X) // (a.Y - a.X) * b.Y_minus_X
PP.MulAdd(&b.Y_plus_X, &a.inner.Y, &a.inner.X)
MM.MulSub(&b.Y_minus_X, &a.inner.Y, &a.inner.X)
TT2d.Mul(&a.inner.T, &b.T2d)
ZZ.Mul(&a.inner.Z, &b.Z)
ZZ2.Add(&ZZ, &ZZ)
Expand All @@ -215,10 +212,8 @@ func (p *completedPoint) AddCompletedProjectiveNiels(a *completedPoint, b *proje

func (p *completedPoint) SubEdwardsProjectiveNiels(a *EdwardsPoint, b *projectiveNielsPoint) *completedPoint {
var PM, MP, TT2d, ZZ, ZZ2 field.Element
PM.Add(&a.inner.Y, &a.inner.X) // a.Y + a.X
PM.Mul(&PM, &b.Y_minus_X) // (a.Y + a.X) * b.Y_minus_X
MP.Sub(&a.inner.Y, &a.inner.X) // a.Y - a.X
MP.Mul(&MP, &b.Y_plus_X) // (a.Y - a.X) * b.Y_plus_X
PM.MulAdd(&b.Y_minus_X, &a.inner.Y, &a.inner.X)
MP.MulSub(&b.Y_plus_X, &a.inner.Y, &a.inner.X)
TT2d.Mul(&a.inner.T, &b.T2d)
ZZ.Mul(&a.inner.Z, &b.Z)
ZZ2.Add(&ZZ, &ZZ)
Expand All @@ -237,10 +232,8 @@ func (p *completedPoint) SubCompletedProjectiveNiels(a *completedPoint, b *proje

func (p *completedPoint) AddEdwardsAffineNiels(a *EdwardsPoint, b *affineNielsPoint) *completedPoint {
var PP, MM, Txy2d, Z2 field.Element
PP.Add(&a.inner.Y, &a.inner.X) // a.Y + a.X
PP.Mul(&PP, &b.y_plus_x) // (a.Y + a.X) * b.y_plus_x
MM.Sub(&a.inner.Y, &a.inner.X) // a.Y - a.X
MM.Mul(&MM, &b.y_minus_x) // (a.Y - a.X) * b.y_minus_x
PP.MulAdd(&b.y_plus_x, &a.inner.Y, &a.inner.X)
MM.MulSub(&b.y_minus_x, &a.inner.Y, &a.inner.X)
Txy2d.Mul(&a.inner.T, &b.xy2d)
Z2.Add(&a.inner.Z, &a.inner.Z)

Expand All @@ -258,11 +251,9 @@ func (p *completedPoint) AddCompletedAffineNiels(a *completedPoint, b *affineNie
}

func (p *completedPoint) SubEdwardsAffineNiels(a *EdwardsPoint, b *affineNielsPoint) *completedPoint {
var Y_plus_X, Y_minus_X, PM, MP, Txy2d, Z2 field.Element
Y_plus_X.Add(&a.inner.Y, &a.inner.X)
Y_minus_X.Sub(&a.inner.Y, &a.inner.X)
PM.Mul(&Y_plus_X, &b.y_minus_x)
MP.Mul(&Y_minus_X, &b.y_plus_x)
var PM, MP, Txy2d, Z2 field.Element
PM.MulAdd(&b.y_minus_x, &a.inner.Y, &a.inner.X)
MP.MulSub(&b.y_plus_x, &a.inner.Y, &a.inner.X)
Txy2d.Mul(&a.inner.T, &b.xy2d)
Z2.Add(&a.inner.Z, &a.inner.Z)

Expand Down
54 changes: 30 additions & 24 deletions curve/montgomery.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (

"github.com/oasisprotocol/curve25519-voi/curve/scalar"
"github.com/oasisprotocol/curve25519-voi/internal/field"
"github.com/oasisprotocol/curve25519-voi/internal/tony"
)

var errUCoordinateOnTwist = fmt.Errorf("curve/montgomery: Montgomery u-coordinate is on twist")
Expand Down Expand Up @@ -127,40 +128,45 @@ func NewMontgomeryPoint() *MontgomeryPoint {
}

func montgomeryDifferentialAddAndDouble(P, Q *montgomeryProjectivePoint, affine_PmQ *field.Element) {
var t0, t1, t2, t3 field.Element
t0.Add(&P.U, &P.W)
t1.Sub(&P.U, &P.W)
t2.Add(&Q.U, &Q.W)
t3.Sub(&Q.U, &Q.W)
// Using the fiat-crypto routines directly can shave off reductions,
// so we do that.

var t4, t5 field.Element
t4.Square(&t0) // (U_P + W_P)^2 = U_P^2 + 2 U_P W_P + W_P^2
t5.Square(&t1) // (U_P - W_P)^2 = U_P^2 - 2 U_P W_P + W_P^2
p_U, p_W := P.U.UnsafeInner(), P.W.UnsafeInner()
q_U, q_W := Q.U.UnsafeInner(), Q.W.UnsafeInner()

var t6 field.Element
t6.Sub(&t4, &t5) // 4 U_P W_P
var t0, t1, t2, t3 tony.LooseFieldElement
t0.Add(p_U, p_W)
t1.Sub(p_U, p_W)
t2.Add(q_U, q_W)
t3.Sub(q_U, q_W)

var t7, t8 field.Element
t7.Mul(&t0, &t3) // (U_P + W_P) (U_Q - W_Q) = U_P U_Q + W_P U_Q - U_P W_Q - W_P W_Q
t8.Mul(&t1, &t2) // (U_P - W_P) (U_Q + W_Q) = U_P U_Q - W_P U_Q + U_P W_Q - W_P W_Q
var t4, t5 tony.TightFieldElement
t4.CarrySquare(&t0) // (U_P + W_P)^2 = U_P^2 + 2 U_P W_P + W_P^2
t5.CarrySquare(&t1) // (U_P - W_P)^2 = U_P^2 - 2 U_P W_P + W_P^2

// Note: dalek uses even more temporary variables, but eliminating them
// is slightly faster since the Go compiler won't do that for us.
var t6 tony.LooseFieldElement
t6.Sub(&t4, &t5) // 4 U_P W_P

Q.U.Add(&t7, &t8) // 2 (U_P U_Q - W_P W_Q): t9
Q.W.Sub(&t7, &t8) // 2 (W_P U_Q - U_P W_Q): t10
var t7, t8 tony.TightFieldElement
t7.CarryMul(&t0, &t3) // (U_P + W_P) (U_Q - W_Q) = U_P U_Q + W_P U_Q - U_P W_Q - W_P W_Q
t8.CarryMul(&t1, &t2) // (U_P - W_P) (U_Q + W_Q) = U_P U_Q - W_P U_Q + U_P W_Q - W_P W_Q

Q.U.Square(&Q.U) // 4 (U_P U_Q - W_P W_Q)^2: t11
Q.W.Square(&Q.W) // 4 (W_P U_Q - U_P W_Q)^2: t12
// 2 (U_P U_Q - W_P W_Q): t9
// 2 (W_P U_Q - U_P W_Q): t10
// 4 (U_P U_Q - W_P W_Q)^2: t11
// 4 (W_P U_Q - U_P W_Q)^2: t12
q_U.CarrySquareAdd(&t7, &t8)
q_W.CarrySquareSub(&t7, &t8)

P.W.Mul(&constAPLUS2_OVER_FOUR, &t6) // (A + 2) U_P U_Q: t13
p_W.CarryScmul121666(&t6) // (A + 2) U_P U_Q: t13

P.U.Mul(&t4, &t5) // ((U_P + W_P)(U_P - W_P))^2 = (U_P^2 - W_P^2)^2: t14
P.W.Add(&P.W, &t5) // (U_P - W_P)^2 + (A + 2) U_P W_P: t15
p_U.CarryMul(t4.RelaxCast(), t5.RelaxCast()) // ((U_P + W_P)(U_P - W_P))^2 = (U_P^2 - W_P^2)^2: t14

P.W.Mul(&t6, &P.W) // 4 (U_P W_P) ((U_P - W_P)^2 + (A + 2) U_P W_P): t16
// (U_P - W_P)^2 + (A + 2) U_P W_P: t15
// 4 (U_P W_P) ((U_P - W_P)^2 + (A + 2) U_P W_P): t16
p_W.CarryMulAdd(&t6, p_W, &t5)

Q.W.Mul(affine_PmQ, &Q.W) // U_D * 4 (W_P U_Q - U_P W_Q)^2: t17
q_W.CarryMul(affine_PmQ.UnsafeInner().RelaxCast(), q_W.RelaxCast()) // U_D * 4 (W_P U_Q - U_P W_Q)^2: t17
// t18 := t11 // W_D * 4 (U_P U_Q - W_P W_Q)^2: t18

// P.U = t14 // U_{P'} = (U_P + W_P)^2 (U_P - W_P)^2
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/oasisprotocol/curve25519-voi
go 1.16

require (
github.com/mit-plv/fiat-crypto/fiat-go v0.0.0-20210807234606-f1951b3d80f1
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/mit-plv/fiat-crypto/fiat-go v0.0.0-20210807234606-f1951b3d80f1 h1:tclc3vLlQfZi9scV1zBCXboNWiG3bpbz7O1gwybPyNQ=
github.com/mit-plv/fiat-crypto/fiat-go v0.0.0-20210807234606-f1951b3d80f1/go.mod h1:59UI5/2yBTcSl1/+qCCOTsfXYy290H670oWjGFRqOLs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
Expand Down
2 changes: 0 additions & 2 deletions internal/asm/amd64/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ type (
affineNielsPointLookupTable struct{}
affineNielsPoint struct{}

Element struct{}

cachedPointLookupTable struct{}
cachedPoint struct{}
extendedPoint struct{}
Expand Down
Loading