mirror of https://github.com/gtank/ristretto255
Merge pull request #19 from gtank/add-ristretto-add-sub
implement Add, Sub, Neg for ed25519 and ristretto255 points.
This commit is contained in:
commit
363fa10df6
|
@ -114,6 +114,50 @@ func (v *ExtendedGroupElement) Add(p1, p2 *ExtendedGroupElement) *ExtendedGroupE
|
|||
return v
|
||||
}
|
||||
|
||||
func (v *ExtendedGroupElement) Sub(p1, p2 *ExtendedGroupElement) *ExtendedGroupElement {
|
||||
// This is the same function as above, but with X2, T2 negated to X2'=-X2, T2'=-T2
|
||||
var tmp1, tmp2, A, B, C, D, E, F, G, H radix51.FieldElement
|
||||
tmp1.Sub(&p1.Y, &p1.X) // tmp1 <-- Y1-X1
|
||||
tmp2.Add(&p2.Y, &p2.X) // tmp2 <-- Y2+X2 = Y2-X2'
|
||||
A.Mul(&tmp1, &tmp2) // A <-- tmp1*tmp2 = (Y1-X1)*(Y2-X2')
|
||||
tmp1.Add(&p1.Y, &p1.X) // tmp1 <-- Y1+X1
|
||||
tmp2.Sub(&p2.Y, &p2.X) // tmp2 <-- Y2-X2 = Y2+X2'
|
||||
B.Mul(&tmp1, &tmp2) // B <-- tmp1*tmp2 = (Y1+X1)*(Y2+X2)
|
||||
tmp1.Mul(&p1.T, &p2.T) // tmp1 <-- -T1*T2' = T1*T2
|
||||
C.Mul(&tmp1, twoD) // C' <-- tmp1*2d = -T1*2*d*T2' = T1*2*d*T2
|
||||
tmp1.Mul(&p1.Z, &p2.Z) // tmp1 <-- Z1*Z2
|
||||
D.Add(&tmp1, &tmp1) // D <-- tmp1 + tmp1 = 2*Z1*Z2
|
||||
E.Sub(&B, &A) // E <-- B-A
|
||||
F.Add(&D, &C) // F <-- D+C' = D-C
|
||||
G.Sub(&D, &C) // G <-- D-C' = D+C
|
||||
H.Add(&B, &A) // H <-- B+A
|
||||
v.X.Mul(&E, &F) // X3 <-- E*F
|
||||
v.Y.Mul(&G, &H) // Y3 <-- G*H
|
||||
v.T.Mul(&E, &H) // T3 <-- E*H
|
||||
v.Z.Mul(&F, &G) // Z3 <-- F*G
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *ExtendedGroupElement) Neg(p *ExtendedGroupElement) *ExtendedGroupElement {
|
||||
v.X.Neg(&p.X)
|
||||
v.Y.Set(&p.Y)
|
||||
v.Z.Set(&p.Z)
|
||||
v.T.Neg(&p.T)
|
||||
return v
|
||||
}
|
||||
|
||||
// by @ebfull
|
||||
// https://github.com/dalek-cryptography/curve25519-dalek/pull/226/files
|
||||
func (v *ExtendedGroupElement) Equal(u *ExtendedGroupElement) int {
|
||||
var t1, t2, t3, t4 radix51.FieldElement
|
||||
t1.Mul(&v.X, &u.Z)
|
||||
t2.Mul(&u.X, &v.Z)
|
||||
t3.Mul(&v.Y, &u.Z)
|
||||
t4.Mul(&u.Y, &v.Z)
|
||||
|
||||
return t1.Equal(&t2) & t3.Equal(&t4)
|
||||
}
|
||||
|
||||
// This implements the explicit formulas from HWCD Section 3.3, "Dedicated
|
||||
// Doubling in [extended coordinates]".
|
||||
//
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package edwards25519
|
||||
|
||||
import (
|
||||
"github.com/gtank/ristretto255/internal/radix51"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAddSubNegOnBasePoint(t *testing.T) {
|
||||
|
||||
basepoint := ExtendedGroupElement{
|
||||
X: radix51.FieldElement([5]uint64{426475514619346, 2063872706840040, 14628272888959, 107677749330612, 288339085807592}),
|
||||
Y: radix51.FieldElement([5]uint64{1934594822876571, 2049809580636559, 1991994783322914, 1758681962032007, 380046701118659}),
|
||||
Z: radix51.FieldElement([5]uint64{1, 0, 0, 0, 0}),
|
||||
T: radix51.FieldElement([5]uint64{410445769351754, 2235400917701188, 1495825632738689, 1351628537510093, 430502003771208}),
|
||||
}
|
||||
|
||||
negBasepoint := ExtendedGroupElement{}
|
||||
|
||||
negBasepoint.Neg(&basepoint)
|
||||
|
||||
check1 := ExtendedGroupElement{}
|
||||
check1.Zero()
|
||||
check2 := ExtendedGroupElement{}
|
||||
check2.Zero()
|
||||
zero := ExtendedGroupElement{}
|
||||
zero.Zero()
|
||||
|
||||
check1.Add(&basepoint, &negBasepoint)
|
||||
check2.Sub(&basepoint, &basepoint)
|
||||
|
||||
if check1.Equal(&check2) != 1 {
|
||||
t.Error("B + (-B) != B - B")
|
||||
}
|
||||
|
||||
if check1.Equal(&zero) != 1 {
|
||||
t.Error("B + (-B) != 0")
|
||||
}
|
||||
}
|
|
@ -255,3 +255,21 @@ func (e *Element) Decode(in []byte) error {
|
|||
// Otherwise, return the internal representation in extended coordinates (x, y, 1, t).
|
||||
return nil
|
||||
}
|
||||
|
||||
// Add sets v = p + q, and returns v.
|
||||
func (v *Element) Add(p, q *Element) *Element {
|
||||
v.r.Add(&p.r, &q.r)
|
||||
return v
|
||||
}
|
||||
|
||||
// Sub sets v = p - q, and returns v.
|
||||
func (v *Element) Sub(p, q *Element) *Element {
|
||||
v.r.Sub(&p.r, &q.r)
|
||||
return v
|
||||
}
|
||||
|
||||
// Neg sets v = -p, and returns v.
|
||||
func (v *Element) Neg(p *Element) *Element {
|
||||
v.r.Neg(&p.r)
|
||||
return v
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue