Skip to content

Commit

Permalink
internal/field: Use fiat-crypto
Browse files Browse the repository at this point in the history
  • Loading branch information
Yawning committed Aug 11, 2021
1 parent c237d57 commit 1fcb446
Show file tree
Hide file tree
Showing 16 changed files with 220 additions and 2,217 deletions.
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
37 changes: 14 additions & 23 deletions curve/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,11 @@ func (p *affineNielsPoint) SetEdwards(ep *EdwardsPoint) *affineNielsPoint {
}

func (p *completedPoint) Double(pp *projectivePoint) *completedPoint {
var XX, YY, ZZ2, X_plus_Y, X_plus_Y_sq field.Element
var XX, YY, ZZ2, X_plus_Y_sq field.Element
XX.Square(&pp.X)
YY.Square(&pp.Y)
ZZ2.Square2(&pp.Z)
X_plus_Y.Add(&pp.X, &pp.Y)
X_plus_Y_sq.Square(&X_plus_Y)
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 @@ -191,11 +190,9 @@ func (p *completedPoint) Double(pp *projectivePoint) *completedPoint {
}

func (p *completedPoint) AddEdwardsProjectiveNiels(a *EdwardsPoint, b *projectiveNielsPoint) *completedPoint {
var Y_plus_X, Y_minus_X, PP, MM, TT2d, ZZ, ZZ2 field.Element
Y_plus_X.Add(&a.inner.Y, &a.inner.X)
Y_minus_X.Sub(&a.inner.Y, &a.inner.X)
PP.Mul(&Y_plus_X, &b.Y_plus_X)
MM.Mul(&Y_minus_X, &b.Y_minus_X)
var PP, MM, TT2d, ZZ, ZZ2 field.Element
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 @@ -214,11 +211,9 @@ func (p *completedPoint) AddCompletedProjectiveNiels(a *completedPoint, b *proje
}

func (p *completedPoint) SubEdwardsProjectiveNiels(a *EdwardsPoint, b *projectiveNielsPoint) *completedPoint {
var Y_plus_X, Y_minus_X, PM, MP, TT2d, ZZ, ZZ2 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, TT2d, ZZ, ZZ2 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)
TT2d.Mul(&a.inner.T, &b.T2d)
ZZ.Mul(&a.inner.Z, &b.Z)
ZZ2.Add(&ZZ, &ZZ)
Expand All @@ -236,11 +231,9 @@ func (p *completedPoint) SubCompletedProjectiveNiels(a *completedPoint, b *proje
}

func (p *completedPoint) AddEdwardsAffineNiels(a *EdwardsPoint, b *affineNielsPoint) *completedPoint {
var Y_plus_X, Y_minus_X, PP, MM, Txy2d, Z2 field.Element
Y_plus_X.Add(&a.inner.Y, &a.inner.X)
Y_minus_X.Sub(&a.inner.Y, &a.inner.X)
PP.Mul(&Y_plus_X, &b.y_plus_x)
MM.Mul(&Y_minus_X, &b.y_minus_x)
var PP, MM, Txy2d, Z2 field.Element
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
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

0 comments on commit 1fcb446

Please sign in to comment.