Skip to content

Commit

Permalink
[WIP] First working version (passes all VXEdDSA test-vectors); still …
Browse files Browse the repository at this point in the history
…needs some cleanup:

- [ ] increase code readability (and more golang idiomatic)
- [ ] use cached public-key
- [ ] cleanup ed25519 package (unexport funcs, keep only one elligator2 implementation, test-vectors for elligator)
- [ ] adopt to google's keytransparency vrf interface (?)
- [ ] asserts
- [ ] TODOs, XXXs
  • Loading branch information
liamsi committed Feb 5, 2017
1 parent bb348f8 commit 5dd17d8
Show file tree
Hide file tree
Showing 8 changed files with 562 additions and 251 deletions.
42 changes: 17 additions & 25 deletions crypto/internal/ed25519/extra25519/extra25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,8 @@ func legendreIsNonsquare(in edwards25519.FieldElement) int32 {
return int32(1 & b[31])
}

func montgomeryXToEdwardsY(out, x *edwards25519.FieldElement) {
// compare to fe_montx_to_edy
func FeMontgomeryXToEdwardsY(out, x *edwards25519.FieldElement) {
/*
y = (u - 1) / (u + 1)
Expand All @@ -392,7 +393,7 @@ func montgomeryXToEdwardsY(out, x *edwards25519.FieldElement) {
edwards25519.FeMul(out, &tt, &t) // (u-1)/(u+1)
}

func Elligator(u *edwards25519.FieldElement, r edwards25519.FieldElement) {
func elligator(u *edwards25519.FieldElement, r edwards25519.FieldElement) {
/* r = input
* x = -A/(1+2r^2) # 2 is nonsquare
* e = (x^3 + Ax^2 + x)^((q-1)/2) # legendre symbol
Expand Down Expand Up @@ -437,32 +438,23 @@ func HashToEdwards(out *edwards25519.ExtendedGroupElement, h *[32]byte) {
hh[31] &= 127
edwards25519.FeFromBytes(&out.Y, &hh)
representativeToMontgomeryX(&out.X, &out.Y)
montgomeryXToEdwardsY(&out.Y, &out.X)
FeMontgomeryXToEdwardsY(&out.Y, &out.X)
if ok := out.FromParityAndY(bit, &out.Y); !ok {
panic("HashToEdwards: point not on curve")
}
}

func HashToPoint(p *edwards25519.ExtendedGroupElement, in []byte) {
var h, u edwards25519.FieldElement
hash := sha512.Sum512(in)

/* take the high bit as Edwards sign bit */
sign_bit := (hash[31] & 0x80) >> 7
hash[31] &= 0x7F
var hs [32]byte
copy(hs[:], hash[:32])

edwards25519.FeFromBytes(&h, &hs)

Elligator(&u, h)

var p3 edwards25519.ExtendedGroupElement
geMontXtoExtendedFieldElement(&p3, u, sign_bit)

edwards25519.GeDouble(p, &p3)
edwards25519.GeDouble(p, p)
edwards25519.GeDouble(p, p)
func HashToPoint(m []byte) *edwards25519.ExtendedGroupElement {
// H(n) = (f(h(n))^8)
var hmb [32]byte
h64 := sha512.Sum512(m)
copy(hmb[:], h64[:32])
var hm edwards25519.ExtendedGroupElement
HashToEdwards(&hm, &hmb)
edwards25519.GeDouble(&hm, &hm)
edwards25519.GeDouble(&hm, &hm)
edwards25519.GeDouble(&hm, &hm)
return &hm
}

/* sqrt(-(A+2)) */
Expand All @@ -473,7 +465,7 @@ var a_bytes = [32]byte{
0xbb, 0x06, 0xa0, 0x60, 0xf4, 0xed, 0x26, 0x0f,
}

func geMontXtoExtendedFieldElement(p *edwards25519.ExtendedGroupElement, u edwards25519.FieldElement, edSignBit byte) {
func GeMontXtoExtendedGroupElement(p *edwards25519.ExtendedGroupElement, u edwards25519.FieldElement, edSignBit byte) {
var x, y, v, A, v2, iv, nx edwards25519.FieldElement

edwards25519.FeFromBytes(&A, &a_bytes)
Expand All @@ -482,7 +474,7 @@ func geMontXtoExtendedFieldElement(p *edwards25519.ExtendedGroupElement, u edwar
/* given u, recover v */
/* given u and v, recover edwards x */

montgomeryXToEdwardsY(&y, &u) /* y = (u - 1) / (u + 1) */
FeMontgomeryXToEdwardsY(&y, &u) /* y = (u - 1) / (u + 1) */

FeMontRhs(&v2, &u) /* v^2 = u(u^2 + Au + 1) */

Expand Down
51 changes: 27 additions & 24 deletions crypto/internal/ed25519/extra25519/extra25519_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,6 @@ var calculatev_correct_output = [32]byte{
}

func TestElligatorFast(t *testing.T) {
// TODO remove sha512 tests:
want := sha512_correct_output
sha512Input := []byte("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu")
got := sha512.Sum512(sha512Input)
if !bytes.Equal(want[:], got[:]) {
t.Fatal("SHA512 #1 isn't equal to test-vector")
}
sha512Input[111] ^= 1
got = sha512.Sum512(sha512Input)
if bytes.Equal(want[:], got[:]) {
t.Fatal("SHA512 #2 shouldn't be the same")
}

var b [32]byte
for count := 0; count < 32; count++ {
b[count] = byte(count)
Expand All @@ -188,27 +175,25 @@ func TestElligatorFast(t *testing.T) {
var out edwards25519.FieldElement
edwards25519.FeFromBytes(&in, &b)

Elligator(&out, in)
elligator(&out, in)

var b2 [32]byte
edwards25519.FeToBytes(&b2, &out)
//TEST("Elligator vector", memcmp(bytes, elligator_correct_output, 32) == 0);
if !bytes.Equal(b2[:], elligator_correct_output[:]) {
fmt.Println(hex.Dump(b2[:]))
fmt.Println(hex.Dump(elligator_correct_output[:]))
t.Fatal("Elligator test vector faile")
}

/* Elligator(0) == 0 test */
edwards25519.FeZero(&in)
Elligator(&out, in)
elligator(&out, in)

var bi, bo [32]byte
edwards25519.FeToBytes(&bi, &in)
edwards25519.FeToBytes(&bo, &out)

if !bytes.Equal(bi[:], bo[:]) {
fmt.Println("Elligator(0) != 0")
t.Error("Elligator(0) != 0")
}

/* ge_montx_to_p3(0) -> order2 point test */
Expand All @@ -217,7 +202,7 @@ func TestElligatorFast(t *testing.T) {
edwards25519.FeZero(&zero)
edwards25519.FeSub(&negone, &zero, &one)
var p3 edwards25519.ExtendedGroupElement
geMontXtoExtendedFieldElement(&p3, zero, 0)
GeMontXtoExtendedGroupElement(&p3, zero, 0)
if !(edwards25519.FeIsequal(p3.X, zero) == 1 &&
edwards25519.FeIsequal(p3.Y, negone) == 1 &&
edwards25519.FeIsequal(p3.Z, one) == 1 &&
Expand All @@ -231,7 +216,7 @@ func TestElligatorFast(t *testing.T) {
htp[count] = byte(count)
}

HashToPoint(&p3, htp[:])
p3 = *HashToPoint(htp[:])

p3.ToBytes(&htp)
if !bytes.Equal(htp[:], hashtopoint_correct_output1[:]) {
Expand All @@ -244,15 +229,33 @@ func TestElligatorFast(t *testing.T) {
htp[count] = byte(count + 1)
}

HashToPoint(&p3, htp[:])
p3 = *HashToPoint(htp[:])
p3.ToBytes(&htp)
//TEST("hash_to_point #2", memcmp(htp, hashtopoint_correct_output2, 32) == 0);
if !bytes.Equal(htp[:], hashtopoint_correct_output2[:]) {
fmt.Println(hex.Dump(htp[:]))
fmt.Println(hex.Dump(hashtopoint_correct_output2[:]))
t.Fatal("hash_to_point #2 failed")
}
// TODO add other tests from:
// https://github.com/WhisperSystems/curve25519-java/blob/master/android/jni/ed25519/tests/tests.c
/* calculate_U vector test */

/* TODO move to VRF package: calculate_V vector test */
//Bv := edwards25519.ExtendedGroupElement{}
//var V [32]byte
//Vbuf := make([]byte, 200)
//var a [32]byte
//var A [32]byte
//Vmsg := []byte{0x00, 0x01, 0x02}
//
//for count:=0; count < 32; count++ {
// a[count] = byte(8 + count)
// A[count] = byte(9 + count)
//}
//// sc_clamp(a):
//a[0] &= 248; a[31] &= 127; a[31] |= 64
//_ = calculateBvAndV(&V, Vbuf, a, A, Vmsg)
//if !bytes.Equal(V[:], calculatev_correct_output[:]) {
// fmt.Println(hex.Dump(V[:]))
// fmt.Println(hex.Dump(calculatev_correct_output[:]))
// t.Fatal("calculate_Bv_and_V vector failed")
//}
}
Loading

0 comments on commit 5dd17d8

Please sign in to comment.