From 78ed6d36e0cc2f468c916f20f6459c9ab459ebf0 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Mon, 17 Jul 2017 13:26:21 -0700 Subject: [PATCH] cln16sidh: Add prototype of extension field multiplication --- field.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ field_test.go | 13 +++++++++++++ 2 files changed, 66 insertions(+) diff --git a/field.go b/field.go index d48486d..b4ade5b 100644 --- a/field.go +++ b/field.go @@ -1,5 +1,58 @@ package cln16sidh +// Represents an element of the extension field F_{p^2}. +type FieldElement struct { + A Fp751Element + B Fp751Element +} + +func (dest *FieldElement) Mul(lhs, rhs *FieldElement) { + // Let (a,b,c,d) = (lhs.A,lhs.B,rhs.A,rhs.B). + + a := &lhs.A + b := &lhs.B + c := &rhs.A + d := &rhs.B + + // We want to compute + // + // (a + bi)*(c + di) = (a*c - b*d) + (a*d + b*c)i + // + // Use Karatsuba's trick: note that + // + // (b - a)*(c - d) = (b*c + a*d) - a*c - b*d + // + // so (a*d + b*c) = (b-a)*(c-d) + a*c + b*d. + + var ac, bd Fp751X2 + Fp751Mul(&ac, a, c) + Fp751Mul(&bd, b, d) + + var b_minus_a, c_minus_d Fp751Element + Fp751SubReduced(&b_minus_a, b, a) + Fp751SubReduced(&c_minus_d, c, d) + + var ad_plus_bc Fp751X2 + Fp751Mul(&ad_plus_bc, &b_minus_a, &c_minus_d) + Fp751X2AddLazy(&ad_plus_bc, &ad_plus_bc, &ac) + Fp751X2AddLazy(&ad_plus_bc, &ad_plus_bc, &bd) + + Fp751Reduce(&dest.B, &ad_plus_bc) + + Fp751X2AddLazy(&ac, &ac, &bd) + Fp751Reduce(&dest.A, &ac) +} + +func (dest *FieldElement) Add(lhs, rhs *FieldElement) { + Fp751AddReduced(&dest.A, &lhs.A, &rhs.A) + Fp751AddReduced(&dest.B, &lhs.B, &rhs.B) +} + +func (dest *FieldElement) Sub(lhs, rhs *FieldElement) { + Fp751SubReduced(&dest.A, &lhs.A, &rhs.A) + Fp751SubReduced(&dest.B, &lhs.B, &rhs.B) +} + const Fp751NumWords = 12 // Represents an element of the base field F_p, in Montgomery form. diff --git a/field_test.go b/field_test.go index 5fb2aca..b83a90c 100644 --- a/field_test.go +++ b/field_test.go @@ -236,3 +236,16 @@ func BenchmarkFp751SubReduced(b *testing.B) { Fp751SubReduced(&benchmarkFp751Element, &x, &y) } } + +func BenchmarkFieldElementMultiply(b *testing.B) { + x := Fp751Element{17026702066521327207, 5108203422050077993, 10225396685796065916, 11153620995215874678, 6531160855165088358, 15302925148404145445, 1248821577836769963, 9789766903037985294, 7493111552032041328, 10838999828319306046, 18103257655515297935, 27403304611634} + + y := Fp751Element{4227467157325093378, 10699492810770426363, 13500940151395637365, 12966403950118934952, 16517692605450415877, 13647111148905630666, 14223628886152717087, 7167843152346903316, 15855377759596736571, 4300673881383687338, 6635288001920617779, 30486099554235} + + z := &FieldElement{A: x, B: y} + w := new(FieldElement) + + for n := 0; n < b.N; n++ { + w.Mul(z, z) + } +}